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))