feat: Ausgaben-Anteile faerben nach Budget
Die Karte zeigte nur, wie sich die Ausgaben verteilen – nicht, ob sie im Rahmen liegen. Der Betrag ist jetzt gruen, solange er unter dem Geplanten bleibt, und rot darueber. Dieselben Farben wie ueberall sonst fuer Einnahme und Ausgabe. Ohne Plan bleibt der Betrag gedeckt. "Ueber Budget" waere sonst die Aussage ueber jede Kategorie, fuer die nie eine Vorgabe gemacht wurde – die Karte stuende dann fast durchgehend auf Rot und sagte nichts mehr. Das Geplante kommt aus derselben Quelle wie im Budget-Fortschritt, also einschliesslich eines Monats-Werts, der die Vorlage uebersteuert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -167,3 +167,45 @@ def test_budget_monate_stossen_lueckenlos_aneinander():
|
||||
f"Starttag {start_day}: {label} endet {bis}, "
|
||||
f"{naechstes} beginnt {von_naechstes}")
|
||||
label = naechstes
|
||||
|
||||
|
||||
def test_ausgabenanteile_nennen_das_geplante(admin):
|
||||
"""Die Karte soll zeigen, ob ein Anteil noch im Rahmen liegt. Ohne Plan
|
||||
wird nichts behauptet – 'ueber Budget' waere sonst die Aussage ueber jede
|
||||
Kategorie, fuer die nie eine Vorgabe gemacht wurde."""
|
||||
import datetime
|
||||
|
||||
leb = _lebensmittel(admin)
|
||||
name = next(c["name"] for g in admin.get("/api/categories").json()
|
||||
for c in g["categories"] if c["id"] == leb)
|
||||
konto = admin.post("/api/accounts", json={
|
||||
"name": "Anteile", "type": "girokonto", "currency": "EUR",
|
||||
"opening_balance_cents": 0}).json()
|
||||
admin.post("/api/transactions", json={
|
||||
"type": "expense", "date": datetime.date.today().isoformat(),
|
||||
"account_id": konto["id"], "amount_cents": 60000, "category_id": leb})
|
||||
|
||||
# Ueber den MONATS-Wert, nicht die Vorlage: Ein vorhandener Monats-Wert
|
||||
# aus einem anderen Test uebersteuert die Vorlage sonst.
|
||||
label = admin.get("/api/budget/current").json()["label"]
|
||||
|
||||
def plane(cents):
|
||||
r = admin.put(f"/api/budget/{label}/category/{leb}",
|
||||
params={"planned_cents": cents})
|
||||
assert r.status_code == 200, r.text
|
||||
|
||||
def zeile():
|
||||
rows = admin.get("/api/dashboard/expense-share").json()["rows"]
|
||||
return next(r for r in rows if r["name"] == name)
|
||||
|
||||
ist = zeile()["amount"]
|
||||
|
||||
plane(0)
|
||||
assert zeile()["planned"] == 0
|
||||
assert zeile()["over"] is False, "ohne Plan darf nichts als ueberschritten gelten"
|
||||
|
||||
plane(ist + 10000)
|
||||
assert zeile()["over"] is False, "im Rahmen"
|
||||
|
||||
plane(max(1, ist - 10000))
|
||||
assert zeile()["over"] is True, "ueberschritten"
|
||||
|
||||
Reference in New Issue
Block a user