feat: Zeigen, welche Buchungen in einem Ausgaben-Anteil stecken
Eine Zahl, die man nicht aufschluesseln kann, muss man glauben. Genau das war der Streitpunkt: Die Karte nannte fuer Lebensmittel einen Betrag, und es gab keine Moeglichkeit nachzusehen, welche Zahlungen darin einbezogen sind und welche nicht. Jetzt oeffnet ein Klick auf einen Anteil - in der Liste wie in der Legende des Kreises - die Buchungen dahinter: Datum, Empfaenger, Konto, Betrag. Die Liste kommt aus derselben Stelle, die auch die Summe bildet (`budget.expense_rows`), sie kann also gar nicht etwas anderes zeigen als das, was gezaehlt wurde. Ein Test haelt das fest. Steht eine Buchung darin, obwohl ihr Datum ausserhalb des Zeitraums liegt, traegt sie die Kalendermarke: Dann wurde ihr Budget-Monat von Hand gesetzt, und das ist der Grund. Nebenbei: Dialoge haengen jetzt am Seitenkoerper. Kacheln der Uebersicht werden per `transform` positioniert - damit war die Kachel der Bezugsrahmen fuer `position: fixed`, und der Dialog sass eingeklemmt darin statt ueber der Seite. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -309,3 +309,63 @@ def test_der_eigene_monat_wird_nicht_festgeschrieben(admin):
|
||||
assert tx["budget_period"] == "2026-10"
|
||||
assert b.period_of(date(2026, 9, 26), 25) == "2026-10"
|
||||
admin.put("/api/settings/budget_start_day", params={"value": "1"})
|
||||
|
||||
|
||||
def test_aufstellung_ergibt_genau_die_summe_der_karte(admin):
|
||||
"""Die Aufstellung kommt aus derselben Stelle wie die Summe – sie kann also
|
||||
gar nicht etwas anderes zeigen als das, was gezaehlt wurde."""
|
||||
import secrets
|
||||
|
||||
admin.put("/api/settings/budget_start_day", params={"value": "1"})
|
||||
today = date.today()
|
||||
acc = admin.post("/api/accounts", json={
|
||||
"name": f"Aufstellung {secrets.token_hex(3)}", "currency": "EUR"}).json()
|
||||
leb = _lebensmittel(admin)
|
||||
betraege = [1234, 5678, 999]
|
||||
for c in betraege:
|
||||
admin.post("/api/transactions", json={
|
||||
"type": "expense", "date": str(today), "account_id": acc["id"],
|
||||
"amount_cents": c, "category_id": leb, "payee": f"Laden {c}"})
|
||||
|
||||
karte = admin.get("/api/dashboard/expense-share?group_by=category").json()
|
||||
zeile = next(r for r in karte["rows"] if r["name"] == "Lebensmittel")
|
||||
assert zeile["ids"], "ohne die Kategorien laesst sich nichts aufschluesseln"
|
||||
|
||||
ids = "&".join(f"ids={i}" for i in zeile["ids"])
|
||||
auf = admin.get(f"/api/dashboard/expense-share/buchungen?{ids}").json()
|
||||
assert auf["total"] == zeile["amount"], "Aufstellung und Karte muessen dasselbe ergeben"
|
||||
assert sum(r["base_cents"] for r in auf["rows"]) == zeile["amount"]
|
||||
assert auf["von"] == karte["von"] and auf["bis"] == karte["bis"]
|
||||
|
||||
# Unsere drei Buchungen stehen darin, jede genau einmal.
|
||||
unsere = [r for r in auf["rows"] if r["title"].startswith("Laden ")]
|
||||
assert sorted(r["amount_cents"] for r in unsere) == sorted(betraege)
|
||||
|
||||
|
||||
def test_aufstellung_zeigt_eine_verschobene_buchung_im_neuen_monat(admin):
|
||||
"""Wandert eine Buchung, wandert sie auch in der Aufstellung mit."""
|
||||
import secrets
|
||||
|
||||
from app.services import budget as b
|
||||
|
||||
admin.put("/api/settings/budget_start_day", params={"value": "1"})
|
||||
today = date.today()
|
||||
hier = b.period_of(today, 1)
|
||||
acc = admin.post("/api/accounts", json={
|
||||
"name": f"Wander {secrets.token_hex(3)}", "currency": "EUR"}).json()
|
||||
leb = _lebensmittel(admin)
|
||||
tx = admin.post("/api/transactions", json={
|
||||
"type": "expense", "date": str(today), "account_id": acc["id"],
|
||||
"amount_cents": 4242, "category_id": leb, "payee": "Wanderladen"}).json()
|
||||
|
||||
karte = admin.get("/api/dashboard/expense-share?group_by=category").json()
|
||||
ids = "&".join(f"ids={i}" for i in
|
||||
next(r for r in karte["rows"] if r["name"] == "Lebensmittel")["ids"])
|
||||
assert any(r["id"] == tx["id"] for r in
|
||||
admin.get(f"/api/dashboard/expense-share/buchungen?{ids}").json()["rows"])
|
||||
|
||||
admin.patch(f"/api/transactions/{tx['id']}", json={"budget_period": b.shift_label(hier, 1)})
|
||||
auf = admin.get(f"/api/dashboard/expense-share/buchungen?{ids}").json()
|
||||
assert not any(r["id"] == tx["id"] for r in auf["rows"])
|
||||
karte2 = admin.get("/api/dashboard/expense-share?group_by=category").json()
|
||||
assert auf["total"] == next(r for r in karte2["rows"] if r["name"] == "Lebensmittel")["amount"]
|
||||
|
||||
Reference in New Issue
Block a user