"""Routes M6 — Commander des jetons.""" from datetime import date, timedelta from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from app.core.database import get_db from app.core.security import get_current_membre, is_sysadmin from app.core.roles import membre_a_module from app.models.vente_jeton import VenteJeton from app.models.affectation import Affectation from app.models.poste import Poste from app.schemas.phase5 import StockJetonsOut, TYPES_JETONS from fastapi import HTTPException router = APIRouter(prefix="/commandes-jetons", tags=["M6 — Commander jetons"]) async def require_resp_jetons(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): """Vérifie que le membre est responsable des jetons.""" if is_sysadmin(membre) or await membre_a_module(membre.id, "M6", db): return membre result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, Affectation.groupe_id == membre.groupe_id, Affectation.statut == "actif", Poste.groupe_id == membre.groupe_id, Poste.nom.ilike("%jeton%"), ) ) if not result.scalars().first(): raise HTTPException(status_code=403, detail="Réservé au responsable des jetons") return membre @router.get("/stock", response_model=list[StockJetonsOut]) async def etat_stock_jetons( membre=Depends(require_resp_jetons), db: AsyncSession = Depends(get_db), ): """M6 — État du stock de jetons (basé sur les ventes, pas les remises).""" il_y_a_30_jours = date.today() - timedelta(days=30) # Compter les jetons vendus par type dans les 30 derniers jours. # Les remises sont statistiques et ne décrémentent pas l'inventaire. result = await db.execute( select(VenteJeton.type_jeton, func.coalesce(func.sum(VenteJeton.quantite), 0)) .where( VenteJeton.groupe_id == membre.groupe_id, VenteJeton.date_vente >= il_y_a_30_jours, ) .group_by(VenteJeton.type_jeton) ) usage = {row[0]: row[1] for row in result.all()} stock = [] for t in TYPES_JETONS: remis = usage.get(t["value"], 0) # Suggestion simple : si plus de 2 remis dans le mois, suggérer commande suggestion = "Bas — commander" if remis >= 2 else "OK" # Le jeton de désir est toujours à surveiller (remis chaque semaine) if t["value"] == "desir" and remis >= 4: suggestion = "Bas — commander" stock.append(StockJetonsOut( type_jeton=t["value"], label=f"{t['emoji']} {t['label']}", remis_dernier_mois=remis, stock_suggestion=suggestion, )) return stock