Initial commit: Robot ökoszisztéma v2.0 - Stabilizált jármű és szerviz robotok
This commit is contained in:
114
code-server-config/data/User/History/6ca6cf1a/ZFcJ.py
Executable file
114
code-server-config/data/User/History/6ca6cf1a/ZFcJ.py
Executable file
@@ -0,0 +1,114 @@
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func, desc
|
||||
from app.models.vehicle import Vehicle
|
||||
from app.models.expense import VehicleEvent, ExpenseCategory
|
||||
from app.models.social import ServiceProvider, SourceType, ModerationStatus
|
||||
from app.schemas.fleet import EventCreate, TCOStats
|
||||
|
||||
async def add_vehicle_event(db: AsyncSession, vehicle_id: int, event_data: EventCreate, user_id: int):
|
||||
"""
|
||||
Összetett logika esemény rögzítésére:
|
||||
1. Provider kezelés (DIY vs Existing vs New Ad-Hoc)
|
||||
2. Odometer integritás ellenőrzés
|
||||
3. Mentés és Jármű frissítés
|
||||
"""
|
||||
|
||||
# 1. Jármű ellenőrzése
|
||||
vehicle_res = await db.execute(select(Vehicle).where(Vehicle.id == vehicle_id))
|
||||
vehicle = vehicle_res.scalars().first()
|
||||
if not vehicle:
|
||||
return {"error": "Vehicle not found"}
|
||||
|
||||
# 2. Provider Logika
|
||||
final_provider_id = event_data.provider_id
|
||||
|
||||
if event_data.is_diy:
|
||||
# Ha DIY, akkor nincs provider
|
||||
final_provider_id = None
|
||||
if not event_data.description:
|
||||
event_data.description = "Saját javítás (DIY)"
|
||||
|
||||
elif event_data.provider_name and not final_provider_id:
|
||||
# Ha nevet kaptunk, de ID-t nem -> Keresés vagy Létrehozás
|
||||
# Megpróbáljuk megkeresni név alapján (case insensitive)
|
||||
provider_res = await db.execute(select(ServiceProvider).where(func.lower(ServiceProvider.name) == event_data.provider_name.lower()))
|
||||
existing_provider = provider_res.scalars().first()
|
||||
|
||||
if existing_provider:
|
||||
final_provider_id = existing_provider.id
|
||||
else:
|
||||
# Nem létezik -> Létrehozunk egy "Fantom" szolgáltatót
|
||||
new_provider = ServiceProvider(
|
||||
name=event_data.provider_name,
|
||||
address="Unknown (User Generated)",
|
||||
status=ModerationStatus.pending, # Ellenőrzésre vár
|
||||
source=SourceType.manual,
|
||||
added_by_user_id=user_id
|
||||
)
|
||||
db.add(new_provider)
|
||||
await db.flush() # Hogy kapjunk ID-t
|
||||
final_provider_id = new_provider.id
|
||||
print(f"--- INFO: Created Ad-Hoc Provider: {event_data.provider_name} (ID: {final_provider_id})")
|
||||
|
||||
# 3. Odometer Logika (Biztonság)
|
||||
anomaly_detected = False
|
||||
|
||||
if event_data.odometer_value < vehicle.current_odometer:
|
||||
# Figyelmeztetés: Csökkent a kilométerállás!
|
||||
anomaly_detected = True
|
||||
print(f"--- WARN: Odometer rollback detected for Vehicle {vehicle_id}!")
|
||||
|
||||
# 4. Esemény mentése
|
||||
new_event = VehicleEvent(
|
||||
vehicle_id=vehicle_id,
|
||||
event_type=event_data.event_type,
|
||||
date=event_data.date,
|
||||
odometer_value=event_data.odometer_value,
|
||||
odometer_anomaly=anomaly_detected,
|
||||
cost_amount=event_data.cost_amount,
|
||||
description=event_data.description,
|
||||
is_diy=event_data.is_diy,
|
||||
service_provider_id=final_provider_id
|
||||
)
|
||||
|
||||
db.add(new_event)
|
||||
|
||||
# 5. Jármű frissítése (Ha nőtt a km, update-eljük a current-et)
|
||||
if event_data.odometer_value > vehicle.current_odometer:
|
||||
vehicle.current_odometer = event_data.odometer_value
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(new_event)
|
||||
return new_event
|
||||
|
||||
async def calculate_tco(db: AsyncSession, vehicle_id: int) -> TCOStats:
|
||||
"""Teljes költség elemzés (TCO)"""
|
||||
|
||||
# Költségek lekérése kategóriánként
|
||||
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()}
|
||||
total_cost = sum(breakdown.values())
|
||||
|
||||
# Km futás számítás
|
||||
vehicle_res = await db.execute(select(Vehicle).where(Vehicle.id == vehicle_id))
|
||||
vehicle = vehicle_res.scalars().first()
|
||||
|
||||
km_driven = 0
|
||||
cost_per_km = 0.0
|
||||
|
||||
if vehicle:
|
||||
km_driven = max(0, vehicle.current_odometer - vehicle.initial_odometer)
|
||||
if km_driven > 0:
|
||||
cost_per_km = total_cost / km_driven
|
||||
|
||||
return TCOStats(
|
||||
vehicle_id=vehicle_id,
|
||||
total_cost=total_cost,
|
||||
breakdown=breakdown,
|
||||
cost_per_km=round(cost_per_km, 2)
|
||||
)
|
||||
Reference in New Issue
Block a user