from datetime import datetime from pydantic import BaseModel, ConfigDict, Field class ProductCostItemBase(BaseModel): client_category: str = Field(min_length=1, max_length=255) item_id: str | None = Field(default=None, max_length=128) product_name: str = Field(min_length=1, max_length=255) mix_product_name: str = Field(min_length=1, max_length=255) unit_type: str = "Standard" own_bag: str | None = None unit_kg: float | None = Field(default=None, gt=0) items_per_pallet: int | None = Field(default=None, gt=0) bagging_process: str | None = Field(default=None, max_length=128) manual_distributor_margin: float | None = Field(default=None, ge=0, lt=1) manual_wholesale_margin: float | None = Field(default=None, ge=0, lt=1) class ProductCostItemCreate(ProductCostItemBase): pass class ProductCostItemUpdate(BaseModel): model_config = ConfigDict(extra="forbid") client_category: str | None = Field(default=None, min_length=1, max_length=255) item_id: str | None = Field(default=None, max_length=128) product_name: str | None = Field(default=None, min_length=1, max_length=255) mix_product_name: str | None = Field(default=None, min_length=1, max_length=255) unit_type: str | None = None own_bag: str | None = None unit_kg: float | None = Field(default=None, gt=0) items_per_pallet: int | None = Field(default=None, gt=0) bagging_process: str | None = Field(default=None, max_length=128) manual_distributor_margin: float | None = Field(default=None, ge=0, lt=1) manual_wholesale_margin: float | None = Field(default=None, ge=0, lt=1) class ProductCostItemRead(ProductCostItemBase): id: int tenant_id: str cleaned_product_cost_per_kg: float | None grading_cost_per_kg: float | None bagging_cost_per_kg: float | None cracking_cost_per_kg: float | None bag_cost_per_unit: float | None freight_cost_per_unit: float | None finished_product_delivered_cost: float | None distributor_price: float | None wholesale_price: float | None warnings: list[str] created_at: datetime updated_at: datetime class ProductCostBaseInputRead(BaseModel): grading_per_tonne: float grading_per_kg: float cracking_per_tonne: float cracking_per_kg: float class ProductCostBaseInputUpdate(ProductCostBaseInputRead): pass class ProductCostNamedInputRead(BaseModel): key: str label: str cost: float class ProductCostClientInputRead(BaseModel): client_category: str distributor_margin: float | None wholesale_margin: float | None class ProductCostInputsRead(BaseModel): base: ProductCostBaseInputRead processes: list[ProductCostNamedInputRead] clients: list[ProductCostClientInputRead] bags: list[ProductCostNamedInputRead] freight: list[ProductCostNamedInputRead] class ProductCostInputsUpdate(BaseModel): model_config = ConfigDict(extra="forbid") base: ProductCostBaseInputUpdate | None = None processes: list[ProductCostNamedInputRead] | None = None clients: list[ProductCostClientInputRead] | None = None bags: list[ProductCostNamedInputRead] | None = None freight: list[ProductCostNamedInputRead] | None = None class ProductCostRecalculateAllRead(BaseModel): recalculated: int