"""Routes C3 — Anniversaires du groupe.""" from datetime import date, timedelta from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.core.database import get_db from app.core.security import get_current_membre from app.models.membre import Membre from app.models.groupe import Groupe from app.schemas.phase5 import AnniversaireOut router = APIRouter(prefix="/anniversaires", tags=["C3 — Anniversaires"]) def _calcul_anniversaire(date_abstinence: date, aujourdhui: date) -> tuple[int, date, int]: """Calcule les années de sobriété, le prochain anniversaire et les jours restants.""" annees = aujourdhui.year - date_abstinence.year # Anniversaire cette année try: anniv_cette_annee = date_abstinence.replace(year=aujourdhui.year) except ValueError: # 29 février anniv_cette_annee = date(aujourdhui.year, 3, 1) if anniv_cette_annee < aujourdhui: # L'anniversaire de cette année est passé try: prochain = date_abstinence.replace(year=aujourdhui.year + 1) except ValueError: prochain = date(aujourdhui.year + 1, 3, 1) annees_sobriete = annees elif anniv_cette_annee == aujourdhui: prochain = anniv_cette_annee annees_sobriete = annees else: prochain = anniv_cette_annee annees_sobriete = annees - 1 # Minimum 0 annees_sobriete = max(0, annees_sobriete) jours_restants = (prochain - aujourdhui).days return annees_sobriete, prochain, jours_restants @router.get("/", response_model=list[AnniversaireOut]) async def anniversaires_groupe( prochains_jours: int = 90, membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db), ): """C3 — Anniversaires de sobriété du groupe courant.""" aujourdhui = date.today() groupe = await db.get(Groupe, membre.groupe_id) if not groupe: return [] result = await db.execute( select(Membre) .where( Membre.groupe_id == membre.groupe_id, Membre.actif == True, Membre.date_abstinence.isnot(None), ) ) anniversaires = [] for m in result.scalars().all(): annees_sobriete, prochain, jours_restants = _calcul_anniversaire(m.date_abstinence, aujourdhui) # Filtrer : prochains X jours OU anniversaire aujourd'hui if 0 <= jours_restants <= prochains_jours: anniversaires.append(AnniversaireOut( membre_prenom=m.prenom, groupe_nom=groupe.nom, date_abstinence=m.date_abstinence, annees_sobriete=annees_sobriete + 1, # prochain anniversaire = +1 prochain_anniversaire=prochain, jours_restants=jours_restants, )) # Trier par jours restants (prochains en premier) anniversaires.sort(key=lambda a: a.jours_restants) return anniversaires