# /opt/docker/dev/service_finder/backend/app/schemas/financial_manager.py """ Pydantic schemas for the FinancialManager API endpoints. THOUGHT PROCESS: - PurchaseRequest: Input schema for the package purchase endpoint. - PurchaseResponse: Output schema with full purchase receipt details. - CommissionInfo: Nested schema for commission distribution results. - Separated from commission.py to avoid circular imports and maintain clean boundaries. """ from pydantic import BaseModel, Field from typing import Optional, List, Any, Dict from datetime import datetime class CommissionItemInfo(BaseModel): """Single commission payout item in the response.""" level: int = Field(..., description="1 = Gen1 (direct referrer), 2 = Gen2 (upline)") user_id: int = Field(..., description="The user ID receiving the commission") commission_percent: float = Field(..., description="The applied commission percentage") commission_amount: float = Field(..., description="The calculated commission amount") class CommissionInfo(BaseModel): """Commission distribution summary in the purchase response.""" total_commission: float = Field(..., description="Sum of all commission payouts") items: List[CommissionItemInfo] = Field(default_factory=list, description="Individual commission items") class PurchaseRequest(BaseModel): """ Request schema for purchasing a subscription package. The FinancialManager orchestrates: 1. Payment processing (via configured gateway) 2. Subscription activation (User or Org level) 3. MLM commission distribution (async via BackgroundTask) """ tier_id: int = Field(..., gt=0, description="The SubscriptionTier ID to purchase") org_id: Optional[int] = Field(None, description="Organization ID for org-level subscription (None = user-level)") region_code: str = Field("GLOBAL", max_length=10, description="Region code for pricing (ISO 3166-1 alpha-2)") currency: str = Field("EUR", max_length=3, description="Currency code (ISO 4217)") duration_days: Optional[int] = Field(None, gt=0, description="Override duration in days (default: from tier.rules)") metadata: Optional[Dict[str, Any]] = Field(None, description="Optional metadata for the PaymentIntent") class PurchaseResponse(BaseModel): """ Response schema for a completed package purchase. Contains the full receipt: payment details, subscription info, and commission distribution results. """ success: bool = Field(..., description="Whether the purchase was successful") payment_intent_id: Optional[int] = Field(None, description="The PaymentIntent ID") transaction_id: Optional[str] = Field(None, description="The transaction UUID") subscription_id: Optional[int] = Field(None, description="The activated subscription ID") tier_name: Optional[str] = Field(None, description="The purchased tier name") valid_from: Optional[datetime] = Field(None, description="Subscription validity start") valid_until: Optional[datetime] = Field(None, description="Subscription validity end") amount_paid: float = Field(0.0, description="The amount paid") currency: str = Field("EUR", description="The payment currency") gateway: str = Field("mock", description="The payment gateway used") gateway_intent_id: Optional[str] = Field(None, description="The gateway's intent ID") is_org_subscription: bool = Field(False, description="Whether this is an org-level subscription") commission: Optional[CommissionInfo] = Field(None, description="Commission distribution results") error: Optional[str] = Field(None, description="Error message if success=False") model_config = {"from_attributes": True}