Project

General

Profile

Actions

Feature #82

closed
CD

Améliorer la génération de PDF pour les contrats avec design professionnel et signatures configurables

Feature #82: Améliorer la génération de PDF pour les contrats avec design professionnel et signatures configurables

Added by Client Dashboard about 2 months ago. Updated about 1 month ago.

Status:
Shipped
Priority:
Normal
Assignee:
-
Start date:
06/15/2026
Due date:
% Done:

100%

Estimated time:
(Total: 0:00 h)
spec_ref:

ÉPIC découpé (PO : sous-tâche backend éclatée en 3). Génération PDF contrats pro + signatures configurables. Sous-tâches : #90 Backend moteur de rendu (police, logo, marges 2cm, schéma réglages) [socle] ; #91 Backend signatures configurables + mentions [dép. #90] ; #92 Backend numéro unique (séquence Postgres) + enregistrement/téléchargement/email après contre-signature [dép. #90] ; #93 Frontend config modèle (police/logo/emplacement) [partage le schéma #90, design requis] ; #94 Frontend avertissement balises manquantes [indépendant]. Entité Contract : html_template_id, signature_data, internal_signature_id, internal_signed_pdf_url.

build_status:
build_number:
ci_run_url:
scan_status:
scan_report_url:
deploy_status:
deployed
preprod_url:
deployed_at:
06/23/2026
branch:
pr_url:
security_key:
severity:
paused:

Description

### Problème
Actuellement, la génération de PDF des contrats dans l'onglet "Édition de contrat" produit un rendu peu professionnel, basé sur une copie brute de l'HTML. Le design manque de cohérence (polices, marges, alignements) et les signatures ne sont pas intégrées de manière flexible ou esthétique. Cela nuit à l'image professionnelle de l'application et complique le processus de validation des contrats.

### Contexte
- Les utilisateurs sélectionnent un modèle de contrat (créé dans les paramètres avec des balises comme `{{nom_artiste}}`) et remplacent ces balises par les données de l'événement.
- Le PDF généré doit être envoyé via un formulaire sans identification pour validation et signature par le destinataire.
- Les signatures (expéditeur et destinataire) doivent être intégrées automatiquement et positionnées de manière configurable.
- Un numéro de contrat unique doit être généré et affiché dans le PDF pour faciliter le suivi.

### Comportement proposé
1. **Design du PDF** :
- Utiliser la police choisie lors de la création du modèle de contrat.
- Intégrer le logo de la structure (configurable dans les paramètres du modèle) en haut à gauche, avec une ligne de séparation.
- Appliquer des marges de 2 cm et une mise en page soignée (alignements, espacements).

2. **Signatures** :
- Permettre de choisir l'emplacement des signatures (bas à droite, bas à gauche, côte à côte) dans les paramètres du modèle.
- Intégrer automatiquement la signature de l'expéditeur (depuis les paramètres) et celle du destinataire (après signature en ligne) aux emplacements choisis.
- Ajouter des mentions sous les signatures (ex: "Signé par [Nom] le [date]").

3. **Numéro de contrat** :
- Générer un numéro unique (ex: "CONTRAT-2024-001") et l'afficher en pied de page.
- Incrémenter automatiquement ce numéro pour chaque nouveau contrat.

4. **Gestion des erreurs** :
- Afficher un message d'avertissement si une balise est manquante avant génération, avec les options "Ignorer et générer" ou "Corriger".

## Acceptance criteria
- [ ] Le PDF généré respecte la police et la mise en page définies dans le modèle de contrat.
- [ ] Le logo de la structure peut être intégré en haut à gauche du PDF (option configurable dans les paramètres du modèle).
- [ ] Les marges de 2 cm sont appliquées sur tous les côtés du PDF.
- [ ] Les signatures (expéditeur et destinataire) sont intégrées aux emplacements configurables dans les paramètres du modèle.
- [ ] Les mentions "Signé par [Nom] le [date]" sont ajoutées sous chaque signature.
- [ ] Un numéro de contrat unique est généré et affiché en pied de page du PDF.
- [ ] Le numéro de contrat est incrémenté automatiquement pour chaque nouveau contrat.
- [ ] Un message d'avertissement s'affiche si une balise est manquante avant génération, avec les options "Ignorer et générer" ou "Corriger".
- [ ] Le PDF final est enregistré dans l'application et peut être téléchargé après contresignature.
- [ ] Le PDF est envoyé par email au destinataire après contresignature.

## Classification
- feature

## Complexity
- 7/10 — La complexité est modérée en raison de l'intégration de plusieurs fonctionnalités (design PDF, gestion des signatures, numéro de contrat, gestion des erreurs) et de la nécessité de configurer des paramètres flexibles dans les modèles de contrat.


