findAccountId('1400'); // Debitorenkonto $erloesId = $this->findAccountId('8000'); // Erlöse 19 % if (!$debitorId) { $this->assert(false, 'Debitorenkonto 1400 nicht gefunden – SKR03-Seed vorhanden?'); return; } if (!$erloesId) { $this->assert(false, 'Erlöskonto 8000 nicht gefunden – SKR03-Seed vorhanden?'); return; } $this->assert(true, 'Benötigte Konten (1400, 8000) vorhanden'); // Testkunden anlegen $customerId = \Steuerkram\Models\Customer::create([ 'nachname' => 'Buchungstest', 'firma' => 'Buchungs GmbH', 'strasse' => 'Hauptstraße 1', 'plz' => '10115', 'ort' => 'Berlin', 'payment_days' => 30, ]); // Rechnung anlegen und finalisieren $datum = date('Y-m-d'); $invoiceId = \Steuerkram\Models\Invoice::create([ 'customer_id' => $customerId, 'betreff' => 'Testrechnung für Buchungstest', 'rechnungs_datum' => $datum, 'leistungszeitraum_von' => date('Y-m-01'), 'leistungszeitraum_bis' => date('Y-m-t'), 'lines' => [ [ 'bezeichnung' => 'Beratungsleistung', 'menge' => 5, 'einheit' => 'Std.', 'einzelpreis' => 200.00, 'ust_satz' => 19.0, ], ], ]); $nr = \Steuerkram\Models\Invoice::finalize($invoiceId); $this->assertNotEmpty($nr, 'Rechnung wurde finalisiert (Rechnungsnummer erhalten)'); $invoice = \Steuerkram\Models\Invoice::find($invoiceId); $this->assertEquals('Gesendet', $invoice['status'] ?? null, 'Rechnungsstatus ist Gesendet'); // Buchungen erzeugen (wie InvoiceController::createBelegAndBookings) $belegNr = \Steuerkram\Models\Beleg::generateBelegNr(); $belegId = \Steuerkram\Models\Beleg::create([ 'beleg_nr' => $belegNr, 'filename' => $nr . '.pdf', 'storage_path' => '', 'mime_type' => 'application/pdf', 'file_hash' => hash('sha256', $nr), 'beleg_datum' => $invoice['rechnungs_datum'], 'eingangs_datum' => $invoice['rechnungs_datum'], 'rechnungs_nr' => $nr, 'betrag_brutto' => $invoice['betrag_brutto'], 'belegtyp' => 'Ausgangsrechnung', ]); $lines = \Steuerkram\Models\Invoice::lines($invoiceId); $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; } $buchungIds = []; foreach ($gruppenNetto as $satz => $netto) { $buchungIds[] = \Steuerkram\Models\Booking::create([ 'beleg_id' => $belegId, 'buchungs_datum' => $invoice['rechnungs_datum'], 'soll_konto_id' => $debitorId, 'haben_konto_id' => $erloesId, 'betrag_netto' => round($netto, 2), 'ust_satz' => $satz, 'buchungstext' => 'Ausgangsrechnung ' . $nr, ]); } $this->assertGreaterThan(0, count($buchungIds), 'Mindestens eine Buchung wurde erzeugt'); // Im Journal auffindbar $year = (int)date('Y'); $month = (int)date('n'); $journal = \Steuerkram\Models\Booking::journal(['year' => $year, 'month' => $month], 1, 999); $foundCount = 0; foreach ($journal['rows'] as $row) { if (in_array((int)$row['id'], $buchungIds, true)) { $foundCount++; } } $this->assertEquals(count($buchungIds), $foundCount, 'Alle Buchungszeilen im Buchungsjournal'); // Buchungsinhalt prüfen (erste Buchung) $firstId = $buchungIds[0]; foreach ($journal['rows'] as $row) { if ((int)$row['id'] === $firstId) { $this->assertEquals(1000.00, (float)$row['betrag_netto'], 'Nettobetrag 1000 € korrekt'); $this->assertEquals(19.0, (float)$row['ust_satz'], 'USt-Satz 19 % korrekt'); $this->assertEquals(190.00, (float)$row['betrag_ust'], 'USt-Betrag 190 € korrekt'); $this->assertEquals(1190.00, (float)$row['betrag_brutto'], 'Bruttobetrag 1190 € korrekt'); $this->assertNotEmpty($row['beleg_nr'], 'Belegnummer im Journal vorhanden'); $this->assertNotEmpty($row['soll_nr'], 'Soll-Konto im Journal vorhanden'); $this->assertNotEmpty($row['haben_nr'], 'Haben-Konto im Journal vorhanden'); break; } } } }