from datetime import date from typing import List, Optional from pydantic import BaseModel, Field, field_validator # Invoice Item schemas class InvoiceItemBase(BaseModel): description: str quantity: float = Field(..., gt=0) unit_price: float = Field(..., ge=0) class InvoiceItemCreate(InvoiceItemBase): pass class InvoiceItemUpdate(InvoiceItemBase): description: Optional[str] = None quantity: Optional[float] = None unit_price: Optional[float] = None class InvoiceItemInDBBase(InvoiceItemBase): id: int invoice_id: int model_config = { "from_attributes": True } class InvoiceItem(InvoiceItemInDBBase): pass # Invoice schemas class InvoiceBase(BaseModel): client_id: int invoice_number: str status: str = "draft" issued_date: Optional[date] = None due_date: Optional[date] = None notes: Optional[str] = None @field_validator("status") def status_validator(cls, v): allowed_statuses = ["draft", "sent", "paid"] if v not in allowed_statuses: raise ValueError(f"Status must be one of: {', '.join(allowed_statuses)}") return v class InvoiceCreate(InvoiceBase): items: List[InvoiceItemCreate] class InvoiceUpdate(InvoiceBase): client_id: Optional[int] = None invoice_number: Optional[str] = None status: Optional[str] = None items: Optional[List[InvoiceItemCreate]] = None class InvoiceInDBBase(InvoiceBase): id: int user_id: int total_amount: float pdf_path: Optional[str] = None model_config = { "from_attributes": True } class Invoice(InvoiceInDBBase): pass class InvoiceInDB(InvoiceInDBBase): pass class InvoiceWithItems(Invoice): items: List[InvoiceItem] = []