first commit
This commit is contained in:
1
app/models/__init__.py
Normal file
1
app/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
55
app/models/car.py
Normal file
55
app/models/car.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from sqlalchemy import Date, DateTime, ForeignKey, Numeric, String, 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))
|
||||
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))
|
||||
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")
|
||||
|
||||
|
||||
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")
|
||||
58
app/models/expense.py
Normal file
58
app/models/expense.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import enum
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
|
||||
from sqlalchemy import Date, DateTime, Enum, ForeignKey, Numeric, String, Text, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.db.base import Base
|
||||
|
||||
|
||||
class ServiceType(str, enum.Enum):
|
||||
maintenance = "maintenance"
|
||||
repair = "repair"
|
||||
fluid = "fluid"
|
||||
tire = "tire"
|
||||
inspection = "inspection"
|
||||
insurance = "insurance"
|
||||
tax = "tax"
|
||||
other = "other"
|
||||
|
||||
|
||||
class FuelEntry(Base):
|
||||
__tablename__ = "fuel_entries"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
car_id: Mapped[int] = mapped_column(ForeignKey("cars.id", ondelete="CASCADE"), index=True)
|
||||
entry_date: Mapped[date] = mapped_column(Date, index=True)
|
||||
odometer: Mapped[int]
|
||||
liters: Mapped[Decimal] = mapped_column(Numeric(8, 3))
|
||||
price_per_liter: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
||||
total_cost: Mapped[Decimal] = mapped_column(Numeric(12, 2))
|
||||
station: Mapped[str | None] = mapped_column(String(160))
|
||||
fuel_brand: Mapped[str | None] = mapped_column(String(80))
|
||||
is_full_tank: Mapped[bool] = mapped_column(default=True)
|
||||
notes: Mapped[str | None] = mapped_column(Text)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
car = relationship("Car", back_populates="fuel_entries")
|
||||
|
||||
|
||||
class ServiceEntry(Base):
|
||||
__tablename__ = "service_entries"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
car_id: Mapped[int] = mapped_column(ForeignKey("cars.id", ondelete="CASCADE"), index=True)
|
||||
entry_date: Mapped[date] = mapped_column(Date, index=True)
|
||||
odometer: Mapped[int | None]
|
||||
service_type: Mapped[ServiceType] = mapped_column(Enum(ServiceType), index=True)
|
||||
title: Mapped[str] = mapped_column(String(180))
|
||||
category: Mapped[str | None] = mapped_column(String(80))
|
||||
vendor: Mapped[str | None] = mapped_column(String(160))
|
||||
total_cost: Mapped[Decimal] = mapped_column(Numeric(12, 2))
|
||||
next_due_date: Mapped[date | None] = mapped_column(Date)
|
||||
next_due_odometer: Mapped[int | None]
|
||||
notes: Mapped[str | None] = mapped_column(Text)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
car = relationship("Car", back_populates="service_entries")
|
||||
24
app/models/user.py
Normal file
24
app/models/user.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import BigInteger, DateTime, String, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.db.base import Base
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
telegram_id: Mapped[int] = mapped_column(BigInteger, unique=True, index=True)
|
||||
username: Mapped[str | None] = mapped_column(String(128))
|
||||
first_name: Mapped[str | None] = mapped_column(String(128))
|
||||
last_name: Mapped[str | None] = mapped_column(String(128))
|
||||
locale: Mapped[str] = mapped_column(String(8), default="ru", server_default="ru")
|
||||
currency: Mapped[str] = mapped_column(String(3), default="RUB", server_default="RUB")
|
||||
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()
|
||||
)
|
||||
|
||||
cars = relationship("Car", back_populates="owner", cascade="all, delete-orphan")
|
||||
Reference in New Issue
Block a user