from datetime import date, datetime from decimal import Decimal from pydantic import BaseModel, ConfigDict, field_validator from app.services.vehicle_identity import validate_vin class CarBase(BaseModel): name: str make: str | None = None model: str | None = None trim: str | None = None generation: str | None = None body_type: str | None = None year: int | None = None plate_number: str | None = None vin: str | None = None fuel_type: str | None = None engine_volume_l: Decimal | None = None transmission: str | None = None drive_type: str | None = None target_consumption_l_per_100km: Decimal | None = None fuel_tank_volume_l: Decimal | None = None engine_oil_type: str | None = None engine_oil_volume_l: Decimal | None = None transmission_fluid_type: str | None = None transmission_fluid_volume_l: Decimal | None = None coolant_type: str | None = None brake_fluid_type: str | None = None tire_pressure_front_bar: Decimal | None = None tire_pressure_rear_bar: Decimal | None = None tire_size: str | None = None oil_change_interval_km: int | None = None oil_change_interval_months: int | None = None purchase_date: date | None = None purchase_price: Decimal | None = None purchase_currency: str | None = None purchase_type: str = "unknown" currency: str = "RUB" include_depreciation: bool = False expected_ownership_months: int | None = None expected_residual_value: Decimal | None = None loan_principal: Decimal | None = None loan_down_payment: Decimal | None = None loan_term_months: int | None = None loan_annual_interest_rate: Decimal | None = None loan_first_payment_date: date | None = None loan_payment_day: int | None = None loan_payment_type: str = "annuity" loan_currency: str | None = None loan_comment: str | None = None current_odometer: int | None = None notes: str | None = None @field_validator("vin") @classmethod def validate_vin_field(cls, value: str | None) -> str | None: return validate_vin(value) class CarCreate(CarBase): owner_id: int | None = None class CarUpdate(BaseModel): name: str | None = None make: str | None = None model: str | None = None trim: str | None = None generation: str | None = None body_type: str | None = None year: int | None = None plate_number: str | None = None vin: str | None = None fuel_type: str | None = None engine_volume_l: Decimal | None = None transmission: str | None = None drive_type: str | None = None target_consumption_l_per_100km: Decimal | None = None fuel_tank_volume_l: Decimal | None = None engine_oil_type: str | None = None engine_oil_volume_l: Decimal | None = None transmission_fluid_type: str | None = None transmission_fluid_volume_l: Decimal | None = None coolant_type: str | None = None brake_fluid_type: str | None = None tire_pressure_front_bar: Decimal | None = None tire_pressure_rear_bar: Decimal | None = None tire_size: str | None = None oil_change_interval_km: int | None = None oil_change_interval_months: int | None = None purchase_date: date | None = None purchase_price: Decimal | None = None purchase_currency: str | None = None purchase_type: str | None = None currency: str | None = None include_depreciation: bool | None = None expected_ownership_months: int | None = None expected_residual_value: Decimal | None = None loan_principal: Decimal | None = None loan_down_payment: Decimal | None = None loan_term_months: int | None = None loan_annual_interest_rate: Decimal | None = None loan_first_payment_date: date | None = None loan_payment_day: int | None = None loan_payment_type: str | None = None loan_currency: str | None = None loan_comment: str | None = None current_odometer: int | None = None notes: str | None = None @field_validator("vin") @classmethod def validate_vin_field(cls, value: str | None) -> str | None: return validate_vin(value) class CarRead(CarBase): id: int owner_id: int created_at: datetime model_config = ConfigDict(from_attributes=True) class CarTrimRead(BaseModel): id: int name: str body_type: str | None = None fuel_type: str | None = None transmission: str | None = None drive_type: str | None = None year_from: int | None = None year_to: int | None = None market: str | None = None model_config = ConfigDict(from_attributes=True) class CarModelRead(BaseModel): id: int name: str trims: list[CarTrimRead] = [] model_config = ConfigDict(from_attributes=True) class CarMakeRead(BaseModel): id: int name: str country: str | None = None models: list[CarModelRead] = [] model_config = ConfigDict(from_attributes=True)