89 lines
3.2 KiB
Python
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
|