gsparc-mezzouna-api/app/routes/fuel.py

88 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Routes — approvisionnements en carburant."""
from fastapi import APIRouter, Depends, Request, Form, UploadFile, File
from fastapi.responses import HTMLResponse, RedirectResponse
from app.auth import require_auth
from app.baserow import list_rows, create_row, update_row, get_row
from app.templates import templates
from app.config import TABLE_VEHICULES, TABLE_APPROVISIONNEMENTS, TABLE_ANOMALIES
from app.business import calculer_kilometrage, calculer_consommation, detecter_anomalies
from app.ocr import extract_text, parse_receipt_ocr
router = APIRouter(prefix="/fuel")
@router.get("/", response_class=HTMLResponse)
async def formulaire(request: Request, user=Depends(require_auth)):
vehicules = await list_rows(TABLE_VEHICULES)
appros = await list_rows(TABLE_APPROVISIONNEMENTS, size=50)
return templates.TemplateResponse("fuel_form.html", {
"request": request,
"vehicules": vehicules,
"appros": appros,
})
@router.post("/add")
async def ajouter_approvisionnement(
request: Request,
matricule: str = Form(...),
date: str = Form(...),
produit: str = Form("Gasoual Normal"),
quantite: float = Form(...),
prix_litre: float = Form(...),
valeur: float = Form(...),
compteur_avant: float = Form(None),
compteur_apres: float = Form(None),
no_recu: str = Form(""),
user=Depends(require_auth),
):
# Calcul automatique
km_parcouru = calculer_kilometrage(compteur_avant or 0, compteur_apres or 0)
conso_100 = calculer_consommation(quantite, km_parcouru) if km_parcouru > 0 else None
data = {
"التاريخ": date,
"رقم_الماتريكول": matricule,
"المنتج": produit,
"الكمية_باللتر": quantite,
"السعر_الليتر": prix_litre,
"القيمة_الجملية": valeur,
"العداد_قبل": compteur_avant,
"العداد_بعد": compteur_apres,
"الكلم_المقطوع": km_parcouru,
"الاستهلاك_100كم": conso_100,
"رقم_الايصال": no_recu,
}
# Détection d'anomalies
appro_precedents = await list_rows(TABLE_APPROVISIONNEMENTS, size=100)
dernier = next((a for a in appro_precedents if a.get("رقم_الماتريكول") == matricule), None)
codes = detecter_anomalies(data, dernier)
if codes:
data["شذوذ"] = True
data["نوع_الشذوذ"] = ", ".join(codes)
await create_row(TABLE_APPROVISIONNEMENTS, data)
return RedirectResponse(url="/fuel", status_code=303)
@router.post("/ocr-upload")
async def upload_recu_ocr(
request: Request,
file: UploadFile = File(...),
user=Depends(require_auth),
):
"""Upload d'un reçu + OCR automatique."""
content = await file.read()
text = await extract_text(content, file.filename or "receipt.jpg")
parsed = parse_receipt_ocr(text)
vehicules = await list_rows(TABLE_VEHICULES)
return templates.TemplateResponse("fuel_form.html", {
"request": request,
"vehicules": vehicules,
"appros": [],
"ocr_text": text,
"ocr_parsed": parsed,
})