From aa1884c31e3c1bf85dbbebcd2e015cbce225bc74cb3fcc42b75a49b58fb4299e Mon Sep 17 00:00:00 2001 From: wlfb Date: Mon, 20 Jul 2026 11:42:04 +0200 Subject: [PATCH] feat: Inline-Bearbeiten fuer Fixposten, Einmalposten, Kredite und Szenario-Kopf Co-Authored-By: Claude Fable 5 --- finance/app/templates/planning.html | 93 +++++++++++++++++++++++++++-- finance/tests/test_gui.py | 18 +++++- 2 files changed, 106 insertions(+), 5 deletions(-) diff --git a/finance/app/templates/planning.html b/finance/app/templates/planning.html index e9273cd..2f6f917 100644 --- a/finance/app/templates/planning.html +++ b/finance/app/templates/planning.html @@ -11,7 +11,7 @@ {% for r in recurring %} - + {{ r.name }} {{ r.amount|eur }} € {{ r.rhythm|de_label }} @@ -20,6 +20,7 @@ {{ r.end_date.strftime('%d.%m.%Y') if r.end_date else '–' }} {{ category_names.get(r.category_id, '–') }} +
@@ -27,6 +28,31 @@
+ + +
+ + + + + + + + + +
+ + {% else %} Noch keine wiederkehrenden Posten. {% endfor %} @@ -100,12 +126,13 @@ {% for p in planned %} - + {{ p.name }} {{ p.amount|eur }} € {{ p.due.strftime('%d.%m.%Y') }} {{ category_names.get(p.category_id, '–') }} +
@@ -113,6 +140,24 @@
+ + +
+ + + + + + +
+ + {% else %} Noch keine Einmalposten. {% endfor %} @@ -145,7 +190,7 @@ {% for l in loans %} - + {{ l.name }} {{ l.principal|eur }} € {{ l.annual_rate_pct|eur }} % @@ -153,6 +198,7 @@ {{ l.payout_date.strftime('%d.%m.%Y') }} {{ l.repayment_type|de_label }} +
@@ -160,6 +206,27 @@
+ + + +
+ + + + + + + + +
+ +
@@ -199,11 +266,23 @@ {% set sc = row.scenario %}
{{ sc.name }} -

+

{{ sc.description }} · Wiederkehrende Posten: {{ 'ja' if sc.include_recurring else 'nein' }} · Einmalposten: {{ 'ja' if sc.include_planned else 'nein' }} +

+
Kredite zuordnen @@ -315,6 +394,12 @@ // json-form-Extension ist zentral in base.html registriert (eine // Definition fuer alle Templates, inkl. data-type="bool"-Handling). + function toggleEdit(prefix, id, editing) { + // UX-Regel: Zeilen werden versteckt (hidden), nie aus dem DOM entfernt. + document.getElementById(prefix + '-row-' + id).hidden = editing; + document.getElementById(prefix + '-edit-' + id).hidden = !editing; + } + function onModTargetTypeChange(select) { var form = select.closest('form'); var catSpan = form.querySelector('.mod-target-category'); diff --git a/finance/tests/test_gui.py b/finance/tests/test_gui.py index 9071e95..e003d46 100644 --- a/finance/tests/test_gui.py +++ b/finance/tests/test_gui.py @@ -2,7 +2,7 @@ from datetime import date, timedelta from decimal import Decimal from app.formats import eur -from app.models.tables import Account, RecurringItem +from app.models.tables import Account, Loan, PlannedItem, RecurringItem, Scenario H = {"Authorization": "Bearer test-key"} @@ -309,6 +309,22 @@ def test_salden_stichtag_garbage_falls_back_to_today(client): assert date.today().strftime('%d.%m.%Y') in r.text +def test_planung_hat_bearbeiten_formulare(client, db): + client.post("/login", data={"username": "admin", "password": "geheim"}) + db.add(RecurringItem(name="EditR", amount=Decimal("-5.00"), rhythm="monthly", due_day=1)) + db.add(PlannedItem(name="EditP", amount=Decimal("-7.00"), due=date(2026, 8, 1))) + db.add(Loan(name="EditL", principal=Decimal("1000.00"), + annual_rate_pct=Decimal("4.50"), term_months=12, + payout_date=date(2026, 8, 1), repayment_type="annuity")) + db.add(Scenario(name="EditS", description="d")) + db.commit() + r = client.get("/planung").text + assert r.count(">Bearbeiten") >= 4 + for fragment in ('hx-patch="/api/recurring/', 'hx-patch="/api/planned/', + 'hx-patch="/api/loans/', 'hx-patch="/api/scenarios/'): + assert fragment in r, fragment + + def test_salden_shows_ohne_anker_footnote(client, db): # UX-Regel: Konten ohne Anker sind immer sichtbar als relative Werte # gekennzeichnet, nicht stillschweigend wie geankerte Konten dargestellt.