from datetime import datetime from typing import List, Optional from pydantic import BaseModel, Field, validator class InvoiceItemBase(BaseModel): description: str quantity: float unit_price: float class InvoiceItemCreate(InvoiceItemBase): pass class InvoiceItemDB(InvoiceItemBase): id: int invoice_id: int amount: float class Config: from_attributes = True class InvoiceBase(BaseModel): customer_name: str customer_email: Optional[str] = None customer_address: Optional[str] = None due_date: datetime notes: Optional[str] = None class InvoiceCreate(InvoiceBase): items: List[InvoiceItemCreate] @validator("items") def validate_items(cls, v): if not v or len(v) == 0: raise ValueError("Invoice must have at least one item") return v class InvoiceUpdate(BaseModel): customer_name: Optional[str] = None customer_email: Optional[str] = None customer_address: Optional[str] = None due_date: Optional[datetime] = None status: Optional[str] = None notes: Optional[str] = None class InvoiceDB(InvoiceBase): id: int invoice_number: str date_created: datetime total_amount: float status: str items: List[InvoiceItemDB] class Config: from_attributes = True class InvoiceSearchQuery(BaseModel): invoice_number: str class InvoiceStatusUpdate(BaseModel): status: str = Field(..., description="New status for the invoice") @validator("status") def validate_status(cls, v): allowed_statuses = ["PENDING", "PAID", "CANCELLED"] if v not in allowed_statuses: raise ValueError(f"Status must be one of {', '.join(allowed_statuses)}") return v