231 lines
7 KiB
Python
231 lines
7 KiB
Python
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"
|
|
|
|
# Fulfillment & Security Attributes
|
|
fulfillment_type: str = "WALK_IN" # WALK_IN, COURIER, DOORSTEP_PICKUP
|
|
alt_phone: Optional[str] = None
|
|
is_whatsapp_alt: Optional[bool] = True
|
|
delivery_address: Optional[str] = None
|
|
pre_dispatch_video_id: Optional[str] = None
|
|
lock_type: Optional[str] = "NONE" # NONE, PIN, PASSWORD, PATTERN
|
|
lock_passcode: Optional[str] = None
|
|
|
|
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"
|
|
|
|
# Fulfillment & Security Attributes
|
|
fulfillment_type: Optional[str] = "WALK_IN"
|
|
fulfillment_fee: Optional[float] = 0.00
|
|
alt_phone: Optional[str] = None
|
|
is_whatsapp_alt: Optional[bool] = True
|
|
delivery_address: Optional[str] = None
|
|
pre_dispatch_video_id: Optional[str] = None
|
|
courier_name: Optional[str] = None
|
|
awb_number: Optional[str] = None
|
|
pickup_status: Optional[str] = None
|
|
lock_type: Optional[str] = "NONE"
|
|
lock_credential_created_at: Optional[datetime] = None
|
|
lock_credential_accessed_at: Optional[datetime] = None
|
|
lock_credential_accessed_by: Optional[str] = None
|
|
lock_credential_deleted_at: Optional[datetime] = None
|
|
lock_credential_decrypted: Optional[str] = None
|
|
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class ServiceJobLogisticsUpdate(BaseModel):
|
|
courier_name: Optional[str] = None
|
|
awb_number: Optional[str] = None
|
|
pickup_status: Optional[str] = None
|
|
|
|
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
|
|
|
|
class ServiceJobMediaBatchCreate(BaseModel):
|
|
category: str # INTAKE_PHOTO, INTAKE_VIDEO, INSPECTION_DONE, READY_FOR_DELIVERY, BEFORE_REPAIR, AFTER_REPAIR
|
|
file_ids: List[str]
|
|
|
|
class ServiceJobMediaResponse(BaseModel):
|
|
media_id: str
|
|
service_job_id: str
|
|
category: str
|
|
file_id: str
|
|
created_at: datetime
|
|
url: Optional[str] = None
|
|
webp_path: Optional[str] = None
|
|
thumbnail_path: Optional[str] = None
|
|
mime_type: Optional[str] = None
|
|
blur_hash: Optional[str] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|