Steuerkram/tests/06_EuerBuchungsTest.php
2026-04-13 16:14:49 +02:00

142 lines
6.9 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 6: EÜR-Buchungsmodell – Einnahmen und Ausgaben.
*
* Prüft das EÜR-Buchungsmodell: buchungstyp, kategorie_konto_id, zahlungskonto_id.
* Stellt sicher, dass Stornobuchungen korrekt funktionieren und
* die Kontenarten den neuen EÜR-Bezeichnungen entsprechen.
*/
class EuerBuchungsTest extends TestCase
{
protected string $testName = 'Test 6: EÜR-Buchungsmodell (Einnahme/Ausgabe)';
public function run(): void
{
$datum = date('Y-m-d');
// EÜR-Snapshot vor allen Testbuchungen
$euerVorher = (new \Steuerkram\Services\EuerCalculator())->calculate((int)date('Y'));
$einnahmenVorher = (float)$euerVorher['total_einnahmen'];
$gewinnVorher = (float)$euerVorher['gewinn'];
// ── Kontenarten prüfen ───────────────────────────────────────
$kontenarten = \Steuerkram\Database::fetchAll(
"SELECT DISTINCT kontenart FROM accounts ORDER BY kontenart"
);
$arten = array_column($kontenarten, 'kontenart');
$this->assert(
in_array('Betriebseinnahme', $arten),
'Kontenart "Betriebseinnahme" existiert'
);
$this->assert(
in_array('Betriebsausgabe', $arten),
'Kontenart "Betriebsausgabe" existiert'
);
$this->assert(
in_array('Zahlungskonto', $arten),
'Kontenart "Zahlungskonto" existiert'
);
$this->assert(
!in_array('Aktiv', $arten) && !in_array('Passiv', $arten)
&& !in_array('Aufwand', $arten) && !in_array('Ertrag', $arten),
'Alte Kontenarten (Aktiv, Passiv, Aufwand, Ertrag) existieren nicht mehr'
);
// Konten laden
$erloesId = $this->findAccountId('8400'); // Erlöse 19 % USt (Betriebseinnahme)
$ausgabeId = $this->findAccountId('4600'); // Werbekosten (Betriebsausgabe)
$bankId = $this->findAccountId('1200'); // Bank (Zahlungskonto)
if (!$erloesId || !$ausgabeId || !$bankId) {
$this->assert(false, 'Benötigte Konten (8400, 4600, 1200) nicht gefunden');
return;
}
// ── Einnahme-Buchung ─────────────────────────────────────────
$belegEinnahme = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-EIN-' . uniqid(),
'filename' => 'test-einnahme.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'einnahme-' . uniqid()),
'beleg_datum' => $datum,
'belegtyp' => 'Ausgangsrechnung',
]);
$einnahmeId = \Steuerkram\Models\Booking::create([
'beleg_id' => $belegEinnahme,
'buchungs_datum' => $datum,
'buchungstyp' => 'Einnahme',
'kategorie_konto_id' => $erloesId,
'zahlungskonto_id' => $bankId,
'betrag_netto' => 1000.00,
'ust_satz' => 19.0,
'buchungstext' => 'Test Einnahme',
]);
$einnahme = \Steuerkram\Models\Booking::find($einnahmeId);
$this->assertEquals('Einnahme', $einnahme['buchungstyp'], 'Einnahme-Buchung hat buchungstyp=Einnahme');
$this->assertEquals($erloesId, (int)$einnahme['kategorie_konto_id'], 'Kategorie-Konto ist Erlöskonto');
$this->assertEquals($bankId, (int)$einnahme['zahlungskonto_id'], 'Zahlungskonto ist Bankkonto');
$this->assertEquals(1000.00, (float)$einnahme['betrag_netto'], 'Nettobetrag korrekt');
$this->assertEquals(190.00, (float)$einnahme['betrag_ust'], 'USt-Betrag korrekt berechnet');
$this->assertEquals(1190.00, (float)$einnahme['betrag_brutto'], 'Bruttobetrag korrekt berechnet');
// ── Ausgabe-Buchung ──────────────────────────────────────────
$belegAusgabe = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-AUS-' . uniqid(),
'filename' => 'test-ausgabe.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'ausgabe-' . uniqid()),
'beleg_datum' => $datum,
'belegtyp' => 'Eingangsrechnung',
]);
$ausgabeBuchungId = \Steuerkram\Models\Booking::create([
'beleg_id' => $belegAusgabe,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $ausgabeId,
'zahlungskonto_id' => $bankId,
'betrag_netto' => 300.00,
'ust_satz' => 19.0,
'buchungstext' => 'Test Ausgabe',
]);
$ausgabe = \Steuerkram\Models\Booking::find($ausgabeBuchungId);
$this->assertEquals('Ausgabe', $ausgabe['buchungstyp'], 'Ausgabe-Buchung hat buchungstyp=Ausgabe');
$this->assertEquals($ausgabeId, (int)$ausgabe['kategorie_konto_id'], 'Kategorie-Konto ist Ausgabenkonto');
// ── Storno prüfen ────────────────────────────────────────────
$stornoId = \Steuerkram\Models\Booking::reverse($ausgabeBuchungId, 'Testgrund');
$storno = \Steuerkram\Models\Booking::find($stornoId);
$this->assertEquals('Ausgabe', $storno['buchungstyp'], 'Storno behält buchungstyp der Originalbuchung');
$this->assertEquals(1, (int)$storno['is_reversal'], 'Storno-Flag gesetzt');
$this->assertEquals($ausgabeId, (int)$storno['kategorie_konto_id'], 'Storno behält Kategorie-Konto');
$this->assertEquals($bankId, (int)$storno['zahlungskonto_id'], 'Storno behält Zahlungskonto');
// Original hat reversed_by
$origNeu = \Steuerkram\Models\Booking::find($ausgabeBuchungId);
$this->assertEquals($stornoId, (int)$origNeu['reversed_by'], 'Original verweist auf Storno-Buchung');
// ── EÜR-Berechnung ───────────────────────────────────────────
// Nach Einnahme (1000 €) + stornierter Ausgabe: Delta muss +1000 € betragen
$euerNachher = (new \Steuerkram\Services\EuerCalculator())->calculate((int)date('Y'));
$this->assert(
(float)$euerNachher['total_einnahmen'] >= $einnahmenVorher + 1000.00,
'EÜR: Einnahmen enthalten die 1000 € Einnahme-Buchung'
);
// Ausgabe wurde storniert → Netto-Effekt auf Gewinn: +1000 €
$this->assert(
(float)$euerNachher['gewinn'] >= $gewinnVorher + 1000.00,
'EÜR: Gewinn ist um ≥ 1000 € gestiegen (Einnahme + stornierte Ausgabe)'
);
}
}