Steuerkram an den e2e-runner angebunden (tests/e2e/, 44 Playwright-Tests). Der erste Smoke-Lauf fand zwei Seiten mit HTTP 500: AccountController::create las $_GET['from'] ungeprüft, assets/form.php nutzte $testMode und $defaultKontoId außerhalb des Bearbeiten-Zweigs. Beides war bis zur Fehler-Härtung (#142) nur eine stille Warning. Test 67 räumt sein Belegverzeichnis jetzt mit ab - es blieb als root-eigenes Verzeichnis liegen und blockierte spätere echte Uploads mit HTTP 500. Test 77 (neu) sichert die Löschsperre von Beleg::delete() ab.
103 lines
4.1 KiB
PHP
103 lines
4.1 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* Test 77: Beleg::delete() – Löschsperre bei Buchungen und gesperrten Belegen.
|
||
*
|
||
* Ein Beleg, auf den bereits gebucht wurde, darf nicht verschwinden – sonst
|
||
* hingen die Buchungen ohne Nachweis in der Buchführung (GoBD). Dasselbe gilt
|
||
* für festgeschriebene (locked) Belege.
|
||
*
|
||
* Ergänzt Test 49, der nur den Fall "unlink() schlägt fehl" abdeckt.
|
||
*/
|
||
class BelegLoeschsperreTest extends TestCase
|
||
{
|
||
protected string $testName = 'Test 77: Beleg::delete() – Löschsperre';
|
||
|
||
public function run(): void
|
||
{
|
||
$kategorieId = $this->findAccountId('4930');
|
||
$zahlungsId = $this->findAccountId('1200');
|
||
$this->assertNotEmpty($kategorieId, 'Kategoriekonto 4930 vorhanden');
|
||
$this->assertNotEmpty($zahlungsId, 'Zahlungskonto 1200 vorhanden');
|
||
|
||
// ── Beleg ohne Buchung: löschbar ──────────────────────────────
|
||
$freierBelegId = $this->createBeleg('E2E-frei');
|
||
$this->assert(
|
||
\Steuerkram\Models\Beleg::delete($freierBelegId) === true,
|
||
'Beleg ohne Buchungen lässt sich löschen'
|
||
);
|
||
$this->assert(
|
||
\Steuerkram\Models\Beleg::find($freierBelegId) === false,
|
||
'Gelöschter Beleg ist nicht mehr auffindbar'
|
||
);
|
||
|
||
// ── Beleg mit Buchung: gesperrt ───────────────────────────────
|
||
$gebuchterBelegId = $this->createBeleg('E2E-gebucht');
|
||
\Steuerkram\Models\Booking::create([
|
||
'beleg_id' => $gebuchterBelegId,
|
||
'buchungstyp' => 'Ausgabe',
|
||
'buchungs_datum' => date('Y-m-d'),
|
||
'kategorie_konto_id' => $kategorieId,
|
||
'zahlungskonto_id' => $zahlungsId,
|
||
'betrag_netto' => 42.00,
|
||
'ust_satz' => 19,
|
||
'buchungstext' => 'Löschsperre-Test',
|
||
]);
|
||
|
||
$anzahl = \Steuerkram\Database::fetchOne(
|
||
'SELECT COUNT(*) AS n FROM bookings WHERE beleg_id = ?',
|
||
[$gebuchterBelegId]
|
||
);
|
||
$this->assertGreaterThan(0, (int)$anzahl['n'], 'Buchung wurde angelegt');
|
||
|
||
$this->assert(
|
||
\Steuerkram\Models\Beleg::delete($gebuchterBelegId) === false,
|
||
'Beleg mit Buchungen lässt sich NICHT löschen'
|
||
);
|
||
$this->assertNotEmpty(
|
||
\Steuerkram\Models\Beleg::find($gebuchterBelegId),
|
||
'Gebuchter Beleg existiert nach dem Löschversuch weiterhin'
|
||
);
|
||
|
||
$nachher = \Steuerkram\Database::fetchOne(
|
||
'SELECT COUNT(*) AS n FROM bookings WHERE beleg_id = ?',
|
||
[$gebuchterBelegId]
|
||
);
|
||
$this->assertEquals(
|
||
(int)$anzahl['n'],
|
||
(int)$nachher['n'],
|
||
'Die Buchungen des Belegs bleiben unangetastet'
|
||
);
|
||
|
||
// ── Gesperrter Beleg ohne Buchung: ebenfalls gesperrt ─────────
|
||
$lockedBelegId = $this->createBeleg('E2E-locked');
|
||
\Steuerkram\Database::execute('UPDATE belege SET locked = 1 WHERE id = ?', [$lockedBelegId]);
|
||
$this->assert(
|
||
\Steuerkram\Models\Beleg::delete($lockedBelegId) === false,
|
||
'Festgeschriebener Beleg lässt sich NICHT löschen'
|
||
);
|
||
$this->assertNotEmpty(
|
||
\Steuerkram\Models\Beleg::find($lockedBelegId),
|
||
'Festgeschriebener Beleg existiert weiterhin'
|
||
);
|
||
}
|
||
|
||
/** Legt einen Beleg ohne Datei an (storage_path zeigt bewusst ins Leere). */
|
||
private function createBeleg(string $marker): int
|
||
{
|
||
$belegNr = \Steuerkram\Models\Beleg::generateBelegNr();
|
||
|
||
return \Steuerkram\Models\Beleg::create([
|
||
'beleg_nr' => $belegNr,
|
||
'filename' => $marker . '.pdf',
|
||
'storage_path' => date('Y') . '/' . $marker . '/original.pdf',
|
||
'mime_type' => 'application/pdf',
|
||
'file_hash' => hash('sha256', $belegNr . $marker),
|
||
'belegtyp' => 'Eingangsrechnung',
|
||
'beleg_datum' => date('Y-m-d'),
|
||
'notes' => $marker,
|
||
]);
|
||
}
|
||
}
|