"""Routes S2 — Remise de jeton.""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db from app.core.security import get_current_membre from app.models.jeton import Jeton from app.models.membre import Membre from app.models.affectation import Affectation from app.models.poste import Poste from app.schemas.phase5 import JetonCreate, JetonOut, TYPES_JETONS router = APIRouter(prefix="/jetons", tags=["S2 — Remise de jeton"]) async def require_resp_jetons(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): """Vérifie que le membre est responsable des jetons.""" result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, Affectation.statut == "actif", Poste.nom.ilike("%jeton%"), ) ) if not result.scalar_one_or_none(): raise HTTPException(status_code=403, detail="Réservé au responsable des jetons") return membre @router.get("/types") async def types_jetons(): """Liste des types de jetons disponibles.""" return TYPES_JETONS @router.post("/", response_model=JetonOut) async def remettre_jeton( req: JetonCreate, membre=Depends(require_resp_jetons), db: AsyncSession = Depends(get_db), ): """S2 — Enregistrer la remise d'un jeton.""" # Validation types_valides = [t["value"] for t in TYPES_JETONS] if req.type_jeton not in types_valides: raise HTTPException(status_code=400, detail=f"Type de jeton invalide. Valeurs: {types_valides}") if req.type_jeton == "multiple" and (not req.annees or req.annees < 2): raise HTTPException(status_code=400, detail="Le nombre d'années est requis (≥ 2) pour un jeton multiple") # Vérifier que le membre existe si spécifié membre_prenom = None if req.membre_id: cible = await db.get(Membre, req.membre_id) if not cible or not cible.actif: raise HTTPException(status_code=404, detail="Membre introuvable") membre_prenom = cible.prenom jeton = Jeton( groupe_id=membre.groupe_id, membre_id=req.membre_id, type_jeton=req.type_jeton, date_remise=req.date_remise, annees=req.annees if req.type_jeton == "multiple" else None, remis_par=membre.id, ) db.add(jeton) await db.flush() return JetonOut( id=jeton.id, membre_prenom=membre_prenom, type_jeton=jeton.type_jeton, date_remise=jeton.date_remise, annees=jeton.annees, remis_par_prenom=membre.prenom, cree_le=jeton.cree_le, ) @router.get("/", response_model=list[JetonOut]) async def liste_jetons( limite: int = 30, membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db), ): """Lister les jetons remis récemment (tout le groupe).""" result = await db.execute( select(Jeton) .where(Jeton.groupe_id == membre.groupe_id) .order_by(desc(Jeton.date_remise)) .limit(limite) ) jetons = result.scalars().all() out = [] for j in jetons: m = await db.get(Membre, j.membre_id) if j.membre_id else None r = await db.get(Membre, j.remis_par) if j.remis_par else None out.append(JetonOut( id=j.id, membre_prenom=m.prenom if m else None, type_jeton=j.type_jeton, date_remise=j.date_remise, annees=j.annees, remis_par_prenom=r.prenom if r else None, cree_le=j.cree_le, )) return out