Steuerkram/tests/89_BookingCreatePfadeTest.php

130 lines
5.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);
use Steuerkram\Models\Beleg;
use Steuerkram\Models\Booking;
use Steuerkram\Database;
/**
* Test 89: Booking::create() – die drei Schreibpfade (Fix #159).
*
* Deckt die aus create() extrahierten Teilschritte ab:
* - insertHauptbuchung(): einfache Buchung ohne 7/19%-USt und ohne ig. Erwerb
* - insertVorsteuerUmsatzsteuerZeile(): normale Buchung mit 19% USt/VSt
* - insertIgErwerbReverseCharge(): ig. Erwerb 19% mit zwei Kindzeilen
*/
class BookingCreatePfadeTest extends TestCase
{
protected string $testName = 'Test 89: Booking::create() – Schreibpfade';
public function run(): void
{
$zahlungsId = $this->findAccountId('1200');
$ausgabeId = $this->findAccountId('4120');
if (!$zahlungsId || !$ausgabeId) {
$this->assert(false, 'Benötigte Konten nicht gefunden (1200, 4120)');
return;
}
$this->assert(true, 'Konten 1200, 4120 vorhanden');
$belegId = Beleg::create([
'beleg_nr' => 'BK-TEST-' . uniqid(),
'filename' => 'bk-test.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'bk-test-' . uniqid()),
'beleg_datum' => date('Y-m-d'),
'belegtyp' => 'Eingangsrechnung',
]);
$this->testNurHauptbuchung($belegId, $ausgabeId, $zahlungsId);
$this->testMitVorsteuerZeile($belegId, $ausgabeId, $zahlungsId);
$this->testMitIgErwerbKindzeilen($belegId, $ausgabeId, $zahlungsId);
}
/** Buchung ohne 7/19%-USt und ohne ig. Erwerb → genau eine Zeile. */
private function testNurHauptbuchung(int $belegId, int $ausgabeId, int $zahlungsId): void
{
$bookingId = Booking::create([
'beleg_id' => $belegId,
'buchungs_datum' => date('Y-m-d'),
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $ausgabeId,
'zahlungskonto_id' => $zahlungsId,
'betrag_netto' => 42.00,
'ust_satz' => 0.0,
'buchungstext' => 'Test ohne USt-Zeile',
]);
$rows = Database::fetchAll('SELECT * FROM bookings WHERE beleg_id = ? AND id = ?', [$belegId, $bookingId]);
$this->assertEquals(1, count($rows), 'Buchung ohne 7/19%-USt erzeugt genau eine Zeile');
$kinder = Database::fetchAll('SELECT * FROM bookings WHERE parent_booking_id = ?', [$bookingId]);
$this->assertEquals(0, count($kinder), 'Buchung ohne 7/19%-USt erzeugt keine Kindzeilen');
}
/** Normale Buchung mit 19% USt → Hauptbuchung plus VSt-Korrekturzeile. */
private function testMitVorsteuerZeile(int $belegId, int $ausgabeId, int $zahlungsId): void
{
$bookingId = Booking::create([
'beleg_id' => $belegId,
'buchungs_datum' => date('Y-m-d'),
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $ausgabeId,
'zahlungskonto_id' => $zahlungsId,
'betrag_netto' => 100.00,
'ust_satz' => 19.0,
'buchungstext' => 'Test mit VSt-Zeile',
]);
$kinder = Database::fetchAll(
'SELECT bk.*, a.kontonummer FROM bookings bk
JOIN accounts a ON bk.kategorie_konto_id = a.id
WHERE bk.parent_booking_id = ?',
[$bookingId]
);
$this->assertEquals(1, count($kinder), 'Buchung mit 19% USt erzeugt genau eine VSt-Korrekturzeile');
$vstZeile = $kinder[0] ?? null;
$this->assert($vstZeile !== null, 'VSt-Korrekturzeile vorhanden');
if ($vstZeile !== null) {
$this->assertEquals('1576', $vstZeile['kontonummer'], 'VSt-Korrekturzeile bucht auf Konto 1576 (VSt 19%)');
$this->assertEquals(19.00, round((float)$vstZeile['betrag_netto'], 2), 'VSt-Korrekturzeile: Betrag = 19,00 €');
$this->assertEquals($bookingId, (int)$vstZeile['parent_booking_id'], 'VSt-Korrekturzeile referenziert die Hauptbuchung über parent_booking_id');
}
}
/** ig. Erwerb 19% → zwei Kindzeilen (VST_IGE_19 und UST_IGE_19). */
private function testMitIgErwerbKindzeilen(int $belegId, int $ausgabeId, int $zahlungsId): void
{
$bookingId = Booking::create([
'beleg_id' => $belegId,
'buchungs_datum' => date('Y-m-d'),
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $ausgabeId,
'zahlungskonto_id' => $zahlungsId,
'betrag_netto' => 1000.00,
'ust_satz' => 0.0,
'steuerart' => 'ig_erwerb_19',
'buchungstext' => 'Test ig. Erwerb 19%',
]);
$kinder = Database::fetchAll(
'SELECT bk.*, a.kontonummer FROM bookings bk
JOIN accounts a ON bk.kategorie_konto_id = a.id
WHERE bk.parent_booking_id = ?
ORDER BY a.kontonummer',
[$bookingId]
);
$this->assertEquals(2, count($kinder), 'ig. Erwerb 19% erzeugt genau zwei Kindzeilen');
$summeKinder = 0.0;
foreach ($kinder as $kind) {
$this->assertEquals($bookingId, (int)$kind['parent_booking_id'], 'Kindzeile referenziert die Hauptbuchung');
$summeKinder += (float)$kind['betrag_netto'];
}
$this->assertEquals(380.00, round($summeKinder, 2), 'Summe der Kindzeilen = 2 × 19% von 1000 € = 380 €');
}
}