diff --git a/Changes.md b/Changes.md index 26ebf1a..9335ef8 100644 --- a/Changes.md +++ b/Changes.md @@ -1,5 +1,23 @@ # Änderungen +## Adressverwaltung in der Verwaltung, Typeahead im Zahlungsverkehr (31.08.2026) + +Das Adressbuch (bisher nur über die Verträge-Kachel erreichbar) bekommt in der Verwaltung +eine eigene Kachel „Adressverwaltung“ (Feature #51) – es speist auch den Zahlungsverkehr, +der mit Verträgen nichts zu tun hat. Die Adressliste unter `/vertraege/adressen` bleibt die +gleiche Seite; zu jeder Adresse klappt jetzt ein `
`-Element ihre letzten Buchungen +auf. Da die Buchung kein Fremdschlüsselfeld auf die Adresse führt, sucht +`Buchung::letzteFuerEmpfaenger()` kontenübergreifend nach dem exakten Empfängernamen – die +eindeutige Kombination aus `benutzer_id` und `name` in `adressen` (Migration 008) macht das +zuverlässig. + +Die Empfängerauswahl im Zahlungsverkehr-Formular ist jetzt ein Typeahead: `kombobox.js` +(schon für die Kategorie im Kontoblatt im Einsatz) baut das ``) trägt +zusätzlich `data-kombobox` und wird wie die Kategorie im Kontoblatt (`kombobox.js`, siehe +`docs/`-Test 35) zu einem Eingabefeld mit gefilterter Liste. Die Auswahl füllt Name, IBAN und +BIC; geändert werden darf danach alles. + +**Der Empfänger landet wirklich im Adressbuch**, wenn beim Erfassen einer Überweisung +„Empfänger ins Adressbuch übernehmen“ angekreuzt ist – `ZahlungsverkehrController::anlegen()` +ruft dafür `Adresse::anlegen()` auf, nachdem der Zahlungsauftrag erfolgreich angelegt wurde; +gibt es die Adresse schon, bleibt der Fehler von `Adresse::anlegen()` (Duplikat) ohne Wirkung. + ## Verträge Der Nutzen liegt in der **Kündigungsfrist**: Die Übersicht zeigt, bis wann gekündigt sein diff --git a/public/static/app.css b/public/static/app.css index ccfde32..034c909 100644 --- a/public/static/app.css +++ b/public/static/app.css @@ -1133,6 +1133,9 @@ tr.zugeklappt { display: none; } .filterleiste .kombobox { max-width: 15rem; } .filterleiste .kombobox-eingabe { padding: .3rem .45rem; font-size: .9rem; } +.formular .kombobox { width: 100%; } +.formular .kombobox-eingabe { padding: .5rem .6rem; } + .zuordnungsauswahl .kombobox { width: 100%; max-width: 13rem; } .zuordnungsauswahl .kombobox-eingabe { height: 1.35rem; diff --git a/src/Controllers/VertraegeController.php b/src/Controllers/VertraegeController.php index 7522021..8a7ce99 100644 --- a/src/Controllers/VertraegeController.php +++ b/src/Controllers/VertraegeController.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Finanzmanager\Controllers; use Finanzmanager\Models\Adresse; +use Finanzmanager\Models\Buchung; use Finanzmanager\Models\Kategorie; use Finanzmanager\Models\Konto; use Finanzmanager\Models\Kredit; @@ -96,11 +97,18 @@ class VertraegeController extends BaseController { $this->verlangeAnmeldung(); - $suche = $this->query('suche'); + $suche = $this->query('suche'); + $adressen = Adresse::alle($suche); + + // Auf einen Blick, was zuletzt mit dem Empfänger gebucht wurde – ohne + // eigene Seite, denn die Liste bleibt kurz genug für den Direktabruf. + foreach ($adressen as $nummer => $adresse) { + $adressen[$nummer]['buchungen'] = Buchung::letzteFuerEmpfaenger((string)$adresse['name']); + } $this->render('vertraege/adressen.php', [ 'titel' => 'Adressen', - 'adressen' => Adresse::alle($suche), + 'adressen' => $adressen, 'suche' => $suche, ]); } diff --git a/src/Controllers/VerwaltungController.php b/src/Controllers/VerwaltungController.php index 4341f1b..6b8272c 100644 --- a/src/Controllers/VerwaltungController.php +++ b/src/Controllers/VerwaltungController.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Finanzmanager\Controllers; +use Finanzmanager\Models\Adresse; use Finanzmanager\Models\Bankinstitut; use Finanzmanager\Models\Einstellung; use Finanzmanager\Models\Erinnerung; @@ -44,6 +45,7 @@ class VerwaltungController extends BaseController 'vertraege' => count(Vertrag::alle(true)), 'fristen' => count(Vertrag::fristenLaufenAb(90)), 'bargeld' => count(Kategorie::bargeldAuswahl()), + 'adressen' => Adresse::anzahl(), ], 'bargeldAktiv' => BargeldAbgleich::eingerichtet(), ]); diff --git a/src/Models/Buchung.php b/src/Models/Buchung.php index 94eb82c..0f4e3c3 100644 --- a/src/Models/Buchung.php +++ b/src/Models/Buchung.php @@ -487,6 +487,32 @@ class Buchung return $anzahlen; } + /** + * Die jüngsten Buchungen zu einem Empfängernamen, kontenübergreifend – für + * die Adressverwaltung: Wer sich eine Adresse ansieht, will wissen, was + * zuletzt mit ihr gebucht wurde. Der Empfänger ist ein Freitextfeld, daher + * zählt der exakte Name; die Kollation der Spalte macht das unabhängig von + * Groß-/Kleinschreibung. + * + * @return list> + */ + public static function letzteFuerEmpfaenger(string $empfaenger, int $limit = 5): array + { + if ($empfaenger === '') { + return []; + } + + return Database::fetchAll( + 'SELECT b.id, b.datum, b.betrag, b.buchungstext, k.name AS kontoname + FROM buchungen b + JOIN konten k ON k.id = b.konto_id + WHERE b.benutzer_id = ? AND b.empfaenger = ? + ORDER BY b.datum DESC, b.id DESC + LIMIT ' . max(1, $limit), + [Mandant::id(), $empfaenger] + ); + } + /** Wie viele Buchungen hat das Konto (beide Sichten)? */ public static function anzahlFuerKonto(int $kontoId): int { diff --git a/src/Views/vertraege/adressen.php b/src/Views/vertraege/adressen.php index 0dc5fcd..860deee 100644 --- a/src/Views/vertraege/adressen.php +++ b/src/Views/vertraege/adressen.php @@ -90,6 +90,37 @@ include __DIR__ . '/../layout/kopf.php'; class="knopf klein gefahr">Löschen + + +
+ + Letzte Buchungen + + + +

Noch keine Buchung mit diesem Empfänger.

+ + + + + + + + + + + + + + + +
DatumKontoBuchungstextBetrag
+ +
+ +
+ + diff --git a/src/Views/verwaltung/index.php b/src/Views/verwaltung/index.php index 620dc9b..b7e1574 100644 --- a/src/Views/verwaltung/index.php +++ b/src/Views/verwaltung/index.php @@ -101,6 +101,18 @@ include __DIR__ . '/../layout/kopf.php'; +
+

Adressverwaltung

+

+

+ Das Adressbuch der Zahlungsempfänger – speist die Empfängerauswahl im + Zahlungsverkehr und zeigt zu jeder Adresse die letzten Buchungen. +

+ +
+

Termine

diff --git a/src/Views/zahlungsverkehr/formular.php b/src/Views/zahlungsverkehr/formular.php index a158014..d90950a 100644 --- a/src/Views/zahlungsverkehr/formular.php +++ b/src/Views/zahlungsverkehr/formular.php @@ -65,8 +65,11 @@ include __DIR__ . '/../layout/kopf.php';

Empfänger

- -