diff --git a/Changes.md b/Changes.md index fc9bef7..9320679 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,38 @@ --- +## 2026-08-11 – Duplizierte View-Logik gebündelt: Kontengruppierung, Kontrastfarbe, Helper-Boilerplate (#158) + +- **Kontengruppierung** (`invoices/book.php`, `invoices/show.php`, `belege/_buchungsform.php`) war dreimal kopiert und bereits divergiert: Nur `belege/_buchungsform.php` (per `include` in `detail.php`) filterte Zahlungskonten auf den Nummernbereich 1200–1299, die beiden Rechnungs-Views nicht. Neue Methode `View::gruppiereKonten(array $accounts, bool $nurZahlungskonten1200 = false)` bündelt beide Varianten; alle drei Views wenden jetzt den Filter an (Parameter `true`). + - Entscheidung für „Filter überall anwenden“ statt „nirgends“ oder „Unterschied beibehalten“: `BuchungsvorlageController::modal()` filtert unabhängig davon bereits identisch auf 1200–1299 – das ist die etablierte Konvention für „welches Bankkonto hat die Zahlung erhalten“-Auswahlen im Projekt, nicht nur ein Sonderfall der Belegerfassung. Produktiv gab es zum Zeitpunkt der Änderung noch keine einzige Rechnungs-Zahlungsbuchung (0 Zeilen in `bookings` mit verknüpfter `invoices`), das Risiko eines bestehenden Workflows, der auf Kasse/Verrechnungskonto/USt-Konten als Zahlungskonto einer Rechnung angewiesen ist, bestand also nicht. + - Sichtbare Auswirkung: Im Zahlungs-Modal der Rechnungsdetailansicht und in `invoices/book.php` stehen jetzt nur noch die fünf Bankkonten (1200–1240) zur Auswahl, nicht mehr Kasse, Verrechnungskonto oder die Umsatzsteuerkonten. Siehe `docs/funktionen.md`. +- **Kontrastfarbe**: Die Formel zur Wahl einer lesbaren Textfarbe (`0.299*hexdec(...)+0.587*hexdec(...)+0.114*hexdec(...)`) stand identisch in fünf Views (`belege/detail.php`, `bank/index.php`, `bank/show.php`, `bank/fints.php`, `settings/bankimport.php`). Neue Methode `View::kontrastfarbe(string $hex, string $dunkel = '#1e293b', string $hell = '#ffffff')` validiert die Eingabe (fehlt `#`, ist der Wert zu kurz oder kein gültiges Hex, liefert sie die Standardfarbe statt der bisherigen stillen Rechnung auf 0, die bei leerem/kurzem Wert immer weiße Schrift ergab); dreistellige Kurzform (`#abc`) wird expandiert. Alle fünf Views delegieren jetzt an `View::kontrastfarbe()`. +- **Helper-Boilerplate**: `$h = fn($v) => View::h($v);` (36 Views) und `$fmt = fn($v) => View::formatMoney($v);` (8 exakte Duplikate; abweichende `$fmt`-Definitionen mit `abs()` bzw. ohne geschütztes Leerzeichen blieben unverändert) sind entfernt. `BaseController::renderView()` und `View::render()` stellen `$h`/`$fmt` jetzt per `$data['h'] ??= …` zentral bereit, bevor `extract()` läuft – Views, die die Variablen weiterhin selbst definieren, bleiben dadurch unverändert lauffähig. +- **`tests/87_ViewHelperTest.php`** (neu): Deckt `View::kontrastfarbe()` (bekannte Farben, ungültige/leere Werte → Standardfarbe, Kurzform-Expansion, eigene Standardfarben) und `View::gruppiereKonten()` (mit/ohne Filter) ab. + +## 2026-08-11 – belege/detail.php in Teil-Views und externe JS-Dateien aufgeteilt (#157) + +- `src/Views/belege/detail.php` war mit 1.548 Zeilen die mit Abstand größte Datei der Anwendung, davon 827 Zeilen JavaScript in neun ` - - - -
Dieser Beleg ist gesperrt (GoBD). Keine weiteren Buchungen möglich.
- - - - - - - - - [ - 'id' => (int)$a['id'], - 'lfd_nr' => (int)$a['lfd_nr'], - 'bezeichnung' => $a['bezeichnung'], - 'anschaffungsdatum' => $a['anschaffungsdatum'], - 'anschaffungskosten' => (float)$a['anschaffungskosten'], - 'account_id' => $a['account_id'] !== null ? (int)$a['account_id'] : null, -], $assets ?? []), JSON_HEX_TAG); -?> - - - - - - - - + + + + - - - - + - - + + + + - - - - - + + + diff --git a/src/Views/belege/list.php b/src/Views/belege/list.php index afe52c5..18ac223 100644 --- a/src/Views/belege/list.php +++ b/src/Views/belege/list.php @@ -1,4 +1,4 @@ - View::h($v); $suppliers = $suppliers ?? []; ?> +
diff --git a/src/Views/bookings/journal.php b/src/Views/bookings/journal.php index 9147857..5f0f913 100644 --- a/src/Views/bookings/journal.php +++ b/src/Views/bookings/journal.php @@ -1,4 +1,4 @@ - View::h($v); ?> +
diff --git a/src/Views/buchungsvorlagen/form.php b/src/Views/buchungsvorlagen/form.php index cf7520b..46160a6 100644 --- a/src/Views/buchungsvorlagen/form.php +++ b/src/Views/buchungsvorlagen/form.php @@ -1,6 +1,5 @@ htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); $isEdit = !empty($vorlage['id']); $action = $isEdit ? "/einstellungen/buchungsvorlagen/{$vorlage['id']}" : '/einstellungen/buchungsvorlagen'; diff --git a/src/Views/buchungsvorlagen/modal.php b/src/Views/buchungsvorlagen/modal.php index 9b55cff..2f90e36 100644 --- a/src/Views/buchungsvorlagen/modal.php +++ b/src/Views/buchungsvorlagen/modal.php @@ -1,6 +1,5 @@ htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); // Felder nach Gruppe_nr sortiert gruppieren (dynamisch, unabhängig von festen Nummern) $gruppenFelder = []; diff --git a/src/Views/customers/form.php b/src/Views/customers/form.php index c14aa4b..a422927 100644 --- a/src/Views/customers/form.php +++ b/src/Views/customers/form.php @@ -1,5 +1,3 @@ - View::h($v); ?> -
diff --git a/src/Views/customers/list.php b/src/Views/customers/list.php index 32fc8fe..0d00e8c 100644 --- a/src/Views/customers/list.php +++ b/src/Views/customers/list.php @@ -1,5 +1,3 @@ - View::h($v); ?> -
diff --git a/src/Views/customers/show.php b/src/Views/customers/show.php index 097010a..59573eb 100644 --- a/src/Views/customers/show.php +++ b/src/Views/customers/show.php @@ -1,4 +1,4 @@ - View::h($v); ?> +
diff --git a/src/Views/dashboard.php b/src/Views/dashboard.php index 1bf763b..8e233f7 100644 --- a/src/Views/dashboard.php +++ b/src/Views/dashboard.php @@ -1,7 +1,5 @@ View::h($v); -$fmt = fn($v) => View::formatMoney($v); // Jede Kachelzahl führt auf die Einzelbuchungen, aus denen sie besteht (#167). $detail = function (string $bucket, ?int $month = null) use ($stats): string { diff --git a/src/Views/dashboard_bucket.php b/src/Views/dashboard_bucket.php index ab6334d..ffae923 100644 --- a/src/Views/dashboard_bucket.php +++ b/src/Views/dashboard_bucket.php @@ -1,6 +1,5 @@ View::h($v); $fmt = fn($v) => number_format((float)$v, 2, ',', '.') . ' €'; // Beitrag der Buchung zur Kachelsumme. In der Ergebnis-Ansicht mindern diff --git a/src/Views/ereignisse/_body.php b/src/Views/ereignisse/_body.php index 025a26b..fb27054 100644 --- a/src/Views/ereignisse/_body.php +++ b/src/Views/ereignisse/_body.php @@ -1,7 +1,6 @@ View::h($v); $levelStyles = [ EventLog::LEVEL_ERROR => ['Fehler', 'var(--color-danger,#dc2626)'], diff --git a/src/Views/ereignisse/index.php b/src/Views/ereignisse/index.php index f58f351..ad34327 100644 --- a/src/Views/ereignisse/index.php +++ b/src/Views/ereignisse/index.php @@ -1,7 +1,6 @@ View::h($v); $aktiverKanal = $filter['channel'] ?? ''; $aktivesLevel = $filter['level'] ?? ''; diff --git a/src/Views/invoices/book.php b/src/Views/invoices/book.php index f2a3942..0704e10 100644 --- a/src/Views/invoices/book.php +++ b/src/Views/invoices/book.php @@ -1,7 +1,5 @@ View::h($v); -$fmt = fn($v) => View::formatMoney($v); $customerName = !empty($invoice['firma']) ? $invoice['firma'] @@ -10,10 +8,7 @@ $customerName = !empty($invoice['firma']) $formErrors = $formErrors ?? []; $formData = $formData ?? []; -$kontenGruppen = []; -foreach ($accounts as $acc) { - $kontenGruppen[$acc['kontenart']][] = $acc; -} +$kontenGruppen = View::gruppiereKonten($accounts, true); ?> diff --git a/src/Views/invoices/form.php b/src/Views/invoices/form.php index 4090c13..e49fba2 100644 --- a/src/Views/invoices/form.php +++ b/src/Views/invoices/form.php @@ -1,6 +1,5 @@ View::h($v); $isEdit = !empty($invoice['id']); // Pre-select customer if passed via GET $preCustomer = (int)($_GET['customer_id'] ?? 0); diff --git a/src/Views/invoices/list.php b/src/Views/invoices/list.php index 734ac64..a5eecb6 100644 --- a/src/Views/invoices/list.php +++ b/src/Views/invoices/list.php @@ -1,4 +1,4 @@ - View::h($v); ?> +
diff --git a/src/Views/invoices/show.php b/src/Views/invoices/show.php index b974c62..e8c9b70 100644 --- a/src/Views/invoices/show.php +++ b/src/Views/invoices/show.php @@ -1,7 +1,5 @@ View::h($v); -$fmt = fn($v) => View::formatMoney($v); $customerName = !empty($invoice['firma']) ? $invoice['firma'] @@ -429,8 +427,7 @@ $badgeClass = match($invoice['status']) {