Files
benevoles/backend/app/email/templates.py
T
AdamThomasandClaude Opus 5.5 5a0209ce43 Cerfa mécénat rempli envoyé par email à la confirmation du paiement
Quand un paiement « mécénat » est confirmé, l'email de confirmation porte
en pièce jointe le reçu fiscal (cerfa 11580*05) rempli du bénévole, avec
une phrase l'annonçant dans le corps. Généré en tâche de fond : un échec
de génération envoie l'email sans pièce jointe plutôt que rien.

- build_message/send acceptent des pièces jointes
- app/mecenat/receipts.py : passage Volunteer → MecenatReceipt, partagé
  avec l'export coordination
- modèle cerfa remplacé par une version pré-remplie avec l'association
  (organisme bénéficiaire, cases 200/978, signature) ; position de la
  date du versement ajustée

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 13:47:45 +02:00

81 lines
2.5 KiB
Python

"""Rendu des emails. Les textes vivent dans `locales/fr.json` (`email.*`)."""
from app.i18n import t
# Variables autorisées dans un modèle d'email de planning saisi par la
# coordination.
_PLANNING_PLACEHOLDERS = (
"prenom",
"nom",
"nb_creneaux",
"nb_heures",
"creneaux",
"lien_connexion",
)
def render_magic_link(*, link: str, minutes: int) -> tuple[str, str]:
return (
t("email.magic_link.subject"),
t("email.magic_link.body", link=link, minutes=minutes),
)
def render_registration_confirmation(*, first_name: str) -> tuple[str, str]:
"""Inscription prise en compte, sans paiement en ligne (case désactivée,
ou « je paierai sur place ») — voir `render_registration_paid_confirmation`
pour le cas d'un paiement confirmé."""
return (
t("email.registration_confirmation.subject"),
t("email.registration_confirmation.body", prenom=first_name),
)
def render_registration_paid_confirmation(
*, first_name: str, label: str, amount: float, with_mecenat_receipt: bool = False
) -> tuple[str, str]:
"""Inscription prise en compte **et** paiement en ligne confirmé — envoyé
une fois seulement, au moment de la promotion (`app/api/forms.py:
_promote_pending`). Sert de reçu (montant, type de paiement) en
l'absence de confirmation documentée que l'API SumUp Hosted Checkout en
envoie un elle-même. `with_mecenat_receipt` : le cerfa rempli est joint
(`_promote_pending`), le corps l'annonce."""
body = t(
"email.registration_confirmation_paid.body",
prenom=first_name,
label=label,
montant=amount,
)
if with_mecenat_receipt:
body += "\n\n" + t("email.registration_confirmation_paid.mecenat_receipt_note")
return t("email.registration_confirmation_paid.subject"), body
def _fill(template: str, values: dict[str, object]) -> str:
out = template
for key in _PLANNING_PLACEHOLDERS:
out = out.replace("{" + key + "}", str(values.get(key, "")))
return out
def render_planning(
*,
subject_template: str,
body_template: str,
first_name: str,
last_name: str,
shift_count: int,
hours: float,
shifts_text: str,
login_link: str,
) -> tuple[str, str]:
values: dict[str, object] = {
"prenom": first_name,
"nom": last_name,
"nb_creneaux": shift_count,
"nb_heures": hours,
"creneaux": shifts_text,
"lien_connexion": login_link,
}
return _fill(subject_template, values), _fill(body_template, values)