Add service platform foundation
This commit is contained in:
@@ -1,22 +1,227 @@
|
||||
from datetime import datetime
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from pydantic import BaseModel, ConfigDict, field_validator
|
||||
|
||||
from app.services.vehicle_identity import normalize_license_plate, validate_vin
|
||||
|
||||
|
||||
class ServiceCenterCreate(BaseModel):
|
||||
name: str
|
||||
legal_name: str | None = None
|
||||
display_name: str
|
||||
country: str | None = None
|
||||
city: str | None = None
|
||||
address: str | None = None
|
||||
phone: str | None = None
|
||||
business_registration_number: str | None = None
|
||||
telegram_chat_id: str | None = None
|
||||
contact_phone: str | None = None
|
||||
address: str | None = None
|
||||
|
||||
|
||||
class ServiceCenterRead(ServiceCenterCreate):
|
||||
id: int
|
||||
name: str
|
||||
verification_status: str
|
||||
owner_user_id: int | None = None
|
||||
created_at: datetime
|
||||
verified_at: datetime | None = None
|
||||
suspended_at: datetime | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ServiceCenterVerificationCreate(BaseModel):
|
||||
submitted_documents: list[dict] | None = None
|
||||
comment: str | None = None
|
||||
|
||||
|
||||
class ServiceCenterVerificationRead(ServiceCenterVerificationCreate):
|
||||
id: int
|
||||
service_center_id: int
|
||||
status: str
|
||||
reviewed_by: int | None = None
|
||||
reviewed_at: datetime | None = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ServiceEmployeeInvite(BaseModel):
|
||||
telegram_id: int
|
||||
role: str = "receptionist"
|
||||
permissions: dict | None = None
|
||||
|
||||
|
||||
class ServiceEmployeeRead(BaseModel):
|
||||
id: int
|
||||
service_center_id: int
|
||||
user_id: int
|
||||
role: str
|
||||
permissions: dict | None = None
|
||||
status: str
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class VehicleAccessGrant(BaseModel):
|
||||
service_center_id: int | None = None
|
||||
user_id: int | None = None
|
||||
role: str = "viewer"
|
||||
|
||||
|
||||
class VehicleAccessRead(BaseModel):
|
||||
id: int
|
||||
vehicle_id: int
|
||||
user_id: int
|
||||
role: str
|
||||
status: str
|
||||
created_at: datetime
|
||||
revoked_at: datetime | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class VehicleCreate(BaseModel):
|
||||
name: str
|
||||
make: str | None = None
|
||||
model: str | None = None
|
||||
year: int | None = None
|
||||
license_plate: str | None = None
|
||||
license_plate_country: str | None = None
|
||||
vin: str | None = None
|
||||
current_odometer: int | None = None
|
||||
engine_oil_type: str | None = None
|
||||
engine_oil_volume_l: Decimal | None = None
|
||||
|
||||
@field_validator("vin")
|
||||
@classmethod
|
||||
def validate_vin_field(cls, value: str | None) -> str | None:
|
||||
return validate_vin(value)
|
||||
|
||||
|
||||
class VehicleUpdate(BaseModel):
|
||||
name: str | None = None
|
||||
make: str | None = None
|
||||
model: str | None = None
|
||||
year: int | None = None
|
||||
license_plate: str | None = None
|
||||
license_plate_country: str | None = None
|
||||
vin: str | None = None
|
||||
current_odometer: int | None = None
|
||||
engine_oil_type: str | None = None
|
||||
engine_oil_volume_l: Decimal | None = None
|
||||
|
||||
@field_validator("vin")
|
||||
@classmethod
|
||||
def validate_vin_field(cls, value: str | None) -> str | None:
|
||||
return validate_vin(value)
|
||||
|
||||
|
||||
class VehicleRead(BaseModel):
|
||||
id: int
|
||||
owner_id: int
|
||||
name: str
|
||||
make: str | None = None
|
||||
model: str | None = None
|
||||
year: int | None = None
|
||||
license_plate_display: str | None = None
|
||||
license_plate_country: str | None = None
|
||||
vin_normalized: str | None = None
|
||||
current_odometer: int | None = None
|
||||
engine_oil_type: str | None = None
|
||||
engine_oil_volume_l: Decimal | None = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ServiceVisitCreate(BaseModel):
|
||||
vehicle_id: int
|
||||
visit_date: date
|
||||
odometer: int | None = None
|
||||
notes: str | None = None
|
||||
total_cost: Decimal | None = None
|
||||
currency: str = "RUB"
|
||||
|
||||
|
||||
class ServiceVisitRead(ServiceVisitCreate):
|
||||
id: int
|
||||
service_center_id: int
|
||||
created_by_employee_id: int | None = None
|
||||
status: str
|
||||
owner_resolved_at: datetime | None = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ServiceWorkItemCreate(BaseModel):
|
||||
work_type: str = "other"
|
||||
title: str
|
||||
description: str | None = None
|
||||
parts: list[dict] | None = None
|
||||
oil_brand: str | None = None
|
||||
oil_viscosity: str | None = None
|
||||
oil_volume: Decimal | None = None
|
||||
next_due_odometer: int | None = None
|
||||
next_due_date: date | None = None
|
||||
price: Decimal | None = None
|
||||
|
||||
|
||||
class ServiceWorkItemRead(ServiceWorkItemCreate):
|
||||
id: int
|
||||
service_visit_id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class VehicleDataChangeRequestCreate(BaseModel):
|
||||
vehicle_id: int
|
||||
field_name: str
|
||||
new_value: str | None = None
|
||||
|
||||
|
||||
class VehicleDataChangeRequestRead(VehicleDataChangeRequestCreate):
|
||||
id: int
|
||||
requested_by_service_center_id: int | None = None
|
||||
requested_by_employee_id: int | None = None
|
||||
old_value: str | None = None
|
||||
status: str
|
||||
owner_user_id: int
|
||||
created_at: datetime
|
||||
resolved_at: datetime | None = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class VehicleSearchRequest(BaseModel):
|
||||
license_plate: str | None = None
|
||||
country_code: str | None = None
|
||||
vin: str | None = None
|
||||
|
||||
@field_validator("vin")
|
||||
@classmethod
|
||||
def validate_vin_field(cls, value: str | None) -> str | None:
|
||||
return validate_vin(value)
|
||||
|
||||
@field_validator("license_plate")
|
||||
@classmethod
|
||||
def normalize_plate_field(cls, value: str | None) -> str | None:
|
||||
return normalize_license_plate(value)
|
||||
|
||||
|
||||
class VehicleSearchResult(BaseModel):
|
||||
vehicle_id: int | None = None
|
||||
make: str | None = None
|
||||
model: str | None = None
|
||||
year: int | None = None
|
||||
masked_license_plate: str | None = None
|
||||
masked_vin: str | None = None
|
||||
access_status: str = "none"
|
||||
|
||||
|
||||
class CarServiceLinkCreate(BaseModel):
|
||||
car_id: int
|
||||
service_center_id: int
|
||||
|
||||
Reference in New Issue
Block a user