Inscription en deux temps, emails de confirmation et export Excel des bénévoles
Formulaire public — paiement en ligne : - Le bénévole n'est plus compté en base tant qu'un paiement en ligne choisi n'est pas confirmé (PendingFormSubmission, promu en Volunteer à la confirmation, webhook ou vérification en direct). - Type de paiement « mécénat » : étape d'adresse postale avant le paiement, conservée sur le bénévole pour un reçu fiscal (cerfa) ultérieur. - Page de confirmation au retour de SumUp, avec relance possible après échec/expiration sans ressaisir le formulaire. - « Je paierai sur place » remplace « je ne participe pas » ; tous les champs activés par la coordination sont désormais obligatoires. - La fiche bénévole n'affiche plus l'état des cases à cocher, seulement le résultat réel du paiement (libellé, montant, statut). Emails : - Email de confirmation d'inscription à la création du bénévole (tient lieu de reçu de paiement quand une cotisation est payée en ligne). - Mise en forme HTML au thème de l'application (logo de l'édition en en-tête) pour tous les emails envoyés, texte brut conservé en repli. Export Excel des bénévoles (COORDINATION) : coordonnées, vœux résolus en noms lisibles, cotisation et mécénat. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
68d42ee303
commit
a2b748566b
@@ -29,6 +29,7 @@ from app.auth.deps import (
|
||||
require_staff,
|
||||
)
|
||||
from app.db import get_session
|
||||
from app.exporting import generate_volunteers_xlsx
|
||||
from app.models import (
|
||||
Account,
|
||||
Artist,
|
||||
@@ -169,6 +170,56 @@ def list_volunteers(
|
||||
return [_read(session, v) for v in volunteers]
|
||||
|
||||
|
||||
@router.get("/export")
|
||||
def export_volunteers(
|
||||
edition: Edition = Depends(get_edition),
|
||||
_guard: Account = Depends(require_coordinator),
|
||||
session: Session = Depends(get_session),
|
||||
) -> Response:
|
||||
"""Export Excel de la liste des bénévoles — vœux (postes, artistes,
|
||||
compagnons) résolus en noms lisibles, pas en UUID. Déclaré avant
|
||||
`/{volunteer_id}` : un chemin statique doit être enregistré avant le
|
||||
chemin dynamique qui le suivrait sinon FastAPI essaierait de parser
|
||||
« export » comme un UUID."""
|
||||
volunteers_orm = list(
|
||||
session.exec(
|
||||
select(Volunteer)
|
||||
.where(Volunteer.edition_id == edition.id)
|
||||
.order_by(Volunteer.last_name, Volunteer.first_name)
|
||||
)
|
||||
)
|
||||
volunteers = [_read(session, v) for v in volunteers_orm]
|
||||
position_names = {
|
||||
p.id: p.name
|
||||
for p in session.exec(
|
||||
select(Position).where(Position.edition_id == edition.id)
|
||||
)
|
||||
}
|
||||
artist_names = {
|
||||
a.id: a.name
|
||||
for a in session.exec(select(Artist).where(Artist.edition_id == edition.id))
|
||||
}
|
||||
volunteer_names = {
|
||||
v.id: f"{v.first_name} {v.last_name}" for v in volunteers_orm
|
||||
}
|
||||
|
||||
content = generate_volunteers_xlsx(
|
||||
volunteers,
|
||||
position_names=position_names,
|
||||
artist_names=artist_names,
|
||||
volunteer_names=volunteer_names,
|
||||
)
|
||||
return Response(
|
||||
content=content,
|
||||
media_type=(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
),
|
||||
headers={
|
||||
"Content-Disposition": f'attachment; filename="benevoles-{edition.year}.xlsx"'
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{volunteer_id}", response_model=VolunteerRead)
|
||||
def get_volunteer(
|
||||
volunteer_id: uuid.UUID,
|
||||
|
||||
Reference in New Issue
Block a user