"""Settlement validators — Phase 10.8.""" from __future__ import annotations from decimal import Decimal from shared.exceptions import AppError from app.models.types import SettlementIntentStatus ALLOWED_TRANSITIONS: dict[str, set[SettlementIntentStatus]] = { "submit": {SettlementIntentStatus.DRAFT}, "settle": {SettlementIntentStatus.SUBMITTED}, "fail": {SettlementIntentStatus.SUBMITTED}, "cancel": {SettlementIntentStatus.DRAFT, SettlementIntentStatus.PENDING}, } TARGET_STATUS: dict[str, SettlementIntentStatus] = { "submit": SettlementIntentStatus.SUBMITTED, "settle": SettlementIntentStatus.SETTLED, "fail": SettlementIntentStatus.FAILED, "cancel": SettlementIntentStatus.CANCELLED, } TERMINAL = frozenset( { SettlementIntentStatus.SETTLED, SettlementIntentStatus.FAILED, SettlementIntentStatus.CANCELLED, } ) def ensure_settlement_transition(*, action: str, current: SettlementIntentStatus) -> None: if current in TERMINAL: raise AppError( "تسویه در وضعیت پایانی است", status_code=409, error_code="settlement_terminal", details={"status": current.value, "action": action}, ) allowed = ALLOWED_TRANSITIONS.get(action, set()) if current not in allowed: raise AppError( "انتقال وضعیت تسویه مجاز نیست", status_code=409, error_code="invalid_settlement_transition", details={ "from_status": current.value, "action": action, "allowed_from": sorted(s.value for s in allowed), }, ) def target_settlement_status(action: str) -> SettlementIntentStatus: return TARGET_STATUS[action] def validate_settlement_amount(amount: Decimal) -> Decimal: if amount <= 0: raise AppError( "مبلغ تسویه باید بزرگ‌تر از صفر باشد", status_code=422, error_code="invalid_settlement_amount", ) return amount