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:
@@ -218,18 +218,24 @@ def _neutrale_kategorien(db: Session, user: User) -> set[int]:
|
||||
}
|
||||
|
||||
|
||||
def actual_expense_by_category(db: Session, user: User, label: str, start: date, end: date,
|
||||
base: str) -> dict[int, int]:
|
||||
"""Ist-Ausgaben je Kategorie in Hauptwährung (inkl. budgetierter Sparen-Transfers)."""
|
||||
def expense_rows(db: Session, user: User, label: str, start: date, end: date,
|
||||
base: str) -> list[tuple[int, Transaction, int]]:
|
||||
"""Die einzelnen Buchungen hinter den Ist-Ausgaben: (Kategorie, Buchung, Betrag).
|
||||
|
||||
Die Summe darueber IST der Ist-Wert – beides kommt aus dieser einen Stelle,
|
||||
damit eine Aufstellung nie etwas anderes ergeben kann als die Zahl, die sie
|
||||
erklaeren soll.
|
||||
"""
|
||||
from .uebertraege import verknuepfte_ids
|
||||
|
||||
result: dict[int, int] = defaultdict(int)
|
||||
neutral = _neutrale_kategorien(db, user)
|
||||
# Verknüpfte Buchungen sind zwei Seiten derselben Bewegung zwischen eigenen
|
||||
# Konten – Geld wurde verschoben, nicht ausgegeben. Übersprungen, nicht
|
||||
# umkategorisiert: Löst man die Verknüpfung, zählt die Buchung mit ihrer
|
||||
# alten Kategorie sofort wieder mit.
|
||||
verknuepft = verknuepfte_ids(db, user)
|
||||
zeilen: list[tuple[int, Transaction, int]] = []
|
||||
|
||||
expenses = (
|
||||
db.query(Transaction)
|
||||
.filter(
|
||||
@@ -243,7 +249,7 @@ def actual_expense_by_category(db: Session, user: User, label: str, start: date,
|
||||
for t in expenses:
|
||||
if t.category_id in neutral or t.id in verknuepft:
|
||||
continue
|
||||
result[t.category_id] += _to_base(db, t.amount_eur_cents, base, t.date)
|
||||
zeilen.append((t.category_id, t, _to_base(db, t.amount_eur_cents, base, t.date)))
|
||||
|
||||
# Transfers auf Sparen/Depot zählen (sofern nicht auf "neutral" gesetzt) als
|
||||
# budgetierte Ausgabe gegen budget_category_id.
|
||||
@@ -262,7 +268,16 @@ def actual_expense_by_category(db: Session, user: User, label: str, start: date,
|
||||
continue
|
||||
to_acc = db.get(Account, t.to_account_id) if t.to_account_id else None
|
||||
if to_acc is not None and to_acc.type in SAVINGS_ACCOUNT_TYPES:
|
||||
result[t.budget_category_id] += _to_base(db, t.amount_eur_cents, base, t.date)
|
||||
zeilen.append((t.budget_category_id, t, _to_base(db, t.amount_eur_cents, base, t.date)))
|
||||
return zeilen
|
||||
|
||||
|
||||
def actual_expense_by_category(db: Session, user: User, label: str, start: date, end: date,
|
||||
base: str) -> dict[int, int]:
|
||||
"""Ist-Ausgaben je Kategorie in Hauptwährung (inkl. budgetierter Sparen-Transfers)."""
|
||||
result: dict[int, int] = defaultdict(int)
|
||||
for cat_id, _txn, cents in expense_rows(db, user, label, start, end, base):
|
||||
result[cat_id] += cents
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user