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

89 lines
3.2 KiB
Python

"""Routes C3 — Anniversaires district 87-16."""
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 district"])
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_district(
prochains_jours: int = 90,
membre=Depends(get_current_membre),
db: AsyncSession = Depends(get_db),
):
"""C3 — Anniversaires de sobriété de tous les groupes du district 87-16."""
aujourdhui = date.today()
# Récupérer le district du groupe du membre
groupe = await db.get(Groupe, membre.groupe_id)
district = groupe.district if groupe else "87-16"
# Tous les membres actifs du district ayant une date d'abstinence
result = await db.execute(
select(Membre, Groupe.nom)
.join(Groupe, Membre.groupe_id == Groupe.id)
.where(
Groupe.district == district,
Membre.actif == True,
Membre.date_abstinence.isnot(None),
)
)
rows = result.all()
anniversaires = []
for m, groupe_nom in rows:
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