Steuerkram/tests/18_StornoBuchungTest.php

103 lines
5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* Test 18: Stornobuchungen in UStVA und EÜR.
*
* Prüft, dass eine stornierte Buchung korrekt mit negativem Betrag angelegt wird
* und sich mit der Originalbuchung in den Berichten gegenseitig auf null aufhebt.
*/
class StornoBuchungTest extends TestCase
{
protected string $testName = 'Test 18: Stornobuchungen in UStVA und EÜR';
public function run(): void
{
$year = (int)date('Y');
$month = (int)date('n');
$datum = date('Y-m-d');
$zahlungsId = $this->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,
'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');
}
}