Steuerkram/tests/09_InvoiceToReportsTest.php

139 lines
6.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 9: Ausgangsrechnung → Dashboard / EÜR / UStVA.
*
* Prüft den vollständigen Pfad: Ausgangsrechnung anlegen, finalisieren,
* Buchung erzeugen und sicherstellen, dass die Werte im Dashboard,
* in der EÜR und in der UStVA erscheinen.
*/
class InvoiceToReportsTest extends TestCase
{
protected string $testName = 'Test 9: Ausgangsrechnung → Dashboard/EÜR/UStVA';
public function run(): void
{
$year = (int)date('Y');
$month = (int)date('n');
$datum = date('Y-m-d');
// ── Konten prüfen ────────────────────────────────────────────────────
$zahlungsId = $this->findAccountId('1200'); // Bank
$erloes19Id = $this->findAccountId('8400'); // Erlöse 19 % USt
if (!$zahlungsId || !$erloes19Id) {
$this->assert(false, 'Benötigte Konten (1200, 8400) nicht gefunden – SKR03-Seed vorhanden?');
return;
}
$this->assert(true, 'Konten 1200 und 8400 vorhanden');
// ── Kunde und Rechnung anlegen ────────────────────────────────────────
$customerId = \Steuerkram\Models\Customer::create([
'nachname' => 'ReportTest',
'firma' => 'Report GmbH',
'strasse' => 'Musterstraße 1',
'plz' => '10115',
'ort' => 'Berlin',
'payment_days' => 14,
]);
$invoiceId = \Steuerkram\Models\Invoice::create([
'customer_id' => $customerId,
'betreff' => 'Testrechnung für Report-Integration',
'rechnungs_datum' => $datum,
'leistungszeitraum_von' => date('Y-m-01'),
'leistungszeitraum_bis' => date('Y-m-t'),
'lines' => [
[
'bezeichnung' => 'Beratungsleistung',
'menge' => 10,
'einheit' => 'h',
'einzelpreis' => 100.00,
'ust_satz' => 19.0,
],
],
]);
$this->assertGreaterThan(0, $invoiceId, 'Rechnung angelegt');
// ── Finalisieren (Modell-Methode, wie in InvoiceController::finalize) ──
$rechnungsNr = \Steuerkram\Models\Invoice::finalize($invoiceId);
$this->assertNotEmpty($rechnungsNr, 'Rechnungsnummer nach Finalisierung vorhanden');
$invoice = \Steuerkram\Models\Invoice::find($invoiceId);
$this->assertEquals('Gesendet', $invoice['status'] ?? null, 'Status nach Finalisierung: Gesendet');
// ── Beleg und Buchungen anlegen (wie InvoiceController::createBelegAndBookings) ──
$belegNr = \Steuerkram\Models\Beleg::generateBelegNr();
$belegId = \Steuerkram\Models\Beleg::create([
'beleg_nr' => $belegNr,
'filename' => $rechnungsNr . '.pdf',
'storage_path' => '',
'mime_type' => 'application/pdf',
'file_hash' => hash('sha256', $rechnungsNr),
'beleg_datum' => $invoice['rechnungs_datum'],
'rechnungs_nr' => $rechnungsNr,
'betrag_brutto' => $invoice['betrag_brutto'],
'belegtyp' => 'Ausgangsrechnung',
'notes' => 'Test Ausgangsrechnung',
]);
$this->assertGreaterThan(0, $belegId, 'Beleg angelegt');
$lines = \Steuerkram\Models\Invoice::lines($invoiceId);
$this->assertGreaterThan(0, count($lines), 'Rechnungspositionen vorhanden');
$gruppenNetto = [];
foreach ($lines as $line) {
$satz = (float)$line['ust_satz'];
$netto = round((float)$line['menge'] * (float)$line['einzelpreis'], 2);
$gruppenNetto[$satz] = ($gruppenNetto[$satz] ?? 0.0) + $netto;
}
foreach ($gruppenNetto as $satz => $netto) {
$kategorieId = $erloes19Id; // vereinfacht für Test mit 19 %
\Steuerkram\Models\Booking::create([
'beleg_id' => $belegId,
'buchungs_datum' => $invoice['rechnungs_datum'],
'buchungstyp' => 'Einnahme',
'kategorie_konto_id' => $kategorieId,
'zahlungskonto_id' => $zahlungsId,
'betrag_netto' => round($netto, 2),
'ust_satz' => $satz,
'buchungstext' => 'Ausgangsrechnung ' . $rechnungsNr,
]);
}
\Steuerkram\Database::execute(
'UPDATE invoices SET beleg_id=? WHERE id=?', [$belegId, $invoiceId]
);
$this->assert(true, 'Buchungen und Beleg-Verknüpfung erstellt');
// ── EÜR prüfen ───────────────────────────────────────────────────────
$euer = (new \Steuerkram\Services\EuerCalculator())->calculate($year);
$this->assert(
(float)$euer['total_einnahmen'] >= 1000.00,
'EÜR: Einnahmen ≥ 1000 € (Ausgangsrechnung eingeflossen)'
);
// ── UStVA prüfen ─────────────────────────────────────────────────────
$kz = (new \Steuerkram\Services\UstvaCalculator())->calculate($year, $month);
$this->assert(
(float)$kz['81']['betrag'] >= 1000.00,
'UStVA Kz 81 (Umsätze 19 %): Betrag ≥ 1000 € (Ausgangsrechnung eingeflossen)'
);
// ── Dashboard-Abfrage prüfen ─────────────────────────────────────────
$umsatz = \Steuerkram\Database::fetchOne(
'SELECT COALESCE(SUM(bk.betrag_netto),0) as total
FROM bookings bk
JOIN fiscal_years fy ON bk.fiscal_year_id = fy.id
WHERE bk.buchungstyp = \'Einnahme\' AND bk.is_reversal = 0 AND fy.year = ?',
[$year]
);
$this->assert(
(float)($umsatz['total'] ?? 0) >= 1000.00,
'Dashboard-Abfrage: Umsatz ≥ 1000 € (Ausgangsrechnung eingeflossen)'
);
}
}