Add order page with real API calls

This commit is contained in:
Urtzi Alfaro
2025-09-19 11:44:38 +02:00
parent 447e2a5012
commit 105410c9d3
22 changed files with 2556 additions and 463 deletions

View File

@@ -11,13 +11,20 @@ from typing import Optional, List, Dict, Any
from uuid import UUID
from pydantic import BaseModel, Field, validator
from app.models.enums import (
CustomerType, DeliveryMethod, PaymentTerms, PaymentMethod, PaymentStatus,
CustomerSegment, PriorityLevel, OrderType, OrderStatus, OrderSource,
SalesChannel, BusinessModel, ProcurementPlanType, ProcurementStrategy,
RiskLevel, RequirementStatus, PlanStatus, DeliveryStatus
)
# ===== 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)$")
customer_type: CustomerType = Field(default=CustomerType.INDIVIDUAL)
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)
@@ -27,16 +34,20 @@ class CustomerBase(BaseModel):
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)$")
preferred_delivery_method: DeliveryMethod = Field(default=DeliveryMethod.DELIVERY)
payment_terms: PaymentTerms = Field(default=PaymentTerms.IMMEDIATE)
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)$")
customer_segment: CustomerSegment = Field(default=CustomerSegment.REGULAR)
priority_level: PriorityLevel = Field(default=PriorityLevel.NORMAL)
special_instructions: Optional[str] = None
delivery_preferences: Optional[Dict[str, Any]] = None
product_preferences: Optional[Dict[str, Any]] = None
class Config:
from_attributes = True
use_enum_values = True
class CustomerCreate(CustomerBase):
customer_code: str = Field(..., min_length=1, max_length=50)
@@ -46,7 +57,7 @@ class CustomerCreate(CustomerBase):
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)$")
customer_type: Optional[CustomerType] = None
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)
@@ -56,16 +67,20 @@ class CustomerUpdate(BaseModel):
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)$")
preferred_delivery_method: Optional[DeliveryMethod] = None
payment_terms: Optional[PaymentTerms] = None
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)$")
customer_segment: Optional[CustomerSegment] = None
priority_level: Optional[PriorityLevel] = None
special_instructions: Optional[str] = None
delivery_preferences: Optional[Dict[str, Any]] = None
product_preferences: Optional[Dict[str, Any]] = None
class Config:
from_attributes = True
use_enum_values = True
class CustomerResponse(CustomerBase):
id: UUID
@@ -129,26 +144,30 @@ class OrderItemResponse(OrderItemBase):
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)$")
order_type: OrderType = Field(default=OrderType.STANDARD)
priority: PriorityLevel = Field(default=PriorityLevel.NORMAL)
requested_delivery_date: datetime
delivery_method: str = Field(default="delivery", pattern="^(delivery|pickup)$")
delivery_method: DeliveryMethod = Field(default=DeliveryMethod.DELIVERY)
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)$")
payment_method: Optional[PaymentMethod] = None
payment_terms: PaymentTerms = Field(default=PaymentTerms.IMMEDIATE)
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_source: OrderSource = Field(default=OrderSource.MANUAL)
sales_channel: SalesChannel = Field(default=SalesChannel.DIRECT)
order_origin: Optional[str] = Field(None, max_length=100)
communication_preferences: Optional[Dict[str, Any]] = None
class Config:
from_attributes = True
use_enum_values = True
class OrderCreate(OrderBase):
tenant_id: UUID
@@ -156,21 +175,25 @@ class OrderCreate(OrderBase):
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)$")
status: Optional[OrderStatus] = None
priority: Optional[PriorityLevel] = None
requested_delivery_date: Optional[datetime] = None
confirmed_delivery_date: Optional[datetime] = None
delivery_method: Optional[str] = Field(None, pattern="^(delivery|pickup)$")
delivery_method: Optional[DeliveryMethod] = None
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)$")
payment_method: Optional[PaymentMethod] = None
payment_status: Optional[PaymentStatus] = None
special_instructions: Optional[str] = None
custom_requirements: Optional[Dict[str, Any]] = None
allergen_warnings: Optional[Dict[str, Any]] = None
class Config:
from_attributes = True
use_enum_values = True
class OrderResponse(OrderBase):
id: UUID
@@ -205,17 +228,21 @@ class ProcurementRequirementBase(BaseModel):
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)$")
product_type: str = Field(default="ingredient") # TODO: Create ProductType enum if needed
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)$")
priority: PriorityLevel = Field(default=PriorityLevel.NORMAL)
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 Config:
from_attributes = True
use_enum_values = True
class ProcurementRequirementCreate(ProcurementRequirementBase):
pass
@@ -248,13 +275,17 @@ class ProcurementPlanBase(BaseModel):
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)$")
plan_type: ProcurementPlanType = Field(default=ProcurementPlanType.REGULAR)
priority: PriorityLevel = Field(default=PriorityLevel.NORMAL)
business_model: Optional[BusinessModel] = None
procurement_strategy: ProcurementStrategy = Field(default=ProcurementStrategy.JUST_IN_TIME)
safety_stock_buffer: Decimal = Field(default=Decimal("20.00"), ge=0, le=100)
special_requirements: Optional[str] = None
class Config:
from_attributes = True
use_enum_values = True
class ProcurementPlanCreate(ProcurementPlanBase):
tenant_id: UUID