# models/schema/order.py """ Pydantic schema for order operations. """ from datetime import datetime from typing import List, Optional from decimal import Decimal from pydantic import BaseModel, Field, ConfigDict # ============================================================================ # Order Item Schemas # ============================================================================ class OrderItemCreate(BaseModel): """Schema for creating an order item.""" product_id: int quantity: int = Field(..., ge=1) class OrderItemResponse(BaseModel): """Schema for order item response.""" model_config = ConfigDict(from_attributes=True) id: int order_id: int product_id: int product_name: str product_sku: Optional[str] quantity: int unit_price: float total_price: float inventory_reserved: bool inventory_fulfilled: bool created_at: datetime updated_at: datetime # ============================================================================ # Order Address Schemas # ============================================================================ class OrderAddressCreate(BaseModel): """Schema for order address (shipping/billing).""" first_name: str = Field(..., min_length=1, max_length=100) last_name: str = Field(..., min_length=1, max_length=100) company: Optional[str] = Field(None, max_length=200) address_line_1: str = Field(..., min_length=1, max_length=255) address_line_2: Optional[str] = Field(None, max_length=255) city: str = Field(..., min_length=1, max_length=100) postal_code: str = Field(..., min_length=1, max_length=20) country: str = Field(..., min_length=2, max_length=100) class OrderAddressResponse(BaseModel): """Schema for order address response.""" model_config = ConfigDict(from_attributes=True) id: int address_type: str first_name: str last_name: str company: Optional[str] address_line_1: str address_line_2: Optional[str] city: str postal_code: str country: str # ============================================================================ # Order Create/Update Schemas # ============================================================================ class OrderCreate(BaseModel): """Schema for creating an order.""" customer_id: Optional[int] = None # Optional for guest checkout items: List[OrderItemCreate] = Field(..., min_length=1) # Addresses shipping_address: OrderAddressCreate billing_address: Optional[OrderAddressCreate] = None # Use shipping if not provided # Optional fields shipping_method: Optional[str] = None customer_notes: Optional[str] = Field(None, max_length=1000) # Cart/session info session_id: Optional[str] = None class OrderUpdate(BaseModel): """Schema for updating order status.""" status: Optional[str] = Field( None, pattern="^(pending|processing|shipped|delivered|cancelled|refunded)$" ) tracking_number: Optional[str] = None internal_notes: Optional[str] = None # ============================================================================ # Order Response Schemas # ============================================================================ class OrderResponse(BaseModel): """Schema for order response.""" model_config = ConfigDict(from_attributes=True) id: int vendor_id: int customer_id: int order_number: str status: str # Financial subtotal: float tax_amount: float shipping_amount: float discount_amount: float total_amount: float currency: str # Shipping shipping_method: Optional[str] tracking_number: Optional[str] # Notes customer_notes: Optional[str] internal_notes: Optional[str] # Timestamps created_at: datetime updated_at: datetime paid_at: Optional[datetime] shipped_at: Optional[datetime] delivered_at: Optional[datetime] cancelled_at: Optional[datetime] class OrderDetailResponse(OrderResponse): """Schema for detailed order response with items and addresses.""" items: List[OrderItemResponse] shipping_address: OrderAddressResponse billing_address: OrderAddressResponse class OrderListResponse(BaseModel): """Schema for paginated order list.""" orders: List[OrderResponse] total: int skip: int limit: int