95 lines
2.2 KiB
Python
95 lines
2.2 KiB
Python
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
|
|
from pydantic import BaseModel, ConfigDict, model_validator
|
|
|
|
from app.models.expense import ServiceType
|
|
|
|
|
|
class FuelEntryBase(BaseModel):
|
|
entry_date: date
|
|
odometer: int
|
|
liters: Decimal
|
|
price_per_liter: Decimal
|
|
total_cost: Decimal | None = None
|
|
station: str | None = None
|
|
fuel_brand: str | None = None
|
|
is_full_tank: bool = True
|
|
notes: str | None = None
|
|
|
|
@model_validator(mode="after")
|
|
def fill_total_cost(self) -> "FuelEntryBase":
|
|
if self.total_cost is None:
|
|
self.total_cost = self.liters * self.price_per_liter
|
|
return self
|
|
|
|
|
|
class FuelEntryCreate(FuelEntryBase):
|
|
car_id: int
|
|
|
|
|
|
class FuelEntryRead(FuelEntryBase):
|
|
id: int
|
|
car_id: int
|
|
total_cost: Decimal
|
|
created_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ServiceEntryBase(BaseModel):
|
|
entry_date: date
|
|
odometer: int | None = None
|
|
service_type: ServiceType
|
|
title: str
|
|
category: str | None = None
|
|
vendor: str | None = None
|
|
total_cost: Decimal
|
|
next_due_date: date | None = None
|
|
next_due_odometer: int | None = None
|
|
notes: str | None = None
|
|
|
|
|
|
class ServiceEntryCreate(ServiceEntryBase):
|
|
car_id: int
|
|
|
|
|
|
class ServiceEntryRead(ServiceEntryBase):
|
|
id: int
|
|
car_id: int
|
|
created_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class OwnershipStats(BaseModel):
|
|
car_id: int
|
|
date_from: date
|
|
date_to: date
|
|
fuel_cost: Decimal
|
|
service_cost: Decimal
|
|
total_cost: Decimal
|
|
liters: Decimal
|
|
distance_km: int
|
|
avg_consumption_l_per_100km: float | None
|
|
cost_per_km: float | None
|
|
fuel_entries_count: int
|
|
service_entries_count: int
|
|
|
|
|
|
class OdometerPrediction(BaseModel):
|
|
car_id: int
|
|
samples: int
|
|
current_odometer: int | None
|
|
predicted_today: int | None
|
|
predicted_30_days: int | None
|
|
avg_km_per_day: float | None
|
|
avg_km_per_month: float | None
|
|
current_price_per_liter: float | None = None
|
|
predicted_price_per_liter_30_days: float | None = None
|
|
avg_price_per_liter: float | None = None
|
|
price_samples: int = 0
|
|
price_confidence: float = 0
|
|
confidence: float
|
|
insight: str
|