"""Kategorien, die nicht in Auswertungen zählen (z. B. „Kontoübertrag"). Eine Umbuchung zwischen eigenen Konten ist keine Ausgabe – das Geld liegt nur woanders. Der Kontostand muss sie trotzdem abbilden.""" import datetime def _account(admin, **kw): body = {"name": "Giro N", "type": "girokonto", "currency": "EUR", "opening_balance_cents": 100000} body.update(kw) return admin.post("/api/accounts", json=body).json() def _expense_cats(admin, n=2): out = [] for g in admin.get("/api/categories").json(): if g["kind"] == "expense": out += g["categories"] return out[:n] def test_neutral_category_out_of_stats_but_in_balance(admin): acc = _account(admin, name="Giro Neutral") normal, uebertrag = _expense_cats(admin, 2) # „Kontoübertrag" aus den Auswertungen nehmen. r = admin.patch(f"/api/categories/{uebertrag['id']}", json={"excluded_from_stats": True}) assert r.status_code == 200, r.text assert r.json()["excluded_from_stats"] is True heute = datetime.date.today().isoformat() for cat, cents in ((normal, 5000), (uebertrag, 30000)): admin.post("/api/transactions", json={ "type": "expense", "date": heute, "account_id": acc["id"], "amount_cents": cents, "category_id": cat["id"], }) # Saldo bildet BEIDE Buchungen ab: 1000.00 - 50.00 - 300.00 = 650.00 assert admin.get(f"/api/accounts/{acc['id']}").json()["balance_cents"] == 65000 # Auswertungen kennen nur die echte Ausgabe. ie = admin.get("/api/dashboard/income-expense").json() assert ie["expense"] == 5000, ie anteile = admin.get("/api/dashboard/expense-share?group_by=category").json() namen = [r["name"] for r in anteile["rows"]] assert normal["name"] in namen assert uebertrag["name"] not in namen assert anteile["total"] == 5000 # Häkchen wieder entfernen -> zählt sofort wieder mit. admin.patch(f"/api/categories/{uebertrag['id']}", json={"excluded_from_stats": False}) assert admin.get("/api/dashboard/income-expense").json()["expense"] == 35000