from datetime import datetime from typing import List, Optional from sqlmodel import Field, SQLModel, Relationship # --- User & Auth --- class User(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) username: str = Field(index=True, unique=True) hashed_password: str is_active: bool = Field(default=True) is_admin: bool = Field(default=False) # --- Inventory & Materials --- class Material(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str = Field(index=True) description: Optional[str] = None unit: str # e.g., "meters", "units", "grams" stock_quantity: float = Field(default=0.0) reorder_level: float = Field(default=0.0) cost_per_unit: float = Field(default=0.0) # --- Products --- class Product(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str = Field(index=True) sku: str = Field(index=True, unique=True) description: Optional[str] = None base_price: float = Field(default=0.0) estimated_time_hours: float = Field(default=0.0) # Relationships orders: List["OrderProductLink"] = Relationship(back_populates="product") materials: List["ProductMaterialLink"] = Relationship(back_populates="product") class ProductMaterialLink(SQLModel, table=True): product_id: Optional[int] = Field(default=None, foreign_key="product.id", primary_key=True) material_id: Optional[int] = Field(default=None, foreign_key="material.id", primary_key=True) quantity_required: float product: Product = Relationship(back_populates="materials") material: Material = Relationship() # --- CRM --- class Client(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) full_name: str = Field(index=True) email: Optional[str] = None phone: Optional[str] = None address: Optional[str] = None # Measurements (as a JSON or separate fields, keeping it simple for now) measurements: Optional[str] = None # Or use a JSON type if supported better orders: List["Order"] = Relationship(back_populates="client") # --- Orders & Production --- class OrderStatus(str): QUOTATION = "Quotation" PENDING = "Pending" IN_PRODUCTION = "In Production" SHIPPED = "Shipped" DELIVERED = "Delivered" CANCELLED = "Cancelled" class Order(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) client_id: int = Field(foreign_key="client.id") order_date: datetime = Field(default_factory=datetime.utcnow) status: str = Field(default=OrderStatus.QUOTATION) total_amount: float = Field(default=0.0) notes: Optional[str] = None client: Client = Relationship(back_populates="orders") products: List["OrderProductLink"] = Relationship(back_populates="order") class OrderProductLink(SQLModel, table=True): order_id: Optional[int] = Field(default=None, foreign_key="order.id", primary_key=True) product_id: Optional[int] = Field(default=None, foreign_key="product.id", primary_key=True) quantity: int = Field(default=1) customizations: Optional[str] = None order: Order = Relationship(back_populates="products") product: Product = Relationship(back_populates="orders") class ProductionStep(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) order_id: int = Field(foreign_key="order.id") step_name: str # e.g., "Corte", "Confección", "Terminado" status: str = Field(default="Pending") # Pending, In Progress, Completed assigned_to: Optional[int] = Field(default=None, foreign_key="user.id") started_at: Optional[datetime] = None completed_at: Optional[datetime] = None