Merge pull request 'Fix: Altrechnung-PDF bei fehlendem Beleg-Speicherpfad on-demand generieren und speichern' (#68) from fds2610-bot/Steuerkram:main into main

Reviewed-on: https://codeberg.org/fds2610/Steuerkram/pulls/68
This commit is contained in:
fds2610 2026-05-06 04:57:21 +02:00
commit a5d6c7a495
2 changed files with 35 additions and 4 deletions

View file

@ -275,12 +275,13 @@ class InvoiceController
if (!$invoice) { http_response_code(404); return; } if (!$invoice) { http_response_code(404); return; }
// Gespeicherte PDF aus dem Beleg ausliefern (GoBD: unveränderlicher Stand) // Gespeicherte PDF aus dem Beleg ausliefern (GoBD: unveränderlicher Stand)
$beleg = null;
if (!empty($invoice['beleg_id'])) { if (!empty($invoice['beleg_id'])) {
$beleg = Beleg::find((int)$invoice['beleg_id']); $beleg = Beleg::find((int)$invoice['beleg_id']);
$absPath = $beleg $absPath = $beleg
? dirname(__DIR__, 2) . '/public/' . $beleg['storage_path'] ? dirname(__DIR__, 2) . '/public/' . $beleg['storage_path']
: ''; : '';
if ($absPath && file_exists($absPath)) { if ($absPath && is_file($absPath)) {
header('Content-Type: application/pdf'); header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . $beleg['filename'] . '"'); header('Content-Disposition: attachment; filename="' . $beleg['filename'] . '"');
header('Content-Length: ' . filesize($absPath)); header('Content-Length: ' . filesize($absPath));
@ -289,7 +290,7 @@ class InvoiceController
} }
} }
// Fallback: PDF on-the-fly generieren (Entwurf oder Beleg noch ohne Datei) // PDF generieren (Entwurf oder Altrechnung ohne gespeicherte Datei)
if (!empty($invoice['storno_of_id'])) { if (!empty($invoice['storno_of_id'])) {
$original = Invoice::find((int)$invoice['storno_of_id']); $original = Invoice::find((int)$invoice['storno_of_id']);
if ($original) { if ($original) {
@ -302,7 +303,37 @@ class InvoiceController
$settings = Setting::get(); $settings = Setting::get();
$svc = new PdfInvoiceService(); $svc = new PdfInvoiceService();
$svc->render($invoice, $lines, $settings); $pdf = $svc->renderToString($invoice, $lines, $settings);
// Finalisierte Altrechnung: PDF nachträglich im Beleg speichern
if ($invoice['status'] !== 'Entwurf' && $beleg !== null) {
if (!empty($beleg['storage_path'])) {
$relPath = $beleg['storage_path'];
$absDir = dirname(dirname(__DIR__, 2) . '/public/' . $relPath);
} else {
$year = date('Y', strtotime($invoice['rechnungs_datum']));
$relDir = 'static/uploads/' . $year . '/' . $beleg['beleg_nr'];
$relPath = $relDir . '/original.pdf';
$absDir = dirname(__DIR__, 2) . '/public/' . $relDir;
}
if (!is_dir($absDir)) {
mkdir($absDir, 0755, true);
}
$absFilePath = dirname(__DIR__, 2) . '/public/' . $relPath;
file_put_contents($absFilePath, $pdf);
\Steuerkram\Database::execute(
'UPDATE belege SET storage_path=?, filename=?, file_hash=?, updated_at=NOW() WHERE id=?',
[$relPath, ($invoice['rechnungs_nr'] ?? 'Rechnung') . '.pdf', hash('sha256', $pdf), (int)$invoice['beleg_id']]
);
}
$prefix = !empty($invoice['storno_of_id']) ? 'Stornorechnung-' : 'Rechnung-';
$filename = $prefix . ($invoice['rechnungs_nr'] ?? 'Entwurf') . '.pdf';
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . strlen($pdf));
echo $pdf;
} }
public function book(array $params): void public function book(array $params): void

View file

@ -1 +1 @@
1-260505 1-260506