Fix #2: Ausgangsrechnung automatisch buchen beim Finalisieren
Beim Finalisieren einer Rechnung wurde bisher kein Beleg und keine Buchungszeilen erstellt – der Nutzer musste danach manuell "Buchen" klicken, was nicht offensichtlich war. - finalize() erstellt jetzt atomar Beleg + Buchungszeilen (via createBelegAndBookings) innerhalb derselben Transaktion - Buchungslogik aus book() in private Methode extrahiert (DRY), book()-Route bleibt für bereits finalisierte, noch ungebuchte Rechnungen erhalten - "Buchen"-Button in der Show-View entfernt (nicht mehr nötig)
This commit is contained in:
parent
2942b663ec
commit
08b99e3992
2 changed files with 79 additions and 73 deletions
|
|
@ -169,12 +169,18 @@ class InvoiceController
|
|||
{
|
||||
$id = (int)$params['id'];
|
||||
try {
|
||||
\Steuerkram\Database::beginTransaction();
|
||||
$nr = Invoice::finalize($id);
|
||||
View::redirect("/invoices/{$id}", "Rechnung {$nr} wurde finalisiert.");
|
||||
$invoice = Invoice::find($id);
|
||||
$belegNr = $this->createBelegAndBookings($invoice);
|
||||
\Steuerkram\Database::commit();
|
||||
View::redirect("/invoices/{$id}", "Rechnung {$nr} wurde finalisiert und gebucht (Beleg {$belegNr}).");
|
||||
} catch (\PDOException $e) {
|
||||
\Steuerkram\Database::rollBack();
|
||||
error_log('[Steuerkram] PDO-Fehler in InvoiceController::finalize(): ' . $e->getMessage());
|
||||
View::redirect("/invoices/{$id}", 'Datenbankfehler beim Finalisieren der Rechnung.', 'error');
|
||||
} catch (\Exception $e) {
|
||||
\Steuerkram\Database::rollBack();
|
||||
View::redirect("/invoices/{$id}", $e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
|
|
@ -208,8 +214,23 @@ class InvoiceController
|
|||
|
||||
try {
|
||||
\Steuerkram\Database::beginTransaction();
|
||||
$belegNr = $this->createBelegAndBookings($invoice);
|
||||
\Steuerkram\Database::commit();
|
||||
View::redirect("/invoices/{$id}", 'Rechnung erfolgreich gebucht (Beleg ' . $belegNr . ').');
|
||||
} catch (\PDOException $e) {
|
||||
\Steuerkram\Database::rollBack();
|
||||
error_log('[Steuerkram] PDO-Fehler in InvoiceController::book(): ' . $e->getMessage());
|
||||
View::redirect("/invoices/{$id}", 'Datenbankfehler beim Buchen der Rechnung.', 'error');
|
||||
} catch (\Exception $e) {
|
||||
\Steuerkram\Database::rollBack();
|
||||
View::redirect("/invoices/{$id}", $e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
private function createBelegAndBookings(array $invoice): string
|
||||
{
|
||||
$id = (int)$invoice['id'];
|
||||
|
||||
// Create Beleg for this invoice
|
||||
$belegNr = Beleg::generateBelegNr();
|
||||
$belegId = Beleg::create([
|
||||
'beleg_nr' => $belegNr,
|
||||
|
|
@ -228,8 +249,10 @@ class InvoiceController
|
|||
$debitorKonto = \Steuerkram\Database::fetchOne(
|
||||
'SELECT id FROM accounts WHERE kontonummer = ?', ['1400']
|
||||
);
|
||||
if (!$debitorKonto) {
|
||||
throw new \RuntimeException('Debitorenkonto 1400 nicht gefunden.');
|
||||
}
|
||||
|
||||
// Erlöse-Konten nach USt-Satz: 8000 (19%), 8200 (7%), 8400 (0%/steuerfrei)
|
||||
$erloesKonten = [];
|
||||
foreach (\Steuerkram\Database::fetchAll(
|
||||
"SELECT id, kontonummer FROM accounts WHERE kontonummer IN ('8000','8200','8400')"
|
||||
|
|
@ -237,7 +260,6 @@ class InvoiceController
|
|||
$erloesKonten[$row['kontonummer']] = $row['id'];
|
||||
}
|
||||
|
||||
// Buchungen pro USt-Satz aus den Rechnungszeilen
|
||||
$lines = Invoice::lines($id);
|
||||
$gruppenNetto = [];
|
||||
foreach ($lines as $line) {
|
||||
|
|
@ -269,21 +291,11 @@ class InvoiceController
|
|||
]);
|
||||
}
|
||||
|
||||
// Link beleg to invoice
|
||||
\Steuerkram\Database::execute(
|
||||
'UPDATE invoices SET beleg_id=? WHERE id=?', [$belegId, $id]
|
||||
);
|
||||
|
||||
\Steuerkram\Database::commit();
|
||||
View::redirect("/invoices/{$id}", 'Rechnung erfolgreich gebucht (Beleg ' . $belegNr . ').');
|
||||
} catch (\PDOException $e) {
|
||||
\Steuerkram\Database::rollBack();
|
||||
error_log('[Steuerkram] PDO-Fehler in InvoiceController::book(): ' . $e->getMessage());
|
||||
View::redirect("/invoices/{$id}", 'Datenbankfehler beim Buchen der Rechnung.', 'error');
|
||||
} catch (\Exception $e) {
|
||||
\Steuerkram\Database::rollBack();
|
||||
View::redirect("/invoices/{$id}", $e->getMessage(), 'error');
|
||||
}
|
||||
return $belegNr;
|
||||
}
|
||||
|
||||
public function markPaid(array $params): void
|
||||
|
|
|
|||
|
|
@ -39,12 +39,6 @@ $badgeClass = match($invoice['status']) {
|
|||
<?php if ($invoice['status'] !== 'Entwurf'): ?>
|
||||
<a href="/invoices/<?= $h($invoice['id']) ?>/pdf" class="btn btn-primary">PDF herunterladen</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($invoice['status'] === 'Gesendet' && empty($invoice['beleg_id'])): ?>
|
||||
<form method="post" action="/invoices/<?= $h($invoice['id']) ?>/book"
|
||||
data-confirm="Rechnung jetzt buchen?">
|
||||
<button type="submit" class="btn btn-success">Buchen</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php if ($invoice['status'] === 'Gesendet'): ?>
|
||||
<form method="post" action="/invoices/<?= $h($invoice['id']) ?>/mark-paid">
|
||||
<button type="submit" class="btn btn-success">Als bezahlt markieren</button>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue