Files
service-finder/backend/app/services/fleet_service.py

40 lines
2.5 KiB
Python
Executable File

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.models.vehicle import UserVehicle
from app.models.expense import VehicleEvent
from app.models.social import ServiceProvider, SourceType, ModerationStatus
from app.schemas.fleet import EventCreate, TCOStats
from app.services.gamification_service import GamificationService
async def add_vehicle_event(db: AsyncSession, vehicle_id: int, event_data: EventCreate, user_id: int):
v_res = await db.execute(select(UserVehicle).where(UserVehicle.id == vehicle_id))
vehicle = v_res.scalars().first()
if not vehicle: return {"error": "Vehicle not found"}
final_provider_id = event_data.provider_id
if event_data.is_diy: final_provider_id = None
elif event_data.provider_name and not final_provider_id:
p_res = await db.execute(select(ServiceProvider).where(func.lower(ServiceProvider.name) == event_data.provider_name.lower()))
existing = p_res.scalars().first()
if existing: final_provider_id = existing.id
else:
new_p = ServiceProvider(name=event_data.provider_name, added_by_user_id=user_id, status=ModerationStatus.pending)
db.add(new_p); await db.flush(); final_provider_id = new_p.id
await GamificationService.award_points(db, user_id, 50, f"Új helyszín: {event_data.provider_name}")
anomaly = event_data.odometer_value < vehicle.current_odometer
new_event = VehicleEvent(vehicle_id=vehicle_id, service_provider_id=final_provider_id, odometer_anomaly=anomaly, **event_data.model_dump(exclude={"provider_id", "provider_name"}))
db.add(new_event)
if event_data.odometer_value > vehicle.current_odometer: vehicle.current_odometer = event_data.odometer_value
await GamificationService.award_points(db, user_id, 20, f"Esemény: {event_data.event_type}")
await db.commit(); await db.refresh(new_event)
return new_event
async def calculate_tco(db: AsyncSession, vehicle_id: int) -> TCOStats:
result = await db.execute(select(VehicleEvent.event_type, func.sum(VehicleEvent.cost_amount)).where(VehicleEvent.vehicle_id == vehicle_id).group_by(VehicleEvent.event_type))
breakdown = {row[0]: row[1] for row in result.all()}
v_res = await db.execute(select(UserVehicle).where(UserVehicle.id == vehicle_id))
v = v_res.scalars().first()
km = (v.current_odometer - v.initial_odometer) if v else 0
cpk = sum(breakdown.values()) / km if km > 0 else 0
return TCOStats(vehicle_id=vehicle_id, total_cost=sum(breakdown.values()), breakdown=breakdown, cost_per_km=round(cpk, 2))