# ================================================================ # services/inventory/app/schemas/dashboard.py # ================================================================ """ Dashboard and analytics schemas for Inventory Service """ from datetime import datetime from decimal import Decimal from typing import List, Optional, Dict, Any from uuid import UUID from pydantic import BaseModel, Field # ===== Dashboard Summary Schemas ===== class InventoryDashboardSummary(BaseModel): """Comprehensive dashboard summary for inventory management""" # Current inventory metrics total_ingredients: int active_ingredients: int total_stock_value: Decimal total_stock_items: int # Stock status breakdown in_stock_items: int low_stock_items: int out_of_stock_items: int expired_items: int expiring_soon_items: int # Food safety metrics food_safety_alerts_active: int temperature_violations_today: int compliance_issues: int certifications_expiring_soon: int # Recent activity recent_stock_movements: int recent_purchases: int recent_waste: int recent_adjustments: int # Business model context business_model: Optional[str] = None # individual_bakery, central_bakery business_model_confidence: Optional[Decimal] = None # Category breakdown stock_by_category: Dict[str, Any] alerts_by_severity: Dict[str, int] movements_by_type: Dict[str, int] # Performance indicators inventory_turnover_ratio: Optional[Decimal] = None waste_percentage: Optional[Decimal] = None compliance_score: Optional[Decimal] = None cost_per_unit_avg: Optional[Decimal] = None # Trending data stock_value_trend: List[Dict[str, Any]] = [] alert_trend: List[Dict[str, Any]] = [] class Config: from_attributes = True class StockStatusSummary(BaseModel): """Summary of stock status by category""" category: str total_ingredients: int in_stock: int low_stock: int out_of_stock: int total_value: Decimal percentage_of_total: Decimal class AlertSummary(BaseModel): """Summary of alerts by type and severity""" alert_type: str severity: str count: int oldest_alert_age_hours: Optional[int] = None average_resolution_time_hours: Optional[int] = None class RecentActivity(BaseModel): """Recent activity item for dashboard""" activity_type: str # stock_added, stock_consumed, alert_created, etc. description: str timestamp: datetime user_name: Optional[str] = None impact_level: str = Field(default="low") # low, medium, high entity_id: Optional[UUID] = None entity_type: Optional[str] = None # ===== Food Safety Dashboard Schemas ===== class FoodSafetyDashboard(BaseModel): """Food safety specific dashboard metrics""" # Compliance overview total_compliance_items: int compliant_items: int non_compliant_items: int pending_review_items: int compliance_percentage: Decimal # Temperature monitoring temperature_sensors_online: int temperature_sensors_total: int temperature_violations_24h: int current_temperature_status: str # all_good, warnings, violations # Expiration tracking items_expiring_today: int items_expiring_this_week: int expired_items_requiring_action: int # Audit and certification status upcoming_audits: int overdue_audits: int certifications_valid: int certifications_expiring_soon: int # Risk assessment high_risk_items: int critical_alerts: int regulatory_notifications_pending: int # Recent safety events recent_safety_incidents: List[RecentActivity] = [] class Config: from_attributes = True class TemperatureMonitoringStatus(BaseModel): """Current temperature monitoring status""" location: str equipment_id: Optional[str] = None current_temperature: Decimal target_min: Decimal target_max: Decimal status: str # normal, warning, critical last_reading: datetime hours_since_last_reading: Decimal alert_active: bool = False class ComplianceStatusSummary(BaseModel): """Compliance status summary by standard""" standard: str standard_name: str total_items: int compliant: int non_compliant: int pending_review: int expired: int compliance_rate: Decimal next_audit_date: Optional[datetime] = None # ===== Analytics and Reporting Schemas ===== class InventoryAnalytics(BaseModel): """Advanced analytics for inventory management""" # Turnover analysis inventory_turnover_rate: Decimal fast_moving_items: List[Dict[str, Any]] slow_moving_items: List[Dict[str, Any]] dead_stock_items: List[Dict[str, Any]] # Cost analysis total_inventory_cost: Decimal cost_by_category: Dict[str, Decimal] average_unit_cost_trend: List[Dict[str, Any]] waste_cost_analysis: Dict[str, Any] # Efficiency metrics stockout_frequency: Dict[str, int] overstock_frequency: Dict[str, int] reorder_accuracy: Decimal forecast_accuracy: Decimal # Quality and safety metrics quality_incidents_rate: Decimal food_safety_score: Decimal compliance_score_by_standard: Dict[str, Decimal] temperature_compliance_rate: Decimal # Supplier performance supplier_performance: List[Dict[str, Any]] delivery_reliability: Decimal quality_consistency: Decimal class Config: from_attributes = True class BusinessModelInsights(BaseModel): """Business model insights based on inventory patterns""" detected_model: str # individual_bakery, central_bakery, mixed confidence_score: Decimal # Model characteristics total_ingredient_types: int average_stock_per_ingredient: Decimal finished_product_ratio: Decimal supplier_diversity: int # Operational patterns order_frequency_pattern: str seasonal_variation: bool bulk_purchasing_indicator: Decimal production_scale_indicator: str # Recommendations business_model_specific_recommendations: List[str] optimization_opportunities: List[str] class Config: from_attributes = True # ===== Request/Filter Schemas ===== class DashboardFilter(BaseModel): """Filtering options for dashboard data""" date_from: Optional[datetime] = None date_to: Optional[datetime] = None categories: Optional[List[str]] = None severity_levels: Optional[List[str]] = None alert_types: Optional[List[str]] = None business_model: Optional[str] = None include_inactive: bool = False class AlertsFilter(BaseModel): """Filtering options for alerts dashboard""" alert_types: Optional[List[str]] = None severities: Optional[List[str]] = None statuses: Optional[List[str]] = None date_from: Optional[datetime] = None date_to: Optional[datetime] = None assigned_to: Optional[UUID] = None unresolved_only: bool = True