111 lines
3.7 KiB
Python
111 lines
3.7 KiB
Python
|
|
"""Routes C5 — Décisions en cours."""
|
||
|
|
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, require_executif
|
||
|
|
from app.models.decision import Decision
|
||
|
|
from app.models.membre import Membre
|
||
|
|
from app.schemas.phase2 import DecisionCreate, DecisionOut, DecisionUpdate
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/decisions", tags=["C5 — Décisions en cours"])
|
||
|
|
|
||
|
|
|
||
|
|
async def _to_out(d: Decision, db: AsyncSession) -> DecisionOut:
|
||
|
|
resp = await db.get(Membre, d.responsable_id) if d.responsable_id else None
|
||
|
|
return DecisionOut(
|
||
|
|
id=d.id,
|
||
|
|
sujet=d.sujet,
|
||
|
|
description=d.description,
|
||
|
|
statut=d.statut,
|
||
|
|
responsable_prenom=resp.prenom if resp else None,
|
||
|
|
proposeur=d.proposeur,
|
||
|
|
secondeur=d.secondeur,
|
||
|
|
date_decision=d.date_decision,
|
||
|
|
date_completion=d.date_completion,
|
||
|
|
cree_le=d.cree_le,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/", response_model=list[DecisionOut])
|
||
|
|
async def liste_decisions(
|
||
|
|
statut: str | None = None,
|
||
|
|
limite: int = 50,
|
||
|
|
membre=Depends(get_current_membre),
|
||
|
|
db: AsyncSession = Depends(get_db),
|
||
|
|
):
|
||
|
|
"""C5 — Lister les décisions du groupe avec filtre optionnel par statut."""
|
||
|
|
query = select(Decision).where(Decision.groupe_id == membre.groupe_id)
|
||
|
|
if statut:
|
||
|
|
query = query.where(Decision.statut == statut)
|
||
|
|
query = query.order_by(desc(Decision.date_decision)).limit(limite)
|
||
|
|
result = await db.execute(query)
|
||
|
|
return [await _to_out(d, db) for d in result.scalars().all()]
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/compteur")
|
||
|
|
async def compteur_decisions(
|
||
|
|
membre=Depends(get_current_membre),
|
||
|
|
db: AsyncSession = Depends(get_db),
|
||
|
|
):
|
||
|
|
"""Nombre de décisions ouvertes (pour le badge sur la tuile)."""
|
||
|
|
result = await db.execute(
|
||
|
|
select(Decision).where(
|
||
|
|
Decision.groupe_id == membre.groupe_id,
|
||
|
|
Decision.statut.in_(["en_attente", "en_cours"]),
|
||
|
|
)
|
||
|
|
)
|
||
|
|
return {"ouvertes": len(result.scalars().all())}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/", response_model=DecisionOut)
|
||
|
|
async def creer_decision(
|
||
|
|
req: DecisionCreate,
|
||
|
|
executif=Depends(require_executif),
|
||
|
|
db: AsyncSession = Depends(get_db),
|
||
|
|
):
|
||
|
|
"""Créer une décision (exécutif — typiquement via le PV)."""
|
||
|
|
decision = Decision(
|
||
|
|
groupe_id=executif.groupe_id,
|
||
|
|
reunion_id=req.reunion_id,
|
||
|
|
sujet=req.sujet.strip(),
|
||
|
|
description=req.description,
|
||
|
|
statut=req.statut,
|
||
|
|
responsable_id=req.responsable_id,
|
||
|
|
proposeur=req.proposeur,
|
||
|
|
secondeur=req.secondeur,
|
||
|
|
date_decision=req.date_decision,
|
||
|
|
cree_par=executif.id,
|
||
|
|
)
|
||
|
|
db.add(decision)
|
||
|
|
await db.flush()
|
||
|
|
return await _to_out(decision, db)
|
||
|
|
|
||
|
|
|
||
|
|
@router.patch("/{decision_id}", response_model=DecisionOut)
|
||
|
|
async def modifier_decision(
|
||
|
|
decision_id: str,
|
||
|
|
req: DecisionUpdate,
|
||
|
|
executif=Depends(require_executif),
|
||
|
|
db: AsyncSession = Depends(get_db),
|
||
|
|
):
|
||
|
|
"""Modifier le statut d'une décision (exécutif)."""
|
||
|
|
result = await db.execute(
|
||
|
|
select(Decision).where(Decision.id == decision_id, Decision.groupe_id == executif.groupe_id)
|
||
|
|
)
|
||
|
|
decision = result.scalar_one_or_none()
|
||
|
|
if not decision:
|
||
|
|
raise HTTPException(status_code=404, detail="Décision introuvable")
|
||
|
|
|
||
|
|
if req.statut is not None:
|
||
|
|
decision.statut = req.statut
|
||
|
|
if req.description is not None:
|
||
|
|
decision.description = req.description
|
||
|
|
if req.responsable_id is not None:
|
||
|
|
decision.responsable_id = req.responsable_id
|
||
|
|
if req.date_completion is not None:
|
||
|
|
decision.date_completion = req.date_completion
|
||
|
|
await db.flush()
|
||
|
|
return await _to_out(decision, db)
|