Files
bakery-ia/services/data/app/schemas/sales.py
2025-07-26 21:10:54 +02:00

160 lines
5.3 KiB
Python

# ================================================================
# services/data/app/schemas/sales.py - MISSING FILE
# ================================================================
"""Sales data schemas"""
from pydantic import BaseModel, Field, validator
from datetime import datetime
from typing import Optional, List, Dict, Any
from uuid import UUID
class SalesDataCreate(BaseModel):
"""Schema for creating sales data - FIXED to work with gateway"""
# ✅ FIX: Make tenant_id optional since it comes from URL path
tenant_id: Optional[UUID] = Field(None, description="Tenant ID (auto-injected from URL path)")
date: datetime
product_name: str = Field(..., min_length=1, max_length=255)
quantity_sold: int = Field(..., gt=0)
revenue: float = Field(..., gt=0)
location_id: Optional[str] = Field(None, max_length=100)
source: str = Field(default="manual", max_length=50)
notes: Optional[str] = Field(None, max_length=500)
@validator('product_name')
def normalize_product_name(cls, v):
return v.strip().lower()
class Config:
from_attributes = True
json_schema_extra = {
"example": {
"date": "2024-01-15T10:00:00Z",
"product_name": "Pan Integral",
"quantity_sold": 25,
"revenue": 37.50,
"source": "manual"
# Note: tenant_id is automatically injected from URL path by gateway
}
}
class SalesDataResponse(BaseModel):
"""Schema for sales data response"""
id: UUID
tenant_id: UUID
date: datetime
product_name: str
quantity_sold: int
revenue: float
location_id: Optional[str]
source: str
notes: Optional[str]
created_at: datetime
updated_at: Optional[datetime]
class Config:
from_attributes = True
class SalesDataQuery(BaseModel):
"""Schema for querying sales data"""
tenant_id: UUID
start_date: Optional[datetime] = None
end_date: Optional[datetime] = None
product_names: Optional[List[str]] = None
location_ids: Optional[List[str]] = None
sources: Optional[List[str]] = None
min_quantity: Optional[int] = None
max_quantity: Optional[int] = None
min_revenue: Optional[float] = None
max_revenue: Optional[float] = None
limit: Optional[int] = Field(default=1000, le=5000)
offset: Optional[int] = Field(default=0, ge=0)
class Config:
from_attributes = True
class SalesDataImport(BaseModel):
"""Schema for importing sales data - FIXED to work with gateway"""
# ✅ FIX: Make tenant_id optional since it comes from URL path
tenant_id: Optional[UUID] = Field(None, description="Tenant ID (auto-injected from URL path)")
data: str = Field(..., description="JSON string or CSV content")
data_format: str = Field(..., pattern="^(csv|json|excel)$")
source: str = Field(default="import", max_length=50)
validate_only: bool = Field(default=False)
class Config:
from_attributes = True
json_schema_extra = {
"example": {
"data": "date,product,quantity,revenue\n2024-01-01,bread,10,25.50",
"data_format": "csv",
# Note: tenant_id is automatically injected from URL path by gateway
}
}
class SalesDataBulkCreate(BaseModel):
"""Schema for bulk creating sales data"""
tenant_id: UUID
records: List[Dict[str, Any]]
source: str = Field(default="bulk_import", max_length=50)
class Config:
from_attributes = True
class SalesValidationResult(BaseModel):
"""Schema for sales data validation result"""
is_valid: bool
total_records: int
valid_records: int
invalid_records: int
errors: List[Dict[str, Any]]
warnings: List[Dict[str, Any]]
summary: Dict[str, Any]
class Config:
from_attributes = True
class SalesImportResult(BaseModel):
"""Complete schema that includes all expected fields"""
success: bool
records_processed: int # total_rows
records_created: int
records_updated: int = 0 # Default to 0 if not tracking updates
records_failed: int # error_count or calculated
errors: List[Dict[str, Any]] # Structured error objects
warnings: List[Dict[str, Any]] # Structured warning objects
processing_time_seconds: float
# Optional additional fields
source: Optional[str] = None
filename: Optional[str] = None
success_rate: Optional[float] = None
class Config:
from_attributes = True
class SalesAggregation(BaseModel):
"""Schema for sales aggregation results"""
period: str # "daily", "weekly", "monthly"
date: datetime
product_name: Optional[str] = None
total_quantity: int
total_revenue: float
average_quantity: float
average_revenue: float
record_count: int
class Config:
from_attributes = True
class SalesExportRequest(BaseModel):
"""Schema for sales export request"""
tenant_id: UUID
format: str = Field(..., pattern="^(csv|json|excel)$")
start_date: Optional[datetime] = None
end_date: Optional[datetime] = None
product_names: Optional[List[str]] = None
location_ids: Optional[List[str]] = None
include_metadata: bool = Field(default=True)
class Config:
from_attributes = True