Files

82-apres-contrat-pdf-pro.png (353 KB) 82-apres-contrat-pdf-pro.png Redmine Admin, 06/15/2026 10:27 AM
82-avant-contrat-brut.png (155 KB) 82-avant-contrat-brut.png Redmine Admin, 06/15/2026 10:27 AM
82-maquette-contrat.html (4.79 KB) 82-maquette-contrat.html Redmine Admin, 06/15/2026 10:27 AM
preprod-smoke-dashboard.png (245 KB) preprod-smoke-dashboard.png Redmine Admin, 06/15/2026 11:44 AM
82-apres-contrat-pdf-pro.png
82-avant-contrat-brut.png
preprod-smoke-dashboard.png

Subtasks 7 (0 open7 closed)

Feature #90: Backend — moteur de rendu PDF du contrat (police, logo, marges)Shipped06/15/2026

Actions
Feature #91: Backend — intégration des signatures configurables dans le PDFShipped06/15/2026

Actions
Feature #92: Backend — numéro de contrat unique + enregistrement/téléchargement/envoi emailShipped06/15/2026

Actions
Feature #93: Frontend — configuration de présentation du modèle de contratShipped06/15/2026

Actions
Feature #94: Frontend — avertissement balises manquantes avant générationShipped06/15/2026

Actions
Feature #377: Refonte du rendu PDF contrat : HTML → Chromium (Playwright) + Paged.js (mise en page A4 pro multi-page)Shipped06/15/2026

Actions
Feature #1110: Améliorer le format/design du PDF de contrat (polish visuel, champs vides, identité Le Bijou)Shipped06/15/2026

Actions

RA Updated by Redmine Admin about 2 months ago Actions #1

  • Status changed from Submitted to Spec

Spec en cours (factory). Transition Submitted → Spec.

RA Updated by Redmine Admin about 2 months ago Actions #2

  • Subtask #90 added

RA Updated by Redmine Admin about 2 months ago Actions #3

  • Subtask #91 added

RA Updated by Redmine Admin about 2 months ago Actions #4

  • Subtask #92 added

RA Updated by Redmine Admin about 2 months ago Actions #5

  • Subtask #93 added

RA Updated by Redmine Admin about 2 months ago Actions #6

  • Subtask #94 added

RA Updated by Redmine Admin about 2 months ago Actions #7

  • spec_ref updated (diff)

**Découpage (PO : 5 sous-tâches)** : #90 (rendu PDF, socle), #91 (signatures), #92 (numéro+délivrance), #93 (config modèle — design requis), #94 (avertissement balises). `spec_ref` posé sur l'épic ; pas de `done_ratio` (dérivé des enfants). Passe design prévue pour #93 + maquette du PDF.

RA Updated by Redmine Admin about 2 months ago Actions #11

  • Status changed from Spec to Design

**Design terminé** (factory designer). Transition Spec → Design.

**Maquettes avant/après attachées** : `82-avant-contrat-brut.png` (état actuel — copie HTML brute, reconstruction HTML car l'app live n'était pas accessible) vs `82-apres-contrat-pdf-pro.png` (PDF professionnel proposé) + `82-maquette-contrat.html`. Section ajoutée au design system : `docs/design/design-system.md`.

