# models/schema/inventory.py from datetime import datetime from typing import List, Optional from pydantic import BaseModel, ConfigDict, Field class InventoryBase(BaseModel): product_id: int = Field(..., description="Product ID in vendor catalog") location: str = Field(..., description="Storage location") class InventoryCreate(InventoryBase): """Set exact inventory quantity (replaces existing).""" quantity: int = Field(..., description="Exact inventory quantity", ge=0) class InventoryAdjust(InventoryBase): """Add or remove inventory quantity.""" quantity: int = Field(..., description="Quantity to add (positive) or remove (negative)") class InventoryUpdate(BaseModel): """Update inventory fields.""" quantity: Optional[int] = Field(None, ge=0) reserved_quantity: Optional[int] = Field(None, ge=0) location: Optional[str] = None class InventoryReserve(BaseModel): """Reserve inventory for orders.""" product_id: int location: str quantity: int = Field(..., gt=0) class InventoryResponse(BaseModel): model_config = ConfigDict(from_attributes=True) id: int product_id: int vendor_id: int location: str quantity: int reserved_quantity: int gtin: Optional[str] created_at: datetime updated_at: datetime @property def available_quantity(self): return max(0, self.quantity - self.reserved_quantity) class InventoryLocationResponse(BaseModel): location: str quantity: int reserved_quantity: int available_quantity: int class ProductInventorySummary(BaseModel): """Inventory summary for a product.""" product_id: int vendor_id: int product_sku: Optional[str] product_title: str total_quantity: int total_reserved: int total_available: int locations: List[InventoryLocationResponse] class InventoryListResponse(BaseModel): inventories: List[InventoryResponse] total: int skip: int limit: int