from pydantic import BaseModel, Field from typing import Optional, List from datetime import datetime class CustomerDeviceCreate(BaseModel): brand: str model: str model_number: Optional[str] = None imei_primary: Optional[str] = None imei_secondary: Optional[str] = None color: Optional[str] = None device_condition: Optional[str] = None device_type: Optional[str] = None notes: Optional[str] = None storage_capacity: Optional[str] = None class CustomerDeviceResponse(BaseModel): device_id: str customer_id: str brand: str model: str model_number: Optional[str] imei_primary: Optional[str] imei_secondary: Optional[str] color: Optional[str] device_condition: Optional[str] device_type: Optional[str] notes: Optional[str] storage_capacity: Optional[str] created_at: datetime updated_at: datetime class Config: from_attributes = True class ServiceCatalogCreate(BaseModel): name: str description: Optional[str] = None base_price: float estimated_duration_minutes: int workflow_type: str = "REPAIR_QUOTE" class ServiceCatalogResponse(BaseModel): service_id: str name: str description: Optional[str] base_price: float estimated_duration_minutes: int workflow_type: str active: bool class Config: from_attributes = True class ServiceAppointmentCreate(BaseModel): scheduled_start: datetime scheduled_end: datetime class ServiceAppointmentResponse(BaseModel): appointment_id: str service_job_id: str scheduled_start: datetime scheduled_end: datetime status: str hold_expires_at: Optional[datetime] created_at: datetime confirmed_at: Optional[datetime] cancelled_at: Optional[datetime] class Config: from_attributes = True class ServiceJobCreate(BaseModel): device_id: Optional[str] = None # If already registered new_device: Optional[CustomerDeviceCreate] = None service_id: Optional[str] = None # Optional for Cashify jobs source: str = "ONLINE" appointment: Optional[ServiceAppointmentCreate] = None customer_id: Optional[str] = None customer_name: Optional[str] = None customer_phone: Optional[str] = None customer_email: Optional[str] = None custom_service_name: Optional[str] = None # Granular Selection Parameters device_type: Optional[str] = None brand_id: Optional[str] = None series_id: Optional[str] = None model_id: Optional[str] = None service_type_id: Optional[str] = None repair_service_id: Optional[str] = None repair_variant_id: Optional[str] = None priority: Optional[str] = "NORMAL" class ServiceJobResponse(BaseModel): job_id: str job_no: str customer_id: str device_id: str source: str service_id: Optional[str] = None status: str custom_service_name: Optional[str] = None device_type: Optional[str] = None brand_id: Optional[str] = None series_id: Optional[str] = None model_id: Optional[str] = None service_type_id: Optional[str] = None repair_service_id: Optional[str] = None repair_variant_id: Optional[str] = None currency: Optional[str] = "INR" service_name_snapshot: Optional[str] = None variant_name_snapshot: Optional[str] = None base_price_snapshot: Optional[float] = None duration_snapshot: Optional[int] = None warranty_snapshot: Optional[int] = None inspection_fee_snapshot: Optional[float] = None queue_number: Optional[str] = None priority: Optional[str] = "NORMAL" created_at: datetime updated_at: datetime class Config: from_attributes = True class ServiceJobIntakeCreate(BaseModel): power_status: Optional[str] = None screen_condition: Optional[str] = None body_condition: Optional[str] = None back_condition: Optional[str] = None camera_condition: Optional[str] = None accessories: Optional[str] = None customer_notes: Optional[str] = None technician_notes: Optional[str] = None class ServiceJobIntakeResponse(BaseModel): intake_id: str service_job_id: str received_by: str received_at: datetime power_status: Optional[str] screen_condition: Optional[str] body_condition: Optional[str] back_condition: Optional[str] camera_condition: Optional[str] accessories: Optional[str] customer_notes: Optional[str] technician_notes: Optional[str] class Config: from_attributes = True class ServiceJobInspectionCreate(BaseModel): result: str # CUSTOMER_REPORT_CONFIRMED, CUSTOMER_REPORT_PARTIALLY_CONFIRMED, CUSTOMER_REPORT_NOT_CONFIRMED, ADDITIONAL_DAMAGE_FOUND customer_report: Optional[str] = None confirmed_damage: Optional[str] = None additional_damage: Optional[str] = None notes: Optional[str] = None class ServiceJobInspectionResponse(BaseModel): inspection_id: str service_job_id: str technician_id: str result: str customer_report: Optional[str] confirmed_damage: Optional[str] additional_damage: Optional[str] notes: Optional[str] created_at: datetime class Config: from_attributes = True class ServiceJobRescheduleRequest(BaseModel): scheduled_start: datetime scheduled_end: datetime reason: Optional[str] = None