Damit ist der geplante Funktionsumfang beisammen. Phase 4 abgeschlossen - Konfigurierbare Cockpit-Kacheln; abgewählte werden nicht berechnet - Einnahmen/Ausgaben je Monat als Balkenpaare mit Saldolinie, aufgesetzt auf den Summenbericht statt auf eine eigene Abfrage - Meine Ausgaben als Ring auf der obersten Kategorieebene - Offene Vorgänge aus allen Modulen Phase 5 – Online-Banking - nemiah/php-fints als Fork auf Codeberg, psr/log direkt eingebaut: die Anwendung hängt an keinem fremden Update-Zyklus - PIN AES-256-GCM-verschlüsselt; Schlüssel aus APP_KEY oder aus data/schluessel/app_key, den der Entrypoint einmalig erzeugt - TAN-Dialog über mehrere Requests (FinTs::persist plus serialisierte Aktion in der Sitzung) – ein wartender Prozess wäre mit php-fpm der falsche Weg - Abgleich statt Direktbuchung: verbinden, übernehmen oder verwerfen - Regeln mit vier Vergleichsarten, Betragsgrenzen und Split-Schema Phase 6 – Wertpapiere - Depotbuchung und Geldbuchung als zwei Seiten eines Geschäfts; betrag ist der Bruttowert, Nebenkosten stehen daneben - Einstand nach gleitendem Durchschnitt, realisierte Gewinne, Erträge - Kursabruf über Leeway oder FMP, täglicher Lauf per Cron - QIF-Import für !Type:Invst Dabei behoben: Der Import buchte den Geldfluss jedes Wertpapiergeschäfts als Abgang – auch bei Verkäufen und Dividenden; und er erkannte das Verrechnungskonto nicht, wenn dem Konto im L-Feld eine Kategorie vorangeht (bei Verkäufen also immer). Phase 7 – Nebenmodule und Zahlungsverkehr - Buchungsvorlagen inklusive QIF-Import, Splits werden mitskaliert - Regelmäßige Buchungen mit Fälligkeitslauf, Finanzkalender, Erinnerungen - Adressen mit IBAN-Prüfung, Verträge mit Kündigungsfrist, Sparziele - Kredite mit gerechnetem Tilgungsplan - Überweisungen über FinTS; die Buchung entsteht erst nach Annahme durch die Bank. Die pain.001-Nachricht erzeugt SepaXml selbst Nebenbei: .dockerignore ergänzt (ohne sie brach der Build an data/mariadb ab), PlatzhalterController entfernt, zwei Inline-Handler beseitigt, die die Content-Security-Policy ohnehin blockierte. 888 PHP-Prüfungen und 45 E2E-Tests grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
145 lines
6.6 KiB
Markdown
145 lines
6.6 KiB
Markdown
# Nebenmodule und Zahlungsverkehr
|
||
|
||
Was in Phase 7 dazugekommen ist: Buchungsvorlagen, regelmäßige Buchungen mit
|
||
Finanzkalender, Erinnerungen, Adressen, Verträge, Sparziele, Kredite und der
|
||
Zahlungsverkehr.
|
||
|
||
## Buchungsvorlagen
|
||
|
||
Eine Vorlage ist eine fertige Buchung ohne Datum. Sie kommt aus dem QIF
|
||
(`!Type:Memorized` – im Beispielexport 579 Stück, vom FinanzManager automatisch gemerkt)
|
||
oder entsteht aus einer vorhandenen Buchung.
|
||
|
||
**Splitzeilen werden mitskaliert.** Weicht der Betrag beim Buchen von dem der Vorlage ab,
|
||
ziehen die Splitzeilen im gleichen Verhältnis mit; die letzte bekommt den Rest, damit die
|
||
Summe auf den Cent zum Buchungsbetrag passt. Ohne das ließe sich eine Vorlage mit Splits
|
||
nur zu ihrem ursprünglichen Betrag buchen.
|
||
|
||
Die Liste sortiert nach Häufigkeit: Wer eine Vorlage sucht, sucht meist eine, die er schon
|
||
oft gebraucht hat.
|
||
|
||
Beim Import entsteht der **Name** aus Empfänger und Betrag – die QIF-Sektion führt keinen.
|
||
Kommt derselbe Name mehrfach vor, zählt ein Zähler hoch, statt Vorlagen stillschweigend zu
|
||
verschlucken.
|
||
|
||
## Regelmäßige Buchungen
|
||
|
||
Jede Reihe führt ihre **nächste Fälligkeit** mit sich. Der Fälligkeitslauf holt, was
|
||
ansteht, bucht es und schreibt das Datum fort. Eine Tabelle vorausberechneter Termine gibt
|
||
es bewusst nicht: Sie wäre bei jeder Änderung neu zu erzeugen.
|
||
|
||
Zwei Betriebsarten:
|
||
|
||
* **automatisch** – wird ohne Rückfrage gebucht. Für Miete und Gehalt, wo Betrag und
|
||
Termin feststehen.
|
||
* **auf Bestätigung** – wird nur gemeldet und wartet auf Knopfdruck. Für alles, dessen
|
||
Betrag schwankt.
|
||
|
||
Der Lauf ist gutmütig gegenüber langen Pausen: Liegen mehrere Termine zurück, wird **jeder
|
||
einzeln** gebucht, nicht einer für alle – nur so stimmen die Monatssummen. Nach dem Buchen
|
||
rückt die Fälligkeit so weit vor, bis sie in der Zukunft liegt.
|
||
|
||
In einen **abgeschlossenen Monat** wird nicht hineingebucht: Die Reihe bleibt stehen und
|
||
meldet sich, statt den ganzen Lauf mit einer Ausnahme abzubrechen.
|
||
|
||
*Überspringen* rückt vor, ohne zu buchen – für den Monat, in dem die Zahlung einmal
|
||
ausgesetzt wurde.
|
||
|
||
## Finanzkalender
|
||
|
||
Zusammengetragen aus vier Quellen: fällige regelmäßige Buchungen, offene Erinnerungen,
|
||
ablaufende Kündigungsfristen und terminierte Überweisungen. Alles gerechnet, nichts
|
||
gespeichert – eine Änderung an einer Reihe wirkt sich sofort aus.
|
||
|
||
Überfälliges bleibt sichtbar und wird markiert, statt aus der Liste zu fallen.
|
||
|
||
## Adressen und IBAN-Prüfung
|
||
|
||
Das Adressbuch speist die Empfängerauswahl im Zahlungsverkehr. **IBANs werden geprüft**
|
||
(ISO 13616: Länge je Land, Prüfziffer modulo 97). Das fängt Zahlendreher ab, bevor eine
|
||
Überweisung hinausgeht – die häufigste und ärgerlichste Fehlerquelle im Zahlungsverkehr.
|
||
|
||
Gerechnet wird stückweise mit `%` statt mit `bcmod`: Die BC-Erweiterung ist keine
|
||
Standardausstattung, und ein Modulo über sieben Ziffern lange Blöcke kommt ohne sie aus.
|
||
|
||
## Verträge
|
||
|
||
Der Nutzen liegt in der **Kündigungsfrist**: Die Übersicht zeigt, bis wann gekündigt sein
|
||
muss, damit sich ein Vertrag nicht stillschweigend verlängert. Verträge, deren Frist in den
|
||
nächsten 90 Tagen abläuft, stehen oben auf der Seite und im Finanzkalender.
|
||
|
||
Der **Jahresbetrag** rechnet verschieden getaktete Verträge vergleichbar: monatlich × 12,
|
||
vierteljährlich × 4 und so fort.
|
||
|
||
Ein Vertrag kann mit einer regelmäßigen Buchung verbunden sein, die seine Zahlung erledigt.
|
||
|
||
## Sparziele
|
||
|
||
Der erreichte Stand kommt **aus dem Kontosaldo**, nicht aus einem eigenen Zähler – ein
|
||
zweiter, gepflegter Wert liefe früher oder später von den Buchungen weg. Der Startbetrag
|
||
zieht ab, was zu Beginn schon auf dem Konto lag.
|
||
|
||
Zum Zieldatum rechnet die Anwendung aus, welche Monatsrate nötig wäre, um den Termin noch
|
||
zu halten.
|
||
|
||
Der Fortschrittsbalken ist ein `<progress>`-Element: Ein eigener Balken bräuchte seine
|
||
Breite als `style`-Attribut, und das verbietet die Content-Security-Policy.
|
||
|
||
## Kredite
|
||
|
||
Gerechnet wird als **Annuitätendarlehen**: gleichbleibende Rate, sinkender Zinsanteil,
|
||
wachsende Tilgung. Zinsen fallen je Periode auf die Restschuld an.
|
||
|
||
Der Tilgungsplan wird **gerechnet, nicht gespeichert** – er ergibt sich vollständig aus
|
||
Betrag, Zins, Rate und Beginn. Eine jährliche Sondertilgung wird im Dezember verrechnet.
|
||
|
||
Deckt die Rate nicht einmal die Zinsen der ersten Periode, entsteht kein Plan, sondern ein
|
||
Hinweis: So ein Kredit würde wachsen statt zu schrumpfen, und eine Endlosschleife wäre die
|
||
schlechtere Antwort darauf.
|
||
|
||
Bei langen Laufzeiten zeigt die Tabelle die nächsten zwei Jahre und das Ende; dazwischen
|
||
steht, wie viele Raten ausgelassen wurden.
|
||
|
||
## Zahlungsverkehr
|
||
|
||
**Erst die Bank, dann die Buchung.** Ein Zahlungsauftrag ist zunächst ein Entwurf. Die
|
||
Buchung auf dem Auftragskonto entsteht erst, wenn die Bank den Auftrag angenommen hat –
|
||
vorher wäre sie eine Behauptung, die man nach einer abgelehnten TAN wieder einsammeln
|
||
müsste.
|
||
|
||
Ein gesendeter Auftrag lässt sich weder ändern noch löschen: Er bleibt als Beleg stehen.
|
||
Fehlgeschlagene tragen die Meldung der Bank daneben.
|
||
|
||
Ohne Ausführungstermin geht die Überweisung sofort hinaus, mit Termin als
|
||
Terminüberweisung; sie erscheint dann im Finanzkalender.
|
||
|
||
### SEPA-XML von Hand
|
||
|
||
php-fints erwartet die fertige **pain.001.001.03**-Nachricht und erzeugt sie nicht. Die
|
||
üblichen Erzeuger wären zwei weitere Abhängigkeiten für ein Dokument von sechzig Zeilen –
|
||
`Services\SepaXml` schreibt es deshalb selbst.
|
||
|
||
Der **SEPA-Zeichenvorrat** ist eng: `a–z A–Z 0–9 / - ? : ( ) . , ' +` und Leerzeichen.
|
||
Umlaute werden umgeschrieben (ä → ae), alles Übrige fällt weg. Ohne diese Umschrift weist
|
||
die Bank den Auftrag zurück – und zwar erst nach dem Absenden.
|
||
|
||
Der Verwendungszweck endet bei 140 Zeichen; das ist das SEPA-Maß, alles darüber würde die
|
||
Bank ohnehin abschneiden.
|
||
|
||
### TAN
|
||
|
||
Für Überweisungen verlangt jede Bank eine TAN. Der Dialog wird genauso über die Sitzung
|
||
fortgesetzt wie beim Abruf (siehe `docs/banking.md`): Zustand sichern, Maske zeigen, nach
|
||
der Eingabe weitermachen.
|
||
|
||
Beim Abbrechen bleibt der Auftrag als Entwurf stehen und lässt sich erneut senden.
|
||
|
||
## Tests
|
||
|
||
`tests/18_NebenmoduleTest.php` – Vorlagen mit skalierten Splits und aus Buchungen,
|
||
QIF-Vorlagenimport samt Idempotenz, Terminrechnung und Fortschreiben der Fälligkeit,
|
||
Fälligkeitslauf (nur automatische Reihen, wartende rücken nicht vor), Erinnerungen,
|
||
IBAN-Prüfung mit gültigen und falschen Nummern, Kündigungsfristen und Jahresbeträge,
|
||
Sparfortschritt aus dem Konto, Tilgungsplan (Annuität, letzte Rate, Sondertilgung,
|
||
zu kleine Rate), Zahlungsaufträge (Buchung erst nach Annahme, Unveränderlichkeit,
|
||
Eingabeprüfungen), SEPA-XML (Schema, Zeichensatz, Wohlgeformtheit) und der Finanzkalender.
|