Files
drivers_bot/app/models/car.py
2026-05-12 19:14:21 +09:00

143 lines
6.8 KiB
Python

from datetime import date, datetime
from decimal import Decimal
from sqlalchemy import (
Date,
DateTime,
ForeignKey,
Integer,
Numeric,
String,
Text,
UniqueConstraint,
func,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db.base import Base
class Car(Base):
__tablename__ = "cars"
id: Mapped[int] = mapped_column(primary_key=True)
owner_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), index=True)
name: Mapped[str] = mapped_column(String(160))
make: Mapped[str | None] = mapped_column(String(80))
model: Mapped[str | None] = mapped_column(String(80))
trim: Mapped[str | None] = mapped_column(String(120))
year: Mapped[int | None]
plate_number: Mapped[str | None] = mapped_column(String(32))
vin: Mapped[str | None] = mapped_column(String(32))
fuel_type: Mapped[str | None] = mapped_column(String(32))
target_consumption_l_per_100km: Mapped[Decimal | None] = mapped_column(Numeric(6, 2))
fuel_tank_volume_l: Mapped[Decimal | None] = mapped_column(Numeric(6, 2))
engine_oil_type: Mapped[str | None] = mapped_column(String(80))
engine_oil_volume_l: Mapped[Decimal | None] = mapped_column(Numeric(5, 2))
transmission_fluid_type: Mapped[str | None] = mapped_column(String(80))
transmission_fluid_volume_l: Mapped[Decimal | None] = mapped_column(Numeric(5, 2))
coolant_type: Mapped[str | None] = mapped_column(String(80))
brake_fluid_type: Mapped[str | None] = mapped_column(String(80))
tire_pressure_front_bar: Mapped[Decimal | None] = mapped_column(Numeric(4, 2))
tire_pressure_rear_bar: Mapped[Decimal | None] = mapped_column(Numeric(4, 2))
purchase_date: Mapped[date | None] = mapped_column(Date)
purchase_price: Mapped[Decimal | None] = mapped_column(Numeric(12, 2))
current_odometer: Mapped[int | None]
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
)
owner = relationship("User", back_populates="cars")
fuel_entries = relationship("FuelEntry", back_populates="car", cascade="all, delete-orphan")
service_entries = relationship("ServiceEntry", back_populates="car", cascade="all, delete-orphan")
service_links = relationship("CarServiceLink", back_populates="car", cascade="all, delete-orphan")
class CarMake(Base):
__tablename__ = "car_makes"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(80), unique=True, index=True)
country: Mapped[str | None] = mapped_column(String(80))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
models = relationship("CarModel", back_populates="make", cascade="all, delete-orphan")
class CarModel(Base):
__tablename__ = "car_models"
__table_args__ = (UniqueConstraint("make_id", "name", name="uq_car_models_make_name"),)
id: Mapped[int] = mapped_column(primary_key=True)
make_id: Mapped[int] = mapped_column(ForeignKey("car_makes.id", ondelete="CASCADE"), index=True)
name: Mapped[str] = mapped_column(String(100), index=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
make = relationship("CarMake", back_populates="models")
trims = relationship("CarTrim", back_populates="model", cascade="all, delete-orphan")
class CarTrim(Base):
__tablename__ = "car_trims"
__table_args__ = (UniqueConstraint("model_id", "name", name="uq_car_trims_model_name"),)
id: Mapped[int] = mapped_column(primary_key=True)
model_id: Mapped[int] = mapped_column(ForeignKey("car_models.id", ondelete="CASCADE"), index=True)
name: Mapped[str] = mapped_column(String(120), index=True)
body_type: Mapped[str | None] = mapped_column(String(60))
fuel_type: Mapped[str | None] = mapped_column(String(32))
transmission: Mapped[str | None] = mapped_column(String(32))
drive_type: Mapped[str | None] = mapped_column(String(32))
year_from: Mapped[int | None] = mapped_column(Integer)
year_to: Mapped[int | None] = mapped_column(Integer)
market: Mapped[str | None] = mapped_column(String(80))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
model = relationship("CarModel", back_populates="trims")
class ServiceCenter(Base):
__tablename__ = "service_centers"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(160), unique=True, index=True)
telegram_chat_id: Mapped[str | None] = mapped_column(String(80), unique=True, index=True)
contact_phone: Mapped[str | None] = mapped_column(String(40))
address: Mapped[str | None] = mapped_column(String(240))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
car_links = relationship("CarServiceLink", back_populates="service_center", cascade="all, delete-orphan")
inbox_messages = relationship("ServiceInboxMessage", back_populates="service_center")
class CarServiceLink(Base):
__tablename__ = "car_service_links"
__table_args__ = (UniqueConstraint("car_id", "service_center_id", name="uq_car_service_link"),)
id: Mapped[int] = mapped_column(primary_key=True)
car_id: Mapped[int] = mapped_column(ForeignKey("cars.id", ondelete="CASCADE"), index=True)
service_center_id: Mapped[int] = mapped_column(ForeignKey("service_centers.id", ondelete="CASCADE"), index=True)
external_vehicle_ref: Mapped[str | None] = mapped_column(String(120), index=True)
is_active: Mapped[bool] = mapped_column(default=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
car = relationship("Car", back_populates="service_links")
service_center = relationship("ServiceCenter", back_populates="car_links")
class ServiceInboxMessage(Base):
__tablename__ = "service_inbox_messages"
id: Mapped[int] = mapped_column(primary_key=True)
service_center_id: Mapped[int | None] = mapped_column(ForeignKey("service_centers.id", ondelete="SET NULL"), index=True)
car_id: Mapped[int | None] = mapped_column(ForeignKey("cars.id", ondelete="SET NULL"), index=True)
source_chat_id: Mapped[str | None] = mapped_column(String(80), index=True)
raw_text: Mapped[str] = mapped_column(Text)
parsed_status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
parsed_payload: Mapped[str | None] = mapped_column(Text)
error: Mapped[str | None] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
service_center = relationship("ServiceCenter", back_populates="inbox_messages")