from pydantic import BaseModel, validator from datetime import datetime from typing import Optional from decimal import Decimal from app.models.donation import DonationType, PaymentMethod class DonationBase(BaseModel): amount: Decimal currency: str = "USD" donation_type: DonationType payment_method: PaymentMethod reference_number: Optional[str] = None notes: Optional[str] = None is_anonymous: bool = False is_recurring: bool = False recurring_frequency: Optional[str] = None donation_date: Optional[datetime] = None @validator("amount") def amount_must_be_positive(cls, v): if v <= 0: raise ValueError("Amount must be positive") return v class DonationCreate(DonationBase): pass class DonationResponse(DonationBase): id: int donor_id: int next_due_date: Optional[datetime] = None created_at: datetime donor_name: Optional[str] = None class Config: from_attributes = True class DonationGoalBase(BaseModel): title: str description: Optional[str] = None target_amount: Decimal currency: str = "USD" start_date: datetime end_date: datetime @validator("target_amount") def target_amount_must_be_positive(cls, v): if v <= 0: raise ValueError("Target amount must be positive") return v @validator("end_date") def end_date_must_be_after_start_date(cls, v, values): if "start_date" in values and v <= values["start_date"]: raise ValueError("End date must be after start date") return v class DonationGoalCreate(DonationGoalBase): pass class DonationGoalUpdate(BaseModel): title: Optional[str] = None description: Optional[str] = None target_amount: Optional[Decimal] = None end_date: Optional[datetime] = None is_active: Optional[bool] = None class DonationGoalResponse(DonationGoalBase): id: int current_amount: Decimal is_active: bool created_by: int created_at: datetime creator_name: Optional[str] = None progress_percentage: float = 0.0 days_remaining: int = 0 class Config: from_attributes = True class TithePledgeBase(BaseModel): monthly_amount: Decimal currency: str = "USD" start_date: datetime end_date: Optional[datetime] = None @validator("monthly_amount") def monthly_amount_must_be_positive(cls, v): if v <= 0: raise ValueError("Monthly amount must be positive") return v class TithePledgeCreate(TithePledgeBase): pass class TithePledgeUpdate(BaseModel): monthly_amount: Optional[Decimal] = None end_date: Optional[datetime] = None is_active: Optional[bool] = None class TithePledgeResponse(TithePledgeBase): id: int user_id: int is_active: bool created_at: datetime class Config: from_attributes = True class DonationStats(BaseModel): total_donations: Decimal total_tithes: Decimal total_offerings: Decimal donation_count: int average_donation: Decimal currency: str = "USD" class MonthlyDonationSummary(BaseModel): month: str year: int total_amount: Decimal donation_count: int tithe_amount: Decimal offering_amount: Decimal