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")