from datetime import date from typing import List, Optional from pydantic import Field, condecimal from app.models.invoice import InvoiceStatus from app.schemas.base import BaseSchema, BaseSchemaIDTimestamps class InvoiceItemBase(BaseSchema): """Base schema for invoice item.""" description: str quantity: condecimal(ge=0, decimal_places=2) = Field(1, description="Quantity") unit_price: condecimal(ge=0, decimal_places=2) = Field(..., description="Unit price") tax_rate: condecimal(ge=0, decimal_places=2) = Field(0, description="Tax rate in percentage") product_id: Optional[int] = None class InvoiceItemCreate(InvoiceItemBase): """Schema for creating an invoice item.""" pass class InvoiceItemUpdate(BaseSchema): """Schema for updating an invoice item.""" description: Optional[str] = None quantity: Optional[condecimal(ge=0, decimal_places=2)] = None unit_price: Optional[condecimal(ge=0, decimal_places=2)] = None tax_rate: Optional[condecimal(ge=0, decimal_places=2)] = None product_id: Optional[int] = None class InvoiceItemInDBBase(InvoiceItemBase, BaseSchemaIDTimestamps): """Base schema for invoice item in database.""" invoice_id: int tax_amount: condecimal(ge=0, decimal_places=2) subtotal: condecimal(ge=0, decimal_places=2) total: condecimal(ge=0, decimal_places=2) class InvoiceItem(InvoiceItemInDBBase): """Schema for invoice item.""" pass class InvoiceBase(BaseSchema): """Base schema for invoice.""" invoice_number: str status: InvoiceStatus = InvoiceStatus.DRAFT issue_date: date = Field(default_factory=date.today) due_date: date notes: Optional[str] = None terms: Optional[str] = None customer_id: int class InvoiceCreate(InvoiceBase): """Schema for creating an invoice.""" items: List[InvoiceItemCreate] class InvoiceUpdate(BaseSchema): """Schema for updating an invoice.""" invoice_number: Optional[str] = None status: Optional[InvoiceStatus] = None issue_date: Optional[date] = None due_date: Optional[date] = None notes: Optional[str] = None terms: Optional[str] = None customer_id: Optional[int] = None class InvoiceInDBBase(InvoiceBase, BaseSchemaIDTimestamps): """Base schema for invoice in database.""" user_id: int subtotal: condecimal(ge=0, decimal_places=2) tax_amount: condecimal(ge=0, decimal_places=2) discount: condecimal(ge=0, decimal_places=2) = 0 total: condecimal(ge=0, decimal_places=2) class Invoice(InvoiceInDBBase): """Schema for invoice.""" items: List[InvoiceItem]