97 lines
3.1 KiB
Python
97 lines
3.1 KiB
Python
"""Routes M3 — Rapport du RSG."""
|
|
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, is_sysadmin
|
|
from app.models.rapport_rsg import RapportRsg
|
|
from app.models.membre import Membre
|
|
from app.models.affectation import Affectation
|
|
from app.models.poste import Poste
|
|
from app.schemas.phase4 import RapportRsgCreate, RapportRsgOut
|
|
|
|
router = APIRouter(prefix="/rapports-rsg", tags=["M3 — Rapport RSG"])
|
|
|
|
|
|
async def require_rsg(membre=Depends(get_current_membre), db=Depends(get_db)):
|
|
"""Vérifie que le membre est RSG, RSG substitut ou exécutif."""
|
|
if is_sysadmin(membre):
|
|
return membre
|
|
result = await db.execute(
|
|
select(Affectation).join(Poste).where(
|
|
Affectation.membre_id == membre.id,
|
|
Affectation.statut == "actif",
|
|
(Poste.nom.ilike("%RSG%") | (Poste.categorie == "executif")),
|
|
)
|
|
)
|
|
if not result.scalars().first():
|
|
raise HTTPException(status_code=403, detail="Réservé au RSG ou à l'exécutif")
|
|
return membre
|
|
|
|
|
|
async def _to_out(r: RapportRsg, db: AsyncSession) -> RapportRsgOut:
|
|
redacteur = await db.get(Membre, r.redacteur_id)
|
|
return RapportRsgOut(
|
|
id=r.id,
|
|
reunion_dist=r.reunion_dist,
|
|
redacteur_prenom=redacteur.prenom if redacteur else "?",
|
|
decisions=r.decisions,
|
|
infos_region=r.infos_region,
|
|
sujets_groupe=r.sujets_groupe,
|
|
cree_le=r.cree_le,
|
|
)
|
|
|
|
|
|
@router.get("/", response_model=list[RapportRsgOut])
|
|
async def liste_rapports_rsg(
|
|
limite: int = 12,
|
|
membre=Depends(get_current_membre),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
"""Lister les rapports RSG du groupe."""
|
|
result = await db.execute(
|
|
select(RapportRsg)
|
|
.where(RapportRsg.groupe_id == membre.groupe_id)
|
|
.order_by(desc(RapportRsg.reunion_dist))
|
|
.limit(limite)
|
|
)
|
|
return [await _to_out(r, db) for r in result.scalars().all()]
|
|
|
|
|
|
@router.post("/", response_model=RapportRsgOut)
|
|
async def creer_rapport_rsg(
|
|
req: RapportRsgCreate,
|
|
membre=Depends(require_rsg),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
"""M3 — Rédiger un rapport de réunion de district."""
|
|
rapport = RapportRsg(
|
|
groupe_id=membre.groupe_id,
|
|
reunion_dist=req.reunion_dist,
|
|
redacteur_id=membre.id,
|
|
decisions=req.decisions,
|
|
infos_region=req.infos_region,
|
|
sujets_groupe=req.sujets_groupe,
|
|
)
|
|
db.add(rapport)
|
|
await db.flush()
|
|
return await _to_out(rapport, db)
|
|
|
|
|
|
@router.get("/{rapport_id}", response_model=RapportRsgOut)
|
|
async def detail_rapport_rsg(
|
|
rapport_id: str,
|
|
membre=Depends(get_current_membre),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
result = await db.execute(
|
|
select(RapportRsg).where(
|
|
RapportRsg.id == rapport_id,
|
|
RapportRsg.groupe_id == membre.groupe_id,
|
|
)
|
|
)
|
|
rapport = result.scalar_one_or_none()
|
|
if not rapport:
|
|
raise HTTPException(status_code=404, detail="Rapport introuvable")
|
|
return await _to_out(rapport, db)
|