Files
bakery-ia/services/recipes/app/schemas/production.py

257 lines
9.7 KiB
Python
Raw Normal View History

# services/recipes/app/schemas/production.py
"""
Pydantic schemas for production-related API requests and responses
"""
from pydantic import BaseModel, Field
from typing import List, Optional, Dict, Any
from uuid import UUID
from datetime import datetime, date
from enum import Enum
from ..models.recipes import ProductionStatus, ProductionPriority, MeasurementUnit
class ProductionIngredientConsumptionCreate(BaseModel):
"""Schema for creating production ingredient consumption"""
recipe_ingredient_id: UUID
ingredient_id: UUID
stock_id: Optional[UUID] = None
planned_quantity: float = Field(..., gt=0)
actual_quantity: float = Field(..., gt=0)
unit: MeasurementUnit
consumption_notes: Optional[str] = None
staff_member: Optional[UUID] = None
ingredient_condition: Optional[str] = None
quality_impact: Optional[str] = None
substitution_used: bool = False
substitution_details: Optional[str] = None
class ProductionIngredientConsumptionResponse(BaseModel):
"""Schema for production ingredient consumption responses"""
id: UUID
tenant_id: UUID
production_batch_id: UUID
recipe_ingredient_id: UUID
ingredient_id: UUID
stock_id: Optional[UUID] = None
planned_quantity: float
actual_quantity: float
unit: str
variance_quantity: Optional[float] = None
variance_percentage: Optional[float] = None
unit_cost: Optional[float] = None
total_cost: Optional[float] = None
consumption_time: datetime
consumption_notes: Optional[str] = None
staff_member: Optional[UUID] = None
ingredient_condition: Optional[str] = None
quality_impact: Optional[str] = None
substitution_used: bool
substitution_details: Optional[str] = None
class Config:
from_attributes = True
class ProductionBatchCreate(BaseModel):
"""Schema for creating production batches"""
recipe_id: UUID
batch_number: str = Field(..., min_length=1, max_length=100)
production_date: date
planned_start_time: Optional[datetime] = None
planned_end_time: Optional[datetime] = None
planned_quantity: float = Field(..., gt=0)
batch_size_multiplier: float = Field(default=1.0, gt=0)
priority: ProductionPriority = ProductionPriority.NORMAL
assigned_staff: Optional[List[UUID]] = None
production_notes: Optional[str] = None
customer_order_reference: Optional[str] = None
pre_order_quantity: Optional[float] = Field(None, ge=0)
shelf_quantity: Optional[float] = Field(None, ge=0)
class ProductionBatchUpdate(BaseModel):
"""Schema for updating production batches"""
batch_number: Optional[str] = Field(None, min_length=1, max_length=100)
production_date: Optional[date] = None
planned_start_time: Optional[datetime] = None
actual_start_time: Optional[datetime] = None
planned_end_time: Optional[datetime] = None
actual_end_time: Optional[datetime] = None
planned_quantity: Optional[float] = Field(None, gt=0)
actual_quantity: Optional[float] = Field(None, ge=0)
batch_size_multiplier: Optional[float] = Field(None, gt=0)
status: Optional[ProductionStatus] = None
priority: Optional[ProductionPriority] = None
assigned_staff: Optional[List[UUID]] = None
production_notes: Optional[str] = None
quality_score: Optional[float] = Field(None, ge=1, le=10)
quality_notes: Optional[str] = None
defect_rate: Optional[float] = Field(None, ge=0, le=100)
rework_required: Optional[bool] = None
labor_cost: Optional[float] = Field(None, ge=0)
overhead_cost: Optional[float] = Field(None, ge=0)
production_temperature: Optional[float] = None
production_humidity: Optional[float] = Field(None, ge=0, le=100)
oven_temperature: Optional[float] = None
baking_time_minutes: Optional[int] = Field(None, ge=0)
waste_quantity: Optional[float] = Field(None, ge=0)
waste_reason: Optional[str] = None
customer_order_reference: Optional[str] = None
pre_order_quantity: Optional[float] = Field(None, ge=0)
shelf_quantity: Optional[float] = Field(None, ge=0)
class ProductionBatchResponse(BaseModel):
"""Schema for production batch responses"""
id: UUID
tenant_id: UUID
recipe_id: UUID
batch_number: str
production_date: date
planned_start_time: Optional[datetime] = None
actual_start_time: Optional[datetime] = None
planned_end_time: Optional[datetime] = None
actual_end_time: Optional[datetime] = None
planned_quantity: float
actual_quantity: Optional[float] = None
yield_percentage: Optional[float] = None
batch_size_multiplier: float
status: str
priority: str
assigned_staff: Optional[List[UUID]] = None
production_notes: Optional[str] = None
quality_score: Optional[float] = None
quality_notes: Optional[str] = None
defect_rate: Optional[float] = None
rework_required: bool
planned_material_cost: Optional[float] = None
actual_material_cost: Optional[float] = None
labor_cost: Optional[float] = None
overhead_cost: Optional[float] = None
total_production_cost: Optional[float] = None
cost_per_unit: Optional[float] = None
production_temperature: Optional[float] = None
production_humidity: Optional[float] = None
oven_temperature: Optional[float] = None
baking_time_minutes: Optional[int] = None
waste_quantity: float
waste_reason: Optional[str] = None
efficiency_percentage: Optional[float] = None
customer_order_reference: Optional[str] = None
pre_order_quantity: Optional[float] = None
shelf_quantity: Optional[float] = None
created_at: datetime
updated_at: datetime
created_by: Optional[UUID] = None
completed_by: Optional[UUID] = None
ingredient_consumptions: Optional[List[ProductionIngredientConsumptionResponse]] = None
class Config:
from_attributes = True
class ProductionBatchSearchRequest(BaseModel):
"""Schema for production batch search requests"""
search_term: Optional[str] = None
status: Optional[ProductionStatus] = None
priority: Optional[ProductionPriority] = None
start_date: Optional[date] = None
end_date: Optional[date] = None
recipe_id: Optional[UUID] = None
limit: int = Field(default=100, ge=1, le=1000)
offset: int = Field(default=0, ge=0)
class ProductionScheduleCreate(BaseModel):
"""Schema for creating production schedules"""
schedule_date: date
schedule_name: Optional[str] = Field(None, max_length=255)
estimated_production_hours: Optional[float] = Field(None, gt=0)
estimated_material_cost: Optional[float] = Field(None, ge=0)
available_staff_hours: Optional[float] = Field(None, gt=0)
oven_capacity_hours: Optional[float] = Field(None, gt=0)
production_capacity_limit: Optional[float] = Field(None, gt=0)
schedule_notes: Optional[str] = None
preparation_instructions: Optional[str] = None
special_requirements: Optional[Dict[str, Any]] = None
class ProductionScheduleUpdate(BaseModel):
"""Schema for updating production schedules"""
schedule_name: Optional[str] = Field(None, max_length=255)
total_planned_batches: Optional[int] = Field(None, ge=0)
total_planned_items: Optional[float] = Field(None, ge=0)
estimated_production_hours: Optional[float] = Field(None, gt=0)
estimated_material_cost: Optional[float] = Field(None, ge=0)
is_published: Optional[bool] = None
is_completed: Optional[bool] = None
completion_percentage: Optional[float] = Field(None, ge=0, le=100)
available_staff_hours: Optional[float] = Field(None, gt=0)
oven_capacity_hours: Optional[float] = Field(None, gt=0)
production_capacity_limit: Optional[float] = Field(None, gt=0)
schedule_notes: Optional[str] = None
preparation_instructions: Optional[str] = None
special_requirements: Optional[Dict[str, Any]] = None
class ProductionScheduleResponse(BaseModel):
"""Schema for production schedule responses"""
id: UUID
tenant_id: UUID
schedule_date: date
schedule_name: Optional[str] = None
total_planned_batches: int
total_planned_items: float
estimated_production_hours: Optional[float] = None
estimated_material_cost: Optional[float] = None
is_published: bool
is_completed: bool
completion_percentage: Optional[float] = None
available_staff_hours: Optional[float] = None
oven_capacity_hours: Optional[float] = None
production_capacity_limit: Optional[float] = None
schedule_notes: Optional[str] = None
preparation_instructions: Optional[str] = None
special_requirements: Optional[Dict[str, Any]] = None
created_at: datetime
updated_at: datetime
created_by: Optional[UUID] = None
published_by: Optional[UUID] = None
published_at: Optional[datetime] = None
class Config:
from_attributes = True
class ProductionStatisticsResponse(BaseModel):
"""Schema for production statistics responses"""
total_batches: int
completed_batches: int
failed_batches: int
success_rate: float
average_yield_percentage: float
average_quality_score: float
total_production_cost: float
status_breakdown: List[Dict[str, Any]]
class StartProductionRequest(BaseModel):
"""Schema for starting production batch"""
staff_member: Optional[UUID] = None
production_notes: Optional[str] = None
ingredient_consumptions: List[ProductionIngredientConsumptionCreate]
class CompleteProductionRequest(BaseModel):
"""Schema for completing production batch"""
actual_quantity: float = Field(..., gt=0)
quality_score: Optional[float] = Field(None, ge=1, le=10)
quality_notes: Optional[str] = None
defect_rate: Optional[float] = Field(None, ge=0, le=100)
waste_quantity: Optional[float] = Field(None, ge=0)
waste_reason: Optional[str] = None
production_notes: Optional[str] = None
staff_member: Optional[UUID] = None