groupe-meditation/backend/app/routers/rotations.py
2026-03-04 14:01:00 -05:00

125 lines
4 KiB
Python

"""Routes G5 — Planifier les rotations hebdomadaires."""
from datetime import date, timedelta
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete
from app.core.database import get_db
from app.core.security import require_executif, get_current_membre
from app.models.rotation import Rotation
from app.models.poste import Poste
from app.models.membre import Membre
from app.schemas.phase3 import RotationCreate, RotationOut
router = APIRouter(prefix="/rotations", tags=["G5 — Rotations"])
async def _to_out(r: Rotation, db: AsyncSession) -> RotationOut:
poste = await db.get(Poste, r.poste_id)
mbr = await db.get(Membre, r.membre_id)
return RotationOut(
id=r.id,
date_reunion=r.date_reunion,
poste_nom=poste.nom if poste else "?",
membre_prenom=mbr.prenom if mbr else "?",
note=r.note,
cree_le=r.cree_le,
)
@router.get("/", response_model=list[RotationOut])
async def liste_rotations(
semaines: int = 4,
membre=Depends(get_current_membre),
db: AsyncSession = Depends(get_db),
):
"""Rotations des prochaines semaines."""
aujourdhui = date.today()
fin = aujourdhui + timedelta(weeks=semaines)
result = await db.execute(
select(Rotation).where(
Rotation.groupe_id == membre.groupe_id,
Rotation.date_reunion >= aujourdhui,
Rotation.date_reunion <= fin,
).order_by(Rotation.date_reunion, Rotation.poste_id)
)
return [await _to_out(r, db) for r in result.scalars().all()]
@router.get("/historique", response_model=list[RotationOut])
async def historique_rotations(
semaines: int = 4,
membre=Depends(get_current_membre),
db: AsyncSession = Depends(get_db),
):
"""Rotations passées."""
aujourdhui = date.today()
debut = aujourdhui - timedelta(weeks=semaines)
result = await db.execute(
select(Rotation).where(
Rotation.groupe_id == membre.groupe_id,
Rotation.date_reunion >= debut,
Rotation.date_reunion < aujourdhui,
).order_by(Rotation.date_reunion.desc())
)
return [await _to_out(r, db) for r in result.scalars().all()]
@router.post("/", response_model=RotationOut)
async def creer_rotation(
req: RotationCreate,
executif=Depends(require_executif),
db: AsyncSession = Depends(get_db),
):
"""G5 — Assigner un serviteur pour une date de réunion."""
rotation = Rotation(
groupe_id=executif.groupe_id,
date_reunion=req.date_reunion,
poste_id=req.poste_id,
membre_id=req.membre_id,
note=req.note,
cree_par=executif.id,
)
db.add(rotation)
await db.flush()
return await _to_out(rotation, db)
@router.post("/batch", response_model=list[RotationOut])
async def creer_rotations_batch(
rotations: list[RotationCreate],
executif=Depends(require_executif),
db: AsyncSession = Depends(get_db),
):
"""G5 — Assigner plusieurs serviteurs d'un coup pour une semaine."""
created = []
for req in rotations:
rotation = Rotation(
groupe_id=executif.groupe_id,
date_reunion=req.date_reunion,
poste_id=req.poste_id,
membre_id=req.membre_id,
note=req.note,
cree_par=executif.id,
)
db.add(rotation)
await db.flush()
created.append(await _to_out(rotation, db))
return created
@router.delete("/{rotation_id}")
async def supprimer_rotation(
rotation_id: str,
executif=Depends(require_executif),
db: AsyncSession = Depends(get_db),
):
"""Supprimer une rotation planifiée."""
result = await db.execute(
select(Rotation).where(Rotation.id == rotation_id, Rotation.groupe_id == executif.groupe_id)
)
rotation = result.scalar_one_or_none()
if not rotation:
raise HTTPException(status_code=404, detail="Rotation introuvable")
await db.delete(rotation)
return {"message": "Rotation supprimée"}