125 lines
4 KiB
Python
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"}
|