# ================================================================ # services/data/app/schemas/sales.py - MISSING FILE # ================================================================ """Sales data schemas""" from pydantic import BaseModel, Field, 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) @field_validator('product_name') @classmethod 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 class SalesValidationRequest(BaseModel): """Schema for JSON-based sales data validation request""" data: str = Field(..., description="Raw data content (CSV, JSON, etc.)") data_format: str = Field(..., pattern="^(csv|json|excel)$", description="Format of the data") validate_only: bool = Field(default=True, description="Only validate, don't import") source: str = Field(default="onboarding_upload", description="Source of the data") class Config: from_attributes = True