diff --git a/Changes.md b/Changes.md index a4e3153..060f028 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,14 @@ --- +## 2026-04-27 – Feature: Neues Rechnungsnummernformat (PPPYYYYMM-nn) + +### Geändert +- `src/Models/Invoice.php`: `generateRechnungsNr()` erzeugt jetzt das Format `PPPYYYYMM-nn` (Prefix + Jahr + Monat + zweistellige Sequenz, die bei Bedarf wächst); Zähler wird monatlich zurückgesetzt +- `migrations/038_invoice_nr_month.sql`: Neue Spalte `invoice_nr_month` in `company_settings` + +--- + ## 2026-04-26 – Fix: Eigenanteil-Buchung als Einnahme statt Ausgabe ### Geändert diff --git a/migrations/038_invoice_nr_month.sql b/migrations/038_invoice_nr_month.sql new file mode 100644 index 0000000..b1be4ab --- /dev/null +++ b/migrations/038_invoice_nr_month.sql @@ -0,0 +1,2 @@ +ALTER TABLE company_settings + ADD COLUMN IF NOT EXISTS invoice_nr_month TINYINT UNSIGNED NOT NULL DEFAULT 0; diff --git a/src/Models/Invoice.php b/src/Models/Invoice.php index 2660e53..8fbbc20 100644 --- a/src/Models/Invoice.php +++ b/src/Models/Invoice.php @@ -262,24 +262,26 @@ class Invoice public static function generateRechnungsNr(): string { - $settings = Database::fetchOne( - 'SELECT invoice_nr_prefix, invoice_nr_next, invoice_nr_year FROM company_settings WHERE id=1' + $settings = Database::fetchOne( + 'SELECT invoice_nr_prefix, invoice_nr_next, invoice_nr_year, invoice_nr_month FROM company_settings WHERE id=1' ); - $prefix = $settings['invoice_nr_prefix'] ?? 'AR'; - $next = (int)($settings['invoice_nr_next'] ?? 1); - $savedYear = (int)($settings['invoice_nr_year'] ?? 0); - $year = (int)date('Y'); + $prefix = $settings['invoice_nr_prefix'] ?? 'AR'; + $next = (int)($settings['invoice_nr_next'] ?? 1); + $savedYear = (int)($settings['invoice_nr_year'] ?? 0); + $savedMonth = (int)($settings['invoice_nr_month'] ?? 0); + $year = (int)date('Y'); + $month = (int)date('n'); - // Reset counter on new year - if ($savedYear !== $year) { + if ($savedYear !== $year || $savedMonth !== $month) { $next = 1; } - $nr = sprintf('%s-%s-%04d', $prefix, $year, $next); + $digits = max(2, strlen((string)$next)); + $nr = sprintf('%s%04d%02d-%0' . $digits . 'd', $prefix, $year, $month, $next); Database::execute( - 'UPDATE company_settings SET invoice_nr_next=?, invoice_nr_year=? WHERE id=1', - [$next + 1, $year] + 'UPDATE company_settings SET invoice_nr_next=?, invoice_nr_year=?, invoice_nr_month=? WHERE id=1', + [$next + 1, $year, $month] ); return $nr; diff --git a/src/Services/PdfInvoiceService.php b/src/Services/PdfInvoiceService.php index 89615ac..dbf87d6 100644 --- a/src/Services/PdfInvoiceService.php +++ b/src/Services/PdfInvoiceService.php @@ -12,6 +12,8 @@ class PdfInvoiceService { $html = $this->buildHtml($invoice, $lines, $settings); + $fontDir = dirname(__DIR__) . '/fonts'; + $mpdf = new Mpdf([ 'mode' => 'utf-8', 'format' => 'A4', @@ -19,6 +21,16 @@ class PdfInvoiceService 'margin_bottom' => 25, 'margin_left' => 25, // DIN 5008: 25mm links 'margin_right' => 15, // DIN 5008: 15mm rechts + 'fontDir' => [$fontDir], + 'fontdata' => [ + 'opensans' => [ + 'R' => 'OpenSans-Regular.ttf', + 'B' => 'OpenSans-Bold.ttf', + 'I' => 'OpenSans-Italic.ttf', + 'BI' => 'OpenSans-BoldItalic.ttf', + ], + ], + 'default_font' => 'opensans', ]); $mpdf->SetTitle('Rechnung ' . ($invoice['rechnungs_nr'] ?? 'Entwurf')); @@ -107,11 +119,13 @@ class PdfInvoiceService
{$logoHtml}
+
- +
{$h($settings['firma'] ?? '')} · {$h($settings['strasse'] ?? '')} · {$h($settings['plz'] ?? '')} {$h($settings['ort'] ?? '')}
+
 
{$h($customerName)}
{$h($inv['strasse'])}
@@ -119,11 +133,12 @@ class PdfInvoiceService
RECHNUNGRechnung
+
@@ -190,7 +205,7 @@ HTML;
{$h($settings['firma'] ?? '')}
- {$h($settings['inhaber'] ?? '')}
+ Inh. {$h($settings['inhaber'] ?? '')}
{$h($settings['strasse'] ?? '')}
{$h($settings['plz'] ?? '')} {$h($settings['ort'] ?? '')}
USt-ID: {$h($settings['ust_id'] ?? '')} @@ -216,7 +231,7 @@ HTML; private function buildCss(): string { return << -
+
-
+
· ·
-
+



-
RECHNUNG
+
Rechnung
- +
- - - - - - + + + + + + - - - - - + + + + +
BetreffRechnungsnummerKundennummerLeistungszeitraumDatum
BetreffRechnungsnummerKundennummerLeistungszeitraumDatum
@@ -169,7 +169,7 @@ $badgeClass = match($invoice['status']) {

-
+ Inh.


USt-ID: diff --git a/src/fonts/OpenSans-Bold.ttf b/src/fonts/OpenSans-Bold.ttf new file mode 100644 index 0000000..51a6bb8 Binary files /dev/null and b/src/fonts/OpenSans-Bold.ttf differ diff --git a/src/fonts/OpenSans-BoldItalic.ttf b/src/fonts/OpenSans-BoldItalic.ttf new file mode 100644 index 0000000..7f58199 Binary files /dev/null and b/src/fonts/OpenSans-BoldItalic.ttf differ diff --git a/src/fonts/OpenSans-Italic.ttf b/src/fonts/OpenSans-Italic.ttf new file mode 100644 index 0000000..88c01b6 Binary files /dev/null and b/src/fonts/OpenSans-Italic.ttf differ diff --git a/src/fonts/OpenSans-Regular.ttf b/src/fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000..abd6746 Binary files /dev/null and b/src/fonts/OpenSans-Regular.ttf differ diff --git a/src/version.txt b/src/version.txt index 0ebbc35..b52cf7f 100644 --- a/src/version.txt +++ b/src/version.txt @@ -1 +1 @@ -1-260427 +1-260428