Add more services
This commit is contained in:
367
services/orders/app/schemas/order_schemas.py
Normal file
367
services/orders/app/schemas/order_schemas.py
Normal file
@@ -0,0 +1,367 @@
|
||||
# ================================================================
|
||||
# services/orders/app/schemas/order_schemas.py
|
||||
# ================================================================
|
||||
"""
|
||||
Order-related Pydantic schemas for Orders Service
|
||||
"""
|
||||
|
||||
from datetime import datetime, date
|
||||
from decimal import Decimal
|
||||
from typing import Optional, List, Dict, Any
|
||||
from uuid import UUID
|
||||
from pydantic import BaseModel, Field, validator
|
||||
|
||||
|
||||
# ===== Customer Schemas =====
|
||||
|
||||
class CustomerBase(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=200)
|
||||
business_name: Optional[str] = Field(None, max_length=200)
|
||||
customer_type: str = Field(default="individual", pattern="^(individual|business|central_bakery)$")
|
||||
email: Optional[str] = Field(None, max_length=255)
|
||||
phone: Optional[str] = Field(None, max_length=50)
|
||||
address_line1: Optional[str] = Field(None, max_length=255)
|
||||
address_line2: Optional[str] = Field(None, max_length=255)
|
||||
city: Optional[str] = Field(None, max_length=100)
|
||||
state: Optional[str] = Field(None, max_length=100)
|
||||
postal_code: Optional[str] = Field(None, max_length=20)
|
||||
country: str = Field(default="US", max_length=100)
|
||||
is_active: bool = Field(default=True)
|
||||
preferred_delivery_method: str = Field(default="delivery", pattern="^(delivery|pickup)$")
|
||||
payment_terms: str = Field(default="immediate", pattern="^(immediate|net_30|net_60)$")
|
||||
credit_limit: Optional[Decimal] = Field(None, ge=0)
|
||||
discount_percentage: Decimal = Field(default=Decimal("0.00"), ge=0, le=100)
|
||||
customer_segment: str = Field(default="regular", pattern="^(vip|regular|wholesale)$")
|
||||
priority_level: str = Field(default="normal", pattern="^(high|normal|low)$")
|
||||
special_instructions: Optional[str] = None
|
||||
delivery_preferences: Optional[Dict[str, Any]] = None
|
||||
product_preferences: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class CustomerCreate(CustomerBase):
|
||||
customer_code: str = Field(..., min_length=1, max_length=50)
|
||||
tenant_id: UUID
|
||||
|
||||
|
||||
class CustomerUpdate(BaseModel):
|
||||
name: Optional[str] = Field(None, min_length=1, max_length=200)
|
||||
business_name: Optional[str] = Field(None, max_length=200)
|
||||
customer_type: Optional[str] = Field(None, pattern="^(individual|business|central_bakery)$")
|
||||
email: Optional[str] = Field(None, max_length=255)
|
||||
phone: Optional[str] = Field(None, max_length=50)
|
||||
address_line1: Optional[str] = Field(None, max_length=255)
|
||||
address_line2: Optional[str] = Field(None, max_length=255)
|
||||
city: Optional[str] = Field(None, max_length=100)
|
||||
state: Optional[str] = Field(None, max_length=100)
|
||||
postal_code: Optional[str] = Field(None, max_length=20)
|
||||
country: Optional[str] = Field(None, max_length=100)
|
||||
is_active: Optional[bool] = None
|
||||
preferred_delivery_method: Optional[str] = Field(None, pattern="^(delivery|pickup)$")
|
||||
payment_terms: Optional[str] = Field(None, pattern="^(immediate|net_30|net_60)$")
|
||||
credit_limit: Optional[Decimal] = Field(None, ge=0)
|
||||
discount_percentage: Optional[Decimal] = Field(None, ge=0, le=100)
|
||||
customer_segment: Optional[str] = Field(None, pattern="^(vip|regular|wholesale)$")
|
||||
priority_level: Optional[str] = Field(None, pattern="^(high|normal|low)$")
|
||||
special_instructions: Optional[str] = None
|
||||
delivery_preferences: Optional[Dict[str, Any]] = None
|
||||
product_preferences: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class CustomerResponse(CustomerBase):
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
customer_code: str
|
||||
total_orders: int
|
||||
total_spent: Decimal
|
||||
average_order_value: Decimal
|
||||
last_order_date: Optional[datetime]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Order Item Schemas =====
|
||||
|
||||
class OrderItemBase(BaseModel):
|
||||
product_id: UUID
|
||||
product_name: str = Field(..., min_length=1, max_length=200)
|
||||
product_sku: Optional[str] = Field(None, max_length=100)
|
||||
product_category: Optional[str] = Field(None, max_length=100)
|
||||
quantity: Decimal = Field(..., gt=0)
|
||||
unit_of_measure: str = Field(default="each", max_length=50)
|
||||
weight: Optional[Decimal] = Field(None, ge=0)
|
||||
unit_price: Decimal = Field(..., ge=0)
|
||||
line_discount: Decimal = Field(default=Decimal("0.00"), ge=0)
|
||||
product_specifications: Optional[Dict[str, Any]] = None
|
||||
customization_details: Optional[str] = None
|
||||
special_instructions: Optional[str] = None
|
||||
recipe_id: Optional[UUID] = None
|
||||
|
||||
|
||||
class OrderItemCreate(OrderItemBase):
|
||||
pass
|
||||
|
||||
|
||||
class OrderItemUpdate(BaseModel):
|
||||
quantity: Optional[Decimal] = Field(None, gt=0)
|
||||
unit_price: Optional[Decimal] = Field(None, ge=0)
|
||||
line_discount: Optional[Decimal] = Field(None, ge=0)
|
||||
product_specifications: Optional[Dict[str, Any]] = None
|
||||
customization_details: Optional[str] = None
|
||||
special_instructions: Optional[str] = None
|
||||
|
||||
|
||||
class OrderItemResponse(OrderItemBase):
|
||||
id: UUID
|
||||
order_id: UUID
|
||||
line_total: Decimal
|
||||
status: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Order Schemas =====
|
||||
|
||||
class OrderBase(BaseModel):
|
||||
customer_id: UUID
|
||||
order_type: str = Field(default="standard", pattern="^(standard|rush|recurring|special)$")
|
||||
priority: str = Field(default="normal", pattern="^(high|normal|low)$")
|
||||
requested_delivery_date: datetime
|
||||
delivery_method: str = Field(default="delivery", pattern="^(delivery|pickup)$")
|
||||
delivery_address: Optional[Dict[str, Any]] = None
|
||||
delivery_instructions: Optional[str] = None
|
||||
delivery_window_start: Optional[datetime] = None
|
||||
delivery_window_end: Optional[datetime] = None
|
||||
discount_percentage: Decimal = Field(default=Decimal("0.00"), ge=0, le=100)
|
||||
delivery_fee: Decimal = Field(default=Decimal("0.00"), ge=0)
|
||||
payment_method: Optional[str] = Field(None, pattern="^(cash|card|bank_transfer|account)$")
|
||||
payment_terms: str = Field(default="immediate", pattern="^(immediate|net_30|net_60)$")
|
||||
special_instructions: Optional[str] = None
|
||||
custom_requirements: Optional[Dict[str, Any]] = None
|
||||
allergen_warnings: Optional[Dict[str, Any]] = None
|
||||
order_source: str = Field(default="manual", pattern="^(manual|online|phone|app|api)$")
|
||||
sales_channel: str = Field(default="direct", pattern="^(direct|wholesale|retail)$")
|
||||
order_origin: Optional[str] = Field(None, max_length=100)
|
||||
communication_preferences: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class OrderCreate(OrderBase):
|
||||
tenant_id: UUID
|
||||
items: List[OrderItemCreate] = Field(..., min_items=1)
|
||||
|
||||
|
||||
class OrderUpdate(BaseModel):
|
||||
status: Optional[str] = Field(None, pattern="^(pending|confirmed|in_production|ready|out_for_delivery|delivered|cancelled|failed)$")
|
||||
priority: Optional[str] = Field(None, pattern="^(high|normal|low)$")
|
||||
requested_delivery_date: Optional[datetime] = None
|
||||
confirmed_delivery_date: Optional[datetime] = None
|
||||
delivery_method: Optional[str] = Field(None, pattern="^(delivery|pickup)$")
|
||||
delivery_address: Optional[Dict[str, Any]] = None
|
||||
delivery_instructions: Optional[str] = None
|
||||
delivery_window_start: Optional[datetime] = None
|
||||
delivery_window_end: Optional[datetime] = None
|
||||
payment_method: Optional[str] = Field(None, pattern="^(cash|card|bank_transfer|account)$")
|
||||
payment_status: Optional[str] = Field(None, pattern="^(pending|partial|paid|failed|refunded)$")
|
||||
special_instructions: Optional[str] = None
|
||||
custom_requirements: Optional[Dict[str, Any]] = None
|
||||
allergen_warnings: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class OrderResponse(OrderBase):
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
order_number: str
|
||||
status: str
|
||||
order_date: datetime
|
||||
confirmed_delivery_date: Optional[datetime]
|
||||
actual_delivery_date: Optional[datetime]
|
||||
subtotal: Decimal
|
||||
discount_amount: Decimal
|
||||
tax_amount: Decimal
|
||||
total_amount: Decimal
|
||||
payment_status: str
|
||||
business_model: Optional[str]
|
||||
estimated_business_model: Optional[str]
|
||||
production_batch_id: Optional[UUID]
|
||||
quality_score: Optional[Decimal]
|
||||
customer_rating: Optional[int]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
items: List[OrderItemResponse] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Procurement Schemas =====
|
||||
|
||||
class ProcurementRequirementBase(BaseModel):
|
||||
product_id: UUID
|
||||
product_name: str = Field(..., min_length=1, max_length=200)
|
||||
product_sku: Optional[str] = Field(None, max_length=100)
|
||||
product_category: Optional[str] = Field(None, max_length=100)
|
||||
product_type: str = Field(default="ingredient", pattern="^(ingredient|packaging|supplies)$")
|
||||
required_quantity: Decimal = Field(..., gt=0)
|
||||
unit_of_measure: str = Field(..., min_length=1, max_length=50)
|
||||
safety_stock_quantity: Decimal = Field(default=Decimal("0.000"), ge=0)
|
||||
required_by_date: date
|
||||
priority: str = Field(default="normal", pattern="^(critical|high|normal|low)$")
|
||||
preferred_supplier_id: Optional[UUID] = None
|
||||
quality_specifications: Optional[Dict[str, Any]] = None
|
||||
special_requirements: Optional[str] = None
|
||||
storage_requirements: Optional[str] = Field(None, max_length=200)
|
||||
|
||||
|
||||
class ProcurementRequirementCreate(ProcurementRequirementBase):
|
||||
pass
|
||||
|
||||
|
||||
class ProcurementRequirementResponse(ProcurementRequirementBase):
|
||||
id: UUID
|
||||
plan_id: UUID
|
||||
requirement_number: str
|
||||
total_quantity_needed: Decimal
|
||||
current_stock_level: Decimal
|
||||
available_stock: Decimal
|
||||
net_requirement: Decimal
|
||||
order_demand: Decimal
|
||||
production_demand: Decimal
|
||||
forecast_demand: Decimal
|
||||
status: str
|
||||
estimated_unit_cost: Optional[Decimal]
|
||||
estimated_total_cost: Optional[Decimal]
|
||||
supplier_name: Optional[str]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ProcurementPlanBase(BaseModel):
|
||||
plan_date: date
|
||||
plan_period_start: date
|
||||
plan_period_end: date
|
||||
planning_horizon_days: int = Field(default=14, ge=1, le=365)
|
||||
plan_type: str = Field(default="regular", pattern="^(regular|emergency|seasonal)$")
|
||||
priority: str = Field(default="normal", pattern="^(high|normal|low)$")
|
||||
business_model: Optional[str] = Field(None, pattern="^(individual_bakery|central_bakery)$")
|
||||
procurement_strategy: str = Field(default="just_in_time", pattern="^(just_in_time|bulk|mixed)$")
|
||||
safety_stock_buffer: Decimal = Field(default=Decimal("20.00"), ge=0, le=100)
|
||||
special_requirements: Optional[str] = None
|
||||
|
||||
|
||||
class ProcurementPlanCreate(ProcurementPlanBase):
|
||||
tenant_id: UUID
|
||||
requirements: List[ProcurementRequirementCreate] = Field(..., min_items=1)
|
||||
|
||||
|
||||
class ProcurementPlanResponse(ProcurementPlanBase):
|
||||
id: UUID
|
||||
tenant_id: UUID
|
||||
plan_number: str
|
||||
status: str
|
||||
total_requirements: int
|
||||
total_estimated_cost: Decimal
|
||||
total_approved_cost: Decimal
|
||||
total_demand_orders: int
|
||||
supply_risk_level: str
|
||||
approved_at: Optional[datetime]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
requirements: List[ProcurementRequirementResponse] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Dashboard and Analytics Schemas =====
|
||||
|
||||
class OrdersDashboardSummary(BaseModel):
|
||||
"""Summary data for orders dashboard"""
|
||||
# Current period metrics
|
||||
total_orders_today: int
|
||||
total_orders_this_week: int
|
||||
total_orders_this_month: int
|
||||
|
||||
# Revenue metrics
|
||||
revenue_today: Decimal
|
||||
revenue_this_week: Decimal
|
||||
revenue_this_month: Decimal
|
||||
|
||||
# Order status breakdown
|
||||
pending_orders: int
|
||||
confirmed_orders: int
|
||||
in_production_orders: int
|
||||
ready_orders: int
|
||||
delivered_orders: int
|
||||
|
||||
# Customer metrics
|
||||
total_customers: int
|
||||
new_customers_this_month: int
|
||||
repeat_customers_rate: Decimal
|
||||
|
||||
# Performance metrics
|
||||
average_order_value: Decimal
|
||||
order_fulfillment_rate: Decimal
|
||||
on_time_delivery_rate: Decimal
|
||||
|
||||
# Business model detection
|
||||
business_model: Optional[str]
|
||||
business_model_confidence: Optional[Decimal]
|
||||
|
||||
# Recent activity
|
||||
recent_orders: List[OrderResponse]
|
||||
high_priority_orders: List[OrderResponse]
|
||||
|
||||
|
||||
class DemandRequirements(BaseModel):
|
||||
"""Demand requirements for production planning"""
|
||||
date: date
|
||||
tenant_id: UUID
|
||||
|
||||
# Product demand breakdown
|
||||
product_demands: List[Dict[str, Any]]
|
||||
|
||||
# Aggregate metrics
|
||||
total_orders: int
|
||||
total_quantity: Decimal
|
||||
total_value: Decimal
|
||||
|
||||
# Business context
|
||||
business_model: Optional[str]
|
||||
rush_orders_count: int
|
||||
special_requirements: List[str]
|
||||
|
||||
# Timing requirements
|
||||
earliest_delivery: datetime
|
||||
latest_delivery: datetime
|
||||
average_lead_time_hours: int
|
||||
|
||||
|
||||
class ProcurementPlanningData(BaseModel):
|
||||
"""Data for procurement planning decisions"""
|
||||
planning_date: date
|
||||
planning_horizon_days: int
|
||||
|
||||
# Demand forecast
|
||||
demand_forecast: List[Dict[str, Any]]
|
||||
|
||||
# Current inventory status
|
||||
inventory_levels: Dict[str, Any]
|
||||
|
||||
# Supplier information
|
||||
supplier_performance: Dict[str, Any]
|
||||
|
||||
# Risk factors
|
||||
supply_risks: List[str]
|
||||
demand_volatility: Decimal
|
||||
|
||||
# Recommendations
|
||||
recommended_purchases: List[Dict[str, Any]]
|
||||
critical_shortages: List[Dict[str, Any]]
|
||||
Reference in New Issue
Block a user