From bf3f56118e5333d7b0c4ec97689d46a16114bc6616fd23a72a31c2fe5cc48d70 Mon Sep 17 00:00:00 2001 From: wlfb Date: Mon, 20 Jul 2026 21:26:48 +0200 Subject: [PATCH] feat: Vorschlaege mit Rhythmus, Start und Hinweis Co-Authored-By: Claude Fable 5 --- finance/app/templates/planning.html | 12 +++++++++--- finance/tests/test_gui.py | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/finance/app/templates/planning.html b/finance/app/templates/planning.html index 9db9ce9..372e2ae 100644 --- a/finance/app/templates/planning.html +++ b/finance/app/templates/planning.html @@ -88,15 +88,19 @@ {% if suggestions %} - + {% for s in suggestions %} - + + @@ -113,8 +118,9 @@
NameBetragRhythmusFälligkeitstag
NameBetragRhythmusFälligkeitstagStart
{{ s.name }}{{ s.amount|eur }} € + {{ s.amount|eur }} € + {% if s.hinweis %}{{ s.hinweis }}{% endif %} + {{ s.rhythm|de_label }} {{ s.due_day }}{{ s.start_date.strftime('%d.%m.%Y') if s.start_date else '–' }}
@@ -105,6 +109,7 @@ +
{% else %} -

Keine Vorschläge — erkannt werden Serien aus mindestens 3 Monaten gleichartiger Buchungen.

+

Keine Vorschläge.

{% endif %} +

Erkannt werden monatliche, vierteljährliche und jährliche Serien; Betrag = jeweils letzte Buchung.

diff --git a/finance/tests/test_gui.py b/finance/tests/test_gui.py index 1e60716..fa3bcf4 100644 --- a/finance/tests/test_gui.py +++ b/finance/tests/test_gui.py @@ -246,6 +246,33 @@ def test_planning_page_shows_empty_suggestions_hint(client): assert r.status_code == 200 assert "Vorschläge aus Buchungen" in r.text assert "Keine Vorschläge" in r.text + assert ("Erkannt werden monatliche, vierteljährliche und jährliche " + "Serien; Betrag = jeweils letzte Buchung.") in r.text + + +def test_vorschlaege_zeigen_rhythmus_und_start(client, db): + # Synthetische vierteljaehrliche Serie relativ zu date.today(), da die + # Route suggest_recurring() ohne today-Injektion aufruft (echter + # Aktiv-Check gegen date.today()). Schrittweite ~91 Tage rueckwaerts, + # letzte Buchung 30 Tage vor heute (innerhalb des Aktiv-Fensters). + from app.models.tables import Transaction + + client.post("/login", data={"username": "admin", "password": "geheim"}) + acc = Account(bank="dkb", iban="DE-SUG-1", name="S", type="giro") + db.add(acc) + db.flush() + today = date.today() + booking_dates = [today - timedelta(days=d) for d in (303, 212, 121, 30)] + for d in booking_dates: + db.add(Transaction(account_id=acc.id, booking_date=d, amount=Decimal("-55.08"), + purpose="p", counterparty="Rundfunk Synth", status="confirmed", + dedup_hash=f"sug-{d.isoformat()}")) + db.commit() + r = client.get("/planung").text + letzte_buchung = booking_dates[-1] + assert "vierteljährlich" in r + assert letzte_buchung.strftime("%d.%m.%Y") in r + assert 'name="start_date"' in r def test_salden_page_stichtag_and_month_overview(client, db):