findAccountId('1200'); // Bank $ausgabeId = $this->findAccountId('4920'); // Telefon (ustva_kz=61) if (!$zahlungsId || !$ausgabeId) { $this->assert(false, 'Benötigte Konten nicht gefunden – SKR03-Seed vorhanden?'); return; } // ── Beleg anlegen ────────────────────────────────────────────── $belegId = \Steuerkram\Models\Beleg::create([ 'beleg_nr' => 'STORNO-TEST-' . uniqid(), 'filename' => 'storno-test.pdf', 'storage_path' => '', 'mime_type' => 'application/pdf', 'file_hash' => hash('sha256', 'storno-test-' . uniqid()), 'beleg_datum' => $datum, 'eingangs_datum' => $datum, 'belegtyp' => 'Ausgangsrechnung', ]); // ── Ausgabe-Buchung anlegen (Netto=100, USt 19%=19, Brutto=119) ─ $bookingId = \Steuerkram\Models\Booking::create([ 'beleg_id' => $belegId, 'buchungs_datum' => $datum, 'buchungstyp' => 'Ausgabe', 'kategorie_konto_id' => $ausgabeId, 'zahlungskonto_id' => $zahlungsId, 'betrag_netto' => 100.00, 'ust_satz' => 19.0, 'buchungstext' => 'Test-Ausgabe für Storno', ]); $original = \Steuerkram\Models\Booking::find($bookingId); $this->assertEquals(100.00, round((float)$original['betrag_netto'], 2), 'Originalbuchung: betrag_netto = 100'); $this->assertEquals(19.00, round((float)$original['betrag_ust'], 2), 'Originalbuchung: betrag_ust = 19'); $this->assertEquals(119.00, round((float)$original['betrag_brutto'], 2),'Originalbuchung: betrag_brutto = 119'); // ── Stornieren ──────────────────────────────────────────────── $reversalId = \Steuerkram\Models\Booking::reverse($bookingId, 'Testfall Storno'); $reversal = \Steuerkram\Models\Booking::find($reversalId); $this->assertEquals(1, (int)$reversal['is_reversal'], 'Stornobuchung: is_reversal = 1'); $this->assertEquals(-100.00, round((float)$reversal['betrag_netto'], 2), 'Stornobuchung: betrag_netto = -100'); $this->assertEquals(-19.00, round((float)$reversal['betrag_ust'], 2), 'Stornobuchung: betrag_ust = -19'); $this->assertEquals(-119.00, round((float)$reversal['betrag_brutto'], 2), 'Stornobuchung: betrag_brutto = -119'); // ── EÜR: storniertes Konto hat Netto-Summe = 0 ─────────────── $euerCalc = new \Steuerkram\Services\EuerCalculator(); $euer = $euerCalc->calculate($year); $kontoNetto = null; foreach ($euer['ausgaben'] as $row) { if ((int)$row['id'] === (int)$ausgabeId) { $kontoNetto = (float)$row['netto']; break; } } // Wenn das Konto nicht mehr auftaucht (alle Buchungen = 0), ist das ebenfalls korrekt. if ($kontoNetto !== null) { $this->assertEquals(0.0, round($kontoNetto, 2), 'EÜR: Storno + Original = 0 auf Ausgabe-Konto'); } else { $this->assert(true, 'EÜR: Konto taucht bei Summe=0 nicht auf (HAVING buchungsanzahl > 0 greift)'); } // ── UStVA: Vorsteuer-KZ hebt sich auf ───────────────────────── // Kz 61 enthält Vorsteuer aus dem Ausgabe-Konto (ustva_kz='61'). // Original: +19, Storno: -19 → Summe = 0 (oder weniger als andere Tests einbringen). // Da weitere Tests parallel laufen können, prüfen wir nur, dass die Storno-Buchung // als eigenständige Zeile in fetchBookingsForKz erscheint. $ustvaCalc = new \Steuerkram\Services\UstvaCalculator(); $bookings = $ustvaCalc->fetchBookingsForKz($year, $month, '61'); $reversalFound = false; foreach ($bookings as $b) { if ((int)$b['id'] === $reversalId) { $reversalFound = true; $this->assertEquals(1, (int)$b['is_reversal'], 'UStVA-Drilldown: Stornobuchung is_reversal = 1'); $this->assertEquals(-19.00, round((float)$b['betrag_ust'], 2), 'UStVA-Drilldown: Storno betrag_ust = -19'); break; } } $this->assert($reversalFound, 'UStVA-Drilldown Kz 61: Stornobuchung erscheint in Detailansicht'); } }