first ruggedy draft

This commit is contained in:
2026-06-28 13:48:15 +02:00
parent c916f64fcb
commit 1053f6a2a3
78 changed files with 20905 additions and 2 deletions

124
tests/test_settlement.py Normal file
View File

@@ -0,0 +1,124 @@
from __future__ import annotations
from datetime import date
from decimal import Decimal
from mousehold_api import models
from mousehold_api.services.settlement import calculate_settlement
from mousehold_domain import FinancialEventStatus, FinancialEventType
from sqlalchemy.orm import Session
def test_equal_split_settlement(
session: Session,
household_setup: dict[str, str],
) -> None:
event = models.FinancialEvent(
household_id=household_setup["household_id"],
payment_account_id=household_setup["account_a_id"],
payer_user_id=household_setup["user_a_id"],
event_type=FinancialEventType.EXPENSE,
status=FinancialEventStatus.CONFIRMED,
event_date=date(2026, 1, 1),
amount=Decimal("120.00"),
currency="EUR",
merchant="Groceries",
)
session.add(event)
session.flush()
session.add_all(
[
models.SplitLine(
event_id=event.id,
user_id=household_setup["user_a_id"],
share_amount=Decimal("60.00"),
),
models.SplitLine(
event_id=event.id,
user_id=household_setup["user_b_id"],
share_amount=Decimal("60.00"),
),
]
)
session.commit()
summary = calculate_settlement(session, household_id=household_setup["household_id"])
assert len(summary.suggested_transfers) == 1
transfer = summary.suggested_transfers[0]
assert transfer.from_user_id == household_setup["user_b_id"]
assert transfer.to_user_id == household_setup["user_a_id"]
assert transfer.amount == Decimal("60.00")
def test_shared_neutral_account_is_excluded(
session: Session,
household_setup: dict[str, str],
) -> None:
event = models.FinancialEvent(
household_id=household_setup["household_id"],
payment_account_id=household_setup["shared_account_id"],
payer_user_id=household_setup["user_a_id"],
event_type=FinancialEventType.EXPENSE,
status=FinancialEventStatus.CONFIRMED,
event_date=date(2026, 1, 1),
amount=Decimal("100.00"),
currency="EUR",
)
session.add(event)
session.flush()
session.add_all(
[
models.SplitLine(
event_id=event.id,
user_id=household_setup["user_a_id"],
share_amount=Decimal("50.00"),
),
models.SplitLine(
event_id=event.id,
user_id=household_setup["user_b_id"],
share_amount=Decimal("50.00"),
),
]
)
session.commit()
summary = calculate_settlement(session, household_id=household_setup["household_id"])
assert summary.included_event_ids == []
assert summary.excluded_event_ids == [event.id]
assert summary.suggested_transfers == []
def test_announced_and_outstanding_are_excluded_by_default(
session: Session,
household_setup: dict[str, str],
) -> None:
event = models.FinancialEvent(
household_id=household_setup["household_id"],
payment_account_id=household_setup["account_a_id"],
payer_user_id=household_setup["user_a_id"],
event_type=FinancialEventType.EXPENSE,
status=FinancialEventStatus.OUTSTANDING,
event_date=date(2026, 1, 1),
amount=Decimal("80.00"),
currency="EUR",
)
session.add(event)
session.flush()
session.add(
models.SplitLine(
event_id=event.id, user_id=household_setup["user_b_id"], share_amount=Decimal("80.00")
)
)
session.commit()
default_summary = calculate_settlement(session, household_id=household_setup["household_id"])
forecast_summary = calculate_settlement(
session,
household_id=household_setup["household_id"],
include_announced=True,
)
assert default_summary.suggested_transfers == []
assert forecast_summary.suggested_transfers[0].amount == Decimal("80.00")