Steuerkram/tests/18_StornoBuchungTest.php

114 lines
5.4 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;
}
// ── EÜR: Konto-Stand VOR den Test-Buchungen ermitteln ─────────
$euerCalcPre = new \Steuerkram\Services\EuerCalculator();
$euerPre = $euerCalcPre->calculate($year);
$kontoNettoPre = 0.0;
foreach ($euerPre['ausgaben'] as $row) {
if ((int)$row['id'] === (int)$ausgabeId) {
$kontoNettoPre = (float)$row['netto'];
break;
}
}
// ── 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: Storno + Original heben sich auf (Konto-Saldo unverändert) ─
// Vergleich mit dem Stand vor den Test-Buchungen, da auf dem Produktivsystem
// bereits echte Buchungen auf dem Konto existieren können.
$euerCalc = new \Steuerkram\Services\EuerCalculator();
$euer = $euerCalc->calculate($year);
$kontoNetto = 0.0;
foreach ($euer['ausgaben'] as $row) {
if ((int)$row['id'] === (int)$ausgabeId) {
$kontoNetto = (float)$row['netto'];
break;
}
}
$this->assertEquals(
round($kontoNettoPre, 2),
round($kontoNetto, 2),
'EÜR: Storno + Original = 0 auf Ausgabe-Konto'
);
// ── UStVA: Vorsteuer-KZ hebt sich auf ─────────────────────────
// Kz 66 enthält alle inländischen Ausgaben mit Vorsteuer (buchungsbasiert).
// 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, '66');
$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 66: Stornobuchung erscheint in Detailansicht');
}
}