**Brief (Atomic Design — React/Vite + shadcn/ui, FR inline) :**
- **PDF (serveur pdf-lib, #90/#91/#92)** : en-tête logo haut-gauche + filet, marges 2 cm, corps serif / labels sans-serif, blocs signature à emplacement configurable (bas droite/gauche/côte à côte) avec mention « Signé par [Nom] le [date] », numéro de contrat unique en en-tête + pied de page.
- **UI config modèle (#93, HtmlContractTemplateManager.jsx)** : atoms réutilisés `Select` (police) / upload (logo) / `RadioGroup` (emplacement) ; molecule « Présentation du PDF » ; organism = formulaire de modèle existant.
- **Avertissement balises manquantes (#94)** : `AlertDialog` shadcn listant les `{{balises}}` non substituées, actions « Ignorer et générer » / « Corriger ».
- États : empty (logo absent → placeholder), loading (génération), error (balise manquante → dialog), populated. Aucune nouvelle couleur de marque.

Sous-tâches prêtes pour le dev après design : #90 (socle rendu), #91 (signatures), #92 (numéro + délivrance), #93 (config UI), #94 (avertissement).

RA Updated by Redmine Admin about 2 months ago Actions #12

  • Status changed from Design to QA

**Épic #82 — rollup → QA.** Les 5 sous-tâches sont mergées sur `dev` et en QA : #90 (moteur rendu) · #91 (signatures) · #92 (numéro + délivrance) · #93 (config UI) · #94 (avertissement balises). Tous gates verts. Validation visuelle du PDF (rendu, signatures aux 3 emplacements, logo, numéro) à faire en préprod.

RA Updated by Redmine Admin about 2 months ago Actions #14

**Smoke préprod ✅ (partiel)** — app + auth OK en live (dashboard avec données réelles, capture jointe). L'UI de config du modèle (#93) et l'avertissement balises (#94) sont déployés. **Le rendu PDF lui-même (logo, marges, signatures aux 3 emplacements, numéro) reste à valider en générant un vrai contrat** (nécessite un événement + modèle + données) — à faire lors de la validation fonctionnelle client.

RA Updated by Redmine Admin about 2 months ago Actions #15

**Bugs trouvés en validation préprod du contrat → corrigés & déployés en préprod (build #12).**

1. **Onglet « Édition contrat » bloqué sur un spinner infini** quand l'événement n'a pas encore de contrat (le contrat naît du formulaire de confirmation). → Remplacé par un **état vide actionnable** : « Aucun contrat… allez dans l'onglet Gestion créer le formulaire de confirmation » (plus de spinner trompeur).
2. **413 PayloadTooLargeError** sur **signHtmlContract** (signature dessinée = data-URI base64), génération et téléchargement de PDF. Cause : `main.ts` ne fixait aucune limite de corps → défaut Express 100 kb. → bodyParser à **25mb**. **Vérifié en live** : un corps de 150 kb renvoyait 413, renvoie désormais 201.
3. **Logo en-tête** : il est rendu côté serveur dans le PDF ; il n'apparaissait pas faute de pouvoir générer/télécharger (bloqué par le 413). Maintenant que la génération passe, le logo doit apparaître — **à confirmer visuellement** en téléchargeant un PDF de contrat (validation client).

PR #22 (dev) → #23 (préprod). Gates verts. La validation visuelle finale du PDF (logo, signatures, numéro) reste côté client.

RA Updated by Redmine Admin about 2 months ago Actions #16

  • Subtask #377 added

RA Updated by Redmine Admin about 2 months ago Actions #17

  • Status changed from QA to Preprod

Déployé en préprod (https://preprod-scobby.omdev.tech). Passage QA → Preprod (épic + sous-tâches #90–#94 + refonte #377 livrés).

RA Updated by Redmine Admin about 2 months ago Actions #18

  • Subtask #1110 added

RA Updated by Redmine Admin about 1 month ago Actions #19

  • Status changed from Preprod to Ready to ship

Épopée livrée sur master (dev = preprod = master). Tous les sous-tickets sont sur master : #90 (PR #8/#19), #91 (PR #11), #92 (PR #14), #93 (PR #10), #94 (PR #7). Refonte rendu PDF (#377) également livrée. Passage en **Ready to ship** — à passer en *Shipped* après confirmation du déploiement prod (gate manuel Jenkins) sur scobby.fr.

RA Updated by Redmine Admin about 1 month ago Actions #20

  • deploy_status set to deployed
  • deployed_at set to 06/23/2026

Déploiement PROD confirmé live sur scobby.fr (gate manuel Jenkins approuvé le 2026-06-23). Passage en **Shipped**.

RA Updated by Redmine Admin about 1 month ago Actions #21

Épopée complète : tous les sous-tickets (#90, #91, #92, #93, #94) + refonte #377 livrés en prod. Déploiement PROD confirmé live sur scobby.fr (gate manuel Jenkins approuvé le 2026-06-23). Passage en **Shipped**.

RA Updated by Redmine Admin about 1 month ago Actions #22

Correctif : ce ticket **ne passe pas en Shipped** car il reste un sous-ticket ouvert — **#1110** « Améliorer le format/design du PDF de contrat (polish visuel, champs vides, identité Le Bijou) », encore en *Spec*. 6 des 7 sous-tickets (#90, #91, #92, #93, #94, #377) sont livrés en prod ; l'épopée reste ouverte jusqu'à la livraison de #1110. (Mon message précédent « épopée complète » était inexact.)

RA Updated by Redmine Admin about 1 month ago Actions #23

  • Status changed from Ready to ship to Shipped

Épopée **complète** : les 7 sous-tickets sont livrés en prod (#90, #91, #92, #93, #94, #377 + #1110, dernier sous-ticket clôturé ce jour). Déploiement PROD confirmé live sur scobby.fr (gate manuel Jenkins approuvé le 2026-06-23). Passage en **Shipped**.

Actions

Also available in: PDF Atom