feat: Eine Ausgabe, die kein Verlust ist
Sparen zaehlt im Budget wie eine Ausgabe – zu Recht, das Geld ist diesen Monat gebunden. Es stand danach aber in Rot da, und wer tausend zuruecklegte statt achthundert, bekam eine Warnung fuer etwas Gutes. Ein Haken an der Kategorie stellt das ab. Zwei Folgen: Der Betrag steht neutral. NICHT gruen: Gruen heisst in Certain ueberall "Geld kommt rein", und CHF 1'010 in Gruen liest sich als Einnahme. Grau sagt genau das Richtige – kein Verlust, kein Gewinn. Und mehr als geplant ist keine Ueberschreitung mehr. Das gilt auch eine Ebene hoeher: Eine Gruppe misst sich an dem, was WIRKLICH zu viel war. Sonst faerbt sich "Finanzen" rot, weil jemand gespart hat, und die echte Ueberschreitung daneben faellt nicht mehr auf. Angezeigt werden weiter die vollen Summen; nur das Urteil laesst das Sparen aus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
15c2a164ec
commit
ff621984dc
@@ -253,3 +253,79 @@ def test_uebertrag_am_stueck_haelt_sich_auch_daran(admin):
|
||||
assert _ist(admin, sparen) == vorher
|
||||
finally:
|
||||
_neutral_setzen(admin, sparen, False)
|
||||
|
||||
|
||||
# --- Eine Ausgabe, die kein Verlust ist --------------------------------------
|
||||
|
||||
|
||||
def test_sparen_zaehlt_weiter_gilt_aber_nicht_als_ueberschreitung(admin):
|
||||
"""Der Betrag bleibt im Budget – das Geld ist diesen Monat gebunden. Nur
|
||||
die Warnung faellt weg: Wer mehr zuruecklegt als geplant, hat nichts
|
||||
ueberzogen, und Rot waere schlicht falsch herum."""
|
||||
admin.put("/api/settings/budget_start_day", params={"value": "1"})
|
||||
sparen = _kategorie(admin, "Sparen & Investments")
|
||||
admin.put(f"/api/budget/template/category/{sparen}", params={"planned_cents": 10000})
|
||||
s = _sparen_szenario(admin, betrag=80000) # deutlich mehr als geplant
|
||||
|
||||
def zeile():
|
||||
v = admin.get("/api/budget/current").json()
|
||||
return next(c for g in v["groups"] for c in g["categories"]
|
||||
if c["category_id"] == sparen)
|
||||
|
||||
ohne = zeile()
|
||||
assert ohne["actual_cents"] >= 80000, "der Betrag muss weiter zaehlen"
|
||||
assert ohne["over"] is True, "die Tatsache bleibt die Tatsache"
|
||||
assert ohne["good"] is False
|
||||
|
||||
r = admin.patch(f"/api/categories/{sparen}", json={"spending_is_good": True})
|
||||
assert r.status_code == 200, r.text
|
||||
try:
|
||||
mit = zeile()
|
||||
assert mit["actual_cents"] == ohne["actual_cents"], "Betrag darf sich nicht aendern"
|
||||
assert mit["good"] is True, "die Kategorie meldet sich nicht als 'kein Verlust'"
|
||||
finally:
|
||||
admin.patch(f"/api/categories/{sparen}", json={"spending_is_good": False})
|
||||
admin.put(f"/api/budget/template/category/{sparen}", params={"planned_cents": 0})
|
||||
|
||||
|
||||
def test_gruppe_gilt_nur_dann_als_kein_verlust_wenn_alle_es_sind(admin):
|
||||
"""Sonst verschwindet eine echte Ueberschreitung hinter dem Sparen, das
|
||||
zufaellig in derselben Gruppe liegt."""
|
||||
sparen = _kategorie(admin, "Sparen & Investments")
|
||||
r = admin.patch(f"/api/categories/{sparen}", json={"spending_is_good": True})
|
||||
assert r.status_code == 200, r.text
|
||||
try:
|
||||
v = admin.get("/api/budget/current").json()
|
||||
gruppe = next(g for g in v["groups"]
|
||||
if any(c["category_id"] == sparen for c in g["categories"]))
|
||||
andere = [c for c in gruppe["categories"] if c["category_id"] != sparen]
|
||||
if andere:
|
||||
assert gruppe["good"] is False, "eine gemischte Gruppe ist nicht 'kein Verlust'"
|
||||
assert next(c for c in gruppe["categories"]
|
||||
if c["category_id"] == sparen)["good"] is True
|
||||
finally:
|
||||
admin.patch(f"/api/categories/{sparen}", json={"spending_is_good": False})
|
||||
|
||||
|
||||
def test_gruppe_wird_nicht_rot_weil_jemand_zu_viel_gespart_hat(admin):
|
||||
"""Die Ueberschreitung einer Gruppe misst sich an dem, was wirklich zu viel
|
||||
war. Sonst faerbt sich "Finanzen" rot, weil mehr zurueckgelegt wurde als
|
||||
geplant – und die echte Ueberschreitung daneben faellt nicht mehr auf."""
|
||||
admin.put("/api/settings/budget_start_day", params={"value": "1"})
|
||||
sparen = _kategorie(admin, "Sparen & Investments")
|
||||
admin.put(f"/api/budget/template/category/{sparen}", params={"planned_cents": 10000})
|
||||
admin.patch(f"/api/categories/{sparen}", json={"spending_is_good": True})
|
||||
try:
|
||||
_sparen_szenario(admin, betrag=90000) # weit ueber dem Plan
|
||||
v = admin.get("/api/budget/current").json()
|
||||
gruppe = next(g for g in v["groups"]
|
||||
if any(c["category_id"] == sparen for c in g["categories"]))
|
||||
zeile = next(c for c in gruppe["categories"] if c["category_id"] == sparen)
|
||||
|
||||
assert zeile["over"] is True, "die Tatsache bleibt stehen"
|
||||
assert zeile["good"] is True
|
||||
assert gruppe["actual_cents"] >= 90000, "die Summe zeigt weiter alles"
|
||||
assert gruppe["over"] is False, "Gruppe rot wegen des Sparens"
|
||||
finally:
|
||||
admin.patch(f"/api/categories/{sparen}", json={"spending_is_good": False})
|
||||
admin.put(f"/api/budget/template/category/{sparen}", params={"planned_cents": 0})
|
||||
|
||||
Reference in New Issue
Block a user