from datetime import date, datetime from pydantic import BaseModel, ConfigDict, Field class MixCalculatorProductOptionRead(BaseModel): product_id: int client_name: str product_name: str mix_id: int mix_name: str unit_of_measure: str unit_size_kg: float mix_total_kg: float class MixCalculatorOptionsRead(BaseModel): clients: list[str] products: list[MixCalculatorProductOptionRead] class MixCalculatorSessionLineRead(BaseModel): id: int | None = None raw_material_id: int | None raw_material_name: str required_kg: float mix_percentage: float unit: str sort_order: int class MixCalculatorSessionBase(BaseModel): mix_date: date client_name: str product_id: int batch_size_kg: float = Field(gt=0) prepared_by_name: str = Field(min_length=1, max_length=255) status: str = "saved" notes: str | None = None class MixCalculatorSessionCreate(MixCalculatorSessionBase): pass class MixCalculatorSessionUpdate(BaseModel): mix_date: date | None = None client_name: str | None = None product_id: int | None = None batch_size_kg: float | None = Field(default=None, gt=0) prepared_by_name: str | None = Field(default=None, min_length=1, max_length=255) status: str | None = None notes: str | None = None class MixCalculatorPreviewRead(BaseModel): client_name: str product_id: int product_name: str mix_id: int mix_name: str mix_date: date batch_size_kg: float total_bags: float total_kg: float product_unit_of_measure: str product_unit_size_kg: float prepared_by_name: str status: str notes: str | None warnings: list[str] lines: list[MixCalculatorSessionLineRead] class MixCalculatorSessionSummaryRead(BaseModel): id: int tenant_id: str session_number: str client_name: str product_id: int product_name: str mix_id: int mix_name: str mix_date: date batch_size_kg: float total_bags: float total_kg: float product_unit_of_measure: str product_unit_size_kg: float prepared_by_user_id: int | None prepared_by_name: str created_by: str status: str notes: str | None created_at: datetime updated_at: datetime warnings: list[str] is_owner: bool model_config = ConfigDict(from_attributes=True) class MixCalculatorSessionRead(MixCalculatorSessionSummaryRead): lines: list[MixCalculatorSessionLineRead]