Numéro d'ordre unique sur chaque reçu fiscal mécénat

Volunteer.mecenat_receipt_number (migration 0020, unique) : année du
paiement + rang sur 5 chiffres (202600001…), une seule numérotation pour
toutes les éditions, repartant à 1 chaque année. Attribué à la
confirmation du paiement, ou au premier export pour les bénévoles payés
avant (dans l'ordre des paiements), puis jamais réattribué — un reçu
regénéré garde son numéro. Attribution sérialisée par un verrou
pg_advisory_xact_lock (webhook et sondage peuvent confirmer deux
paiements à la fois). Imprimé centré dans la case « Numéro d'ordre du
reçu » en page 1 du cerfa.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-10-03 13:48:05 +02:00
co-authored by Claude Opus 5.5
parent 5a0209ce43
commit ccd769d04e
10 changed files with 214 additions and 16 deletions
+9 -1
View File
@@ -30,7 +30,7 @@ from app.auth.deps import (
)
from app.db import get_session
from app.exporting import generate_volunteers_xlsx
from app.mecenat import generate_mecenat_receipts_pdf, receipt_for
from app.mecenat import assign_receipt_number, generate_mecenat_receipts_pdf, receipt_for
from app.models import (
Account,
Artist,
@@ -247,6 +247,14 @@ def export_mecenat_receipts(
status_code=422, detail={"code": "mecenat.no_receipts"}
)
# Bénévoles payés avant la numérotation (ou jamais exportés) : numéro
# attribué maintenant, dans l'ordre des paiements, puis figé.
unnumbered = [v for v in volunteers if not v.mecenat_receipt_number]
if unnumbered:
for v in sorted(unnumbered, key=lambda v: v.fee_paid_at or v.created_at):
assign_receipt_number(session, v)
session.commit()
receipts = [receipt_for(v) for v in volunteers]
content = generate_mecenat_receipts_pdf(receipts)
return Response(