Steuerkram/tests/16_BewirtungssplitTest.php

176 lines
8 KiB
PHP

<?php
declare(strict_types=1);
/**
* Test 16: Bewirtungskonto-Split (70%/30%) bei Buchungen auf 4650/4651.
*
* Stellt sicher, dass:
* - Buchungen auf 4650 automatisch 70% auf 4650 und 30% auf 4654 aufteilen
* - Buchungen auf 4651 automatisch 70% auf 4651 und 30% auf 4656 aufteilen
* - bewirtungsgrund und teilnehmerliste korrekt gespeichert werden
* - Normale Buchungen (nicht 4650/4651) weiterhin als einzelne Buchung gespeichert werden
*/
class BewirtungssplitTest extends TestCase
{
protected string $testName = 'Test 16: Bewirtungskonto-Split 70%/30%';
public function run(): void
{
$datum = date('Y-m-d');
$bankId = $this->findAccountId('1200');
$kto4650 = $this->findAccountId('4650');
$kto4651 = $this->findAccountId('4651');
$kto4654 = $this->findAccountId('4654');
$kto4656 = $this->findAccountId('4656');
if (!$bankId || !$kto4650 || !$kto4651 || !$kto4654 || !$kto4656) {
$this->assert(false, 'Benötigte Konten (1200, 4650, 4651, 4654, 4656) nicht gefunden');
return;
}
// ── Test 1: Split bei Konto 4650 ─────────────────────────────
$beleg1 = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-BEW-4650-' . uniqid(),
'filename' => 'test.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'bew4650' . uniqid()),
'beleg_datum' => $datum,
'belegtyp' => 'Eingangsrechnung',
]);
\Steuerkram\Database::execute(
'UPDATE belege SET bewirtungsgrund = ?, teilnehmerliste = ? WHERE id = ?',
['Kundengespräch', 'Max Mustermann, Erika Mustermann', $beleg1]
);
// Bewirtungssplit direkt über Booking::create + zweite Buchung simulieren
// (wie BookingController::bucheBewirtungssplit() es tut)
$netto = 100.0;
$ustSatz = 19.0;
$netto70 = round($netto * 0.7, 2);
$netto30 = round($netto - $netto70, 2);
$id1a = \Steuerkram\Models\Booking::create([
'beleg_id' => $beleg1,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $kto4650,
'zahlungskonto_id' => $bankId,
'betrag_netto' => $netto70,
'ust_satz' => $ustSatz,
'buchungstext' => 'Bewirtung Test 70%',
]);
$id1b = \Steuerkram\Models\Booking::create([
'beleg_id' => $beleg1,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $kto4654,
'zahlungskonto_id' => $bankId,
'betrag_netto' => $netto30,
'ust_satz' => $ustSatz,
'buchungstext' => 'Bewirtung Test 30%',
]);
$b1a = \Steuerkram\Models\Booking::find($id1a);
$b1b = \Steuerkram\Models\Booking::find($id1b);
$this->assertEquals(70.0, (float)$b1a['betrag_netto'], '70%-Buchung hat 70% Netto');
$this->assertEquals(30.0, (float)$b1b['betrag_netto'], '30%-Buchung hat 30% Netto');
$this->assertEquals($kto4650, (int)$b1a['kategorie_konto_id'], '70%-Buchung auf 4650');
$this->assertEquals($kto4654, (int)$b1b['kategorie_konto_id'], '30%-Buchung auf 4654');
// USt wird proportional berechnet
$expectedUst70 = round($netto70 * $ustSatz / 100, 2);
$expectedUst30 = round($netto30 * $ustSatz / 100, 2);
$this->assertEquals($expectedUst70, (float)$b1a['betrag_ust'], '70%-Buchung USt korrekt');
$this->assertEquals($expectedUst30, (float)$b1b['betrag_ust'], '30%-Buchung USt korrekt');
// Gesamt-VSt = 100 * 19% = 19
$this->assertEquals(
round($netto * $ustSatz / 100, 2),
round((float)$b1a['betrag_ust'] + (float)$b1b['betrag_ust'], 2),
'Gesamt-Vorsteuer korrekt (100% des Nettobetrags)'
);
// Bewirtungsfelder auf dem Beleg gespeichert (seit Migration 024 in belege, nicht bookings)
$belegDaten = \Steuerkram\Models\Beleg::find($beleg1);
$this->assertEquals('Kundengespräch', $belegDaten['bewirtungsgrund'], 'Bewirtungsgrund gespeichert');
$this->assertEquals('Max Mustermann, Erika Mustermann', $belegDaten['teilnehmerliste'], 'Teilnehmerliste gespeichert');
// ── Test 2: Split bei Konto 4651 ─────────────────────────────
$beleg2 = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-BEW-4651-' . uniqid(),
'filename' => 'test2.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'bew4651' . uniqid()),
'beleg_datum' => $datum,
'belegtyp' => 'Eingangsrechnung',
]);
$id2a = \Steuerkram\Models\Booking::create([
'beleg_id' => $beleg2,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $kto4651,
'zahlungskonto_id' => $bankId,
'betrag_netto' => round(50.0 * 0.7, 2),
'ust_satz' => 7.0,
'buchungstext' => 'Bewirtung 4651 70%',
'bewirtungsgrund' => 'Teambesprechung',
'teilnehmerliste' => 'Team A',
]);
$id2b = \Steuerkram\Models\Booking::create([
'beleg_id' => $beleg2,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $kto4656,
'zahlungskonto_id' => $bankId,
'betrag_netto' => round(50.0 - round(50.0 * 0.7, 2), 2),
'ust_satz' => 7.0,
'buchungstext' => 'Bewirtung 4651 30%',
'bewirtungsgrund' => 'Teambesprechung',
'teilnehmerliste' => 'Team A',
]);
$b2a = \Steuerkram\Models\Booking::find($id2a);
$b2b = \Steuerkram\Models\Booking::find($id2b);
$this->assertEquals($kto4651, (int)$b2a['kategorie_konto_id'], '4651-Split: 70% auf 4651');
$this->assertEquals($kto4656, (int)$b2b['kategorie_konto_id'], '4651-Split: 30% auf 4656');
$this->assertEquals(35.0, (float)$b2a['betrag_netto'], '4651-Split: 70% von 50 = 35');
$this->assertEquals(15.0, (float)$b2b['betrag_netto'], '4651-Split: 30% von 50 = 15');
// ── Test 3: Normale Buchung unverändert ──────────────────────
$bankCheck = $this->findAccountId('4600');
if ($bankCheck) {
$beleg3 = \Steuerkram\Models\Beleg::create([
'beleg_nr' => 'TEST-BEW-NORMAL-' . uniqid(),
'filename' => 'test3.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', 'normal' . uniqid()),
'beleg_datum' => $datum,
'belegtyp' => 'Eingangsrechnung',
]);
$idNormal = \Steuerkram\Models\Booking::create([
'beleg_id' => $beleg3,
'buchungs_datum' => $datum,
'buchungstyp' => 'Ausgabe',
'kategorie_konto_id' => $bankCheck,
'zahlungskonto_id' => $bankId,
'betrag_netto' => 200.0,
'ust_satz' => 19.0,
'buchungstext' => 'Normale Buchung',
]);
$bNormal = \Steuerkram\Models\Booking::find($idNormal);
$this->assertEquals(200.0, (float)$bNormal['betrag_netto'], 'Normale Buchung: voller Nettobetrag unverändert');
$this->assertNotEmpty($idNormal, 'Normale Buchung erfolgreich gespeichert');
}
}
}