from __future__ import annotations from datetime import datetime from pydantic import BaseModel, Field class CreditSubscriptionPeriodOut(BaseModel): id: str sequence: int scheduled_at: datetime valid_from: datetime expires_at: datetime grant_credits: float allocated_paid_amount: float status: str status_label: str = "" issued_balance_id: str | None = None issued_at: datetime | None = None model_config = {"from_attributes": True} class CreditSubscriptionOut(BaseModel): id: str subscription_no: str user_id: str team_id: str | None = None team_manager_id_snapshot: str | None = None product_id: str | None = None payment_order_id: str status: str status_label: str = "" purchase_scene: str product_type_snapshot: str product_type_label: str = "" product_name_snapshot: str tier_code: str tier_rank: int billing_cycle: str billing_cycle_label: str = "" anchor_at: datetime start_at: datetime expires_at: datetime next_grant_at: datetime | None = None monthly_grant_credits_snapshot: float monthly_total_credits_snapshot: float quantity_snapshot: int = 1 grant_count: int granted_count: int first_purchase_price_snapshot: float regular_price_snapshot: float activity_price_snapshot: float | None = None actual_unit_price_snapshot: float paid_amount_snapshot: float periods: list[CreditSubscriptionPeriodOut] = Field(default_factory=list) model_config = {"from_attributes": True} class AdminOfflineSubscriptionCreate(BaseModel): product_id: str quantity: int = Field(default=1, ge=1, le=1000) payment_method: str = Field(pattern="^(bank_transfer|cash|other)$") actual_paid_amount: float | None = Field(default=None, ge=0) offline_trade_no: str | None = Field(default=None, max_length=128) offline_payment_detail: str | None = Field(default=None, max_length=128) remark: str | None = Field(default=None, max_length=512)