feat: Engine+Schema fuer Szenario-Ende und szenario-eigene Einmalzahlungen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,3 +22,15 @@ def test_account_transaction_roundtrip(db):
|
||||
db.add(tx)
|
||||
db.commit()
|
||||
assert db.query(Transaction).one().amount == Decimal("-50.00")
|
||||
|
||||
|
||||
def test_scenario_planned_item_roundtrip(db):
|
||||
from app.models.tables import Scenario, ScenarioPlannedItem
|
||||
sc = Scenario(name="SPI-Test", description="")
|
||||
db.add(sc)
|
||||
db.flush()
|
||||
db.add(ScenarioPlannedItem(scenario_id=sc.id, name="Einmalzahlung",
|
||||
amount=Decimal("5000.00"), due=date(2026, 7, 30)))
|
||||
db.commit()
|
||||
item = db.query(ScenarioPlannedItem).one()
|
||||
assert item.amount == Decimal("5000.00") and item.scenario_id == sc.id
|
||||
|
||||
@@ -57,3 +57,51 @@ def test_absolute_modifier_clamps_to_zero():
|
||||
kind="absolute", value=Decimal("300"))]
|
||||
flows = build_cashflows(rec, [], [], [], mods, date(2026, 8, 1), date(2026, 8, 31))
|
||||
assert flows == [(date(2026, 8, 10), Decimal("0.00"))]
|
||||
|
||||
|
||||
def test_ende_modifier_beendet_posten_im_szenario():
|
||||
r = PlainRecurring(1, "Miete", Decimal("-2000.00"), "monthly", 1, None, None, None)
|
||||
m = PlainModifier("recurring", 1, "ende", Decimal("0"), date(2026, 8, 31))
|
||||
flows = build_cashflows([r], [], [], [], [m], date(2026, 7, 1), date(2026, 12, 31))
|
||||
assert [d for d, _ in flows] == [date(2026, 7, 1), date(2026, 8, 1)]
|
||||
assert all(a == Decimal("-2000.00") for _, a in flows)
|
||||
|
||||
|
||||
def test_ende_modifier_minimum_mit_eigenem_ende():
|
||||
# Posten endet selbst am 15.10.; Szenario-Ende 31.08. ist frueher -> gewinnt.
|
||||
r = PlainRecurring(1, "Miete", Decimal("-100.00"), "monthly", 1,
|
||||
None, date(2026, 10, 15), None)
|
||||
m = PlainModifier("recurring", 1, "ende", Decimal("0"), date(2026, 8, 31))
|
||||
flows = build_cashflows([r], [], [], [], [m], date(2026, 7, 1), date(2026, 12, 31))
|
||||
assert [d for d, _ in flows] == [date(2026, 7, 1), date(2026, 8, 1)]
|
||||
# Umgekehrt: Szenario-Ende NACH eigenem Ende aendert nichts.
|
||||
m_spaet = PlainModifier("recurring", 1, "ende", Decimal("0"), date(2026, 12, 31))
|
||||
flows2 = build_cashflows([r], [], [], [], [m_spaet], date(2026, 7, 1), date(2026, 12, 31))
|
||||
assert [d for d, _ in flows2][-1] == date(2026, 10, 1)
|
||||
|
||||
|
||||
def test_ende_modifier_auf_kategorie_trifft_alle_posten_der_kategorie():
|
||||
r1 = PlainRecurring(1, "Miete A", Decimal("-10.00"), "monthly", 1, None, None, 7)
|
||||
r2 = PlainRecurring(2, "Miete B", Decimal("-20.00"), "monthly", 1, None, None, 7)
|
||||
r3 = PlainRecurring(3, "Strom", Decimal("-5.00"), "monthly", 1, None, None, 9)
|
||||
m = PlainModifier("category", 7, "ende", Decimal("0"), date(2026, 7, 31))
|
||||
flows = build_cashflows([r1, r2, r3], [], [], [], [m],
|
||||
date(2026, 7, 1), date(2026, 9, 30))
|
||||
betraege = sorted(a for _, a in flows)
|
||||
# Miete A/B nur je 1x (Juli), Strom 3x (Juli-Sept).
|
||||
assert betraege == [Decimal("-20.00"), Decimal("-10.00"),
|
||||
Decimal("-5.00"), Decimal("-5.00"), Decimal("-5.00")]
|
||||
|
||||
|
||||
def test_ende_modifier_ohne_datum_wirkt_nicht():
|
||||
r = PlainRecurring(1, "Miete", Decimal("-10.00"), "monthly", 1, None, None, None)
|
||||
m = PlainModifier("recurring", 1, "ende", Decimal("0"), None)
|
||||
flows = build_cashflows([r], [], [], [], [m], date(2026, 7, 1), date(2026, 9, 30))
|
||||
assert len(flows) == 3
|
||||
|
||||
|
||||
def test_ende_modifier_aendert_betraege_nicht():
|
||||
r = PlainRecurring(1, "Miete", Decimal("-2000.00"), "monthly", 1, None, None, None)
|
||||
m = PlainModifier("recurring", 1, "ende", Decimal("50"), date(2026, 12, 31))
|
||||
flows = build_cashflows([r], [], [], [], [m], date(2026, 7, 1), date(2026, 8, 31))
|
||||
assert all(a == Decimal("-2000.00") for _, a in flows)
|
||||
|
||||
Reference in New Issue
Block a user