54 lines
2.6 KiB
Python
Executable File
54 lines
2.6 KiB
Python
Executable File
# /opt/docker/dev/service_finder/backend/app/services/fleet_service.py
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, func
|
|
from uuid import UUID
|
|
from app.models.asset import Asset, AssetEvent, AssetCost
|
|
from app.models.social import ServiceProvider, ModerationStatus
|
|
from app.schemas.fleet import EventCreate, TCOStats
|
|
from app.services.gamification_service import gamification_service
|
|
|
|
class FleetService:
|
|
@staticmethod
|
|
async def add_vehicle_event(db: AsyncSession, asset_id: UUID, event_data: EventCreate, user_id: int):
|
|
""" Esemény (szerviz/tankolás) rögzítése a Digitális Iker történetébe. """
|
|
res = await db.execute(select(Asset).where(Asset.id == asset_id))
|
|
asset = res.scalar_one_or_none()
|
|
if not asset: return None
|
|
|
|
# Szolgáltató kezelés
|
|
provider_id = event_data.provider_id
|
|
if not event_data.is_diy and event_data.provider_name and not provider_id:
|
|
p_stmt = select(ServiceProvider).where(func.lower(ServiceProvider.name) == event_data.provider_name.lower())
|
|
existing = (await db.execute(p_stmt)).scalar_one_or_none()
|
|
if existing: 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(); provider_id = new_p.id
|
|
|
|
# Esemény és Telemetria frissítés
|
|
anomaly = event_data.odometer_value < (asset.telemetry.current_mileage if asset.telemetry else 0)
|
|
new_event = AssetEvent(
|
|
asset_id=asset_id,
|
|
event_type=event_data.event_type,
|
|
recorded_mileage=event_data.odometer_value,
|
|
data=event_data.model_dump(exclude={"provider_id", "provider_name"})
|
|
)
|
|
db.add(new_event)
|
|
|
|
# Gamifikáció hívása
|
|
await gamification_service.process_activity(db, user_id, 20, 5, f"Asset Event: {event_data.event_type}")
|
|
|
|
await db.commit()
|
|
return new_event
|
|
|
|
@staticmethod
|
|
async def calculate_tco(db: AsyncSession, asset_id: UUID) -> TCOStats:
|
|
""" TCO számítás az AssetCost tábla alapján. """
|
|
result = await db.execute(
|
|
select(AssetCost.cost_type, func.sum(AssetCost.amount_local))
|
|
.where(AssetCost.asset_id == asset_id)
|
|
.group_by(AssetCost.cost_type)
|
|
)
|
|
breakdown = {row[0]: float(row[1]) for row in result.all()}
|
|
total = sum(breakdown.values())
|
|
return TCOStats(asset_id=asset_id, total_cost_huf=total, cost_per_km=0.0) # KM logika az asset.telemetry-ből |