From 672494ccc0d2f352aa16234384e8f59ffdf7821b Mon Sep 17 00:00:00 2001 From: Manus Date: Mon, 9 Feb 2026 11:53:03 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20Int=C3=A9gration=20des=20signatur?= =?UTF-8?q?es=20formateurs=20dans=20la=20feuille=20de=20pr=C3=A9sence=20PD?= =?UTF-8?q?F=20-=20Les=20signatures=20tactiles=20des=20formateurs=20(matin?= =?UTF-8?q?=20et=20apr=C3=A8s-midi)=20sont=20maintenant=20affich=C3=A9es?= =?UTF-8?q?=20dans=20la=20section=20d=C3=A9di=C3=A9e=20de=20la=20feuille?= =?UTF-8?q?=20de=20pr=C3=A9sence=20au=20lieu=20des=20lignes=20vides?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/exportService.ts | 51 +++++++++++++++++++++++++++++++++++++++-- server/routers.ts | 8 ++++++- todo.md | 9 ++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/server/exportService.ts b/server/exportService.ts index 22a1a10..387dee6 100644 --- a/server/exportService.ts +++ b/server/exportService.ts @@ -47,6 +47,11 @@ interface FeuillePresenceInfo { publicCible: string; formateur?: string; apprenants: ApprenantPresence[]; + signaturesFormateurs?: Array<{ + dateFormationId: number; + periode: 'matin' | 'apres_midi'; + signatureUrl: string | null; + }>; } /** @@ -301,14 +306,56 @@ export function generateFeuillePresence(feuilleInfo: FeuillePresenceInfo): Buffe doc.text('Signatures du formateur :', 14, signatureY); doc.setFont('helvetica', 'normal'); + // Récupérer les signatures formateurs pour cette date + const signatureMatin = feuilleInfo.signaturesFormateurs?.find( + s => s.dateFormationId === dateInfo.id && s.periode === 'matin' + ); + const signatureApresMidi = feuilleInfo.signaturesFormateurs?.find( + s => s.dateFormationId === dateInfo.id && s.periode === 'apres_midi' + ); + // Signature Matin doc.setFontSize(9); doc.text('Matin :', 14, signatureY + 8); - doc.line(30, signatureY + 8, 90, signatureY + 8); + + if (signatureMatin?.signatureUrl) { + try { + const signaturePath = path.resolve(process.cwd(), signatureMatin.signatureUrl.substring(1)); + if (fs.existsSync(signaturePath)) { + const signatureBuffer = fs.readFileSync(signaturePath); + const signatureBase64 = `data:image/png;base64,${signatureBuffer.toString('base64')}`; + doc.addImage(signatureBase64, 'PNG', 30, signatureY + 2, 60, 15); + } else { + doc.line(30, signatureY + 8, 90, signatureY + 8); + } + } catch (error) { + console.error('Erreur lors du chargement de la signature formateur matin:', error); + doc.line(30, signatureY + 8, 90, signatureY + 8); + } + } else { + doc.line(30, signatureY + 8, 90, signatureY + 8); + } // Signature Après-midi doc.text('Après-midi :', 110, signatureY + 8); - doc.line(140, signatureY + 8, 200, signatureY + 8); + + if (signatureApresMidi?.signatureUrl) { + try { + const signaturePath = path.resolve(process.cwd(), signatureApresMidi.signatureUrl.substring(1)); + if (fs.existsSync(signaturePath)) { + const signatureBuffer = fs.readFileSync(signaturePath); + const signatureBase64 = `data:image/png;base64,${signatureBuffer.toString('base64')}`; + doc.addImage(signatureBase64, 'PNG', 140, signatureY + 2, 60, 15); + } else { + doc.line(140, signatureY + 8, 200, signatureY + 8); + } + } catch (error) { + console.error('Erreur lors du chargement de la signature formateur après-midi:', error); + doc.line(140, signatureY + 8, 200, signatureY + 8); + } + } else { + doc.line(140, signatureY + 8, 200, signatureY + 8); + } }; // Générer une page pour chaque date diff --git a/server/routers.ts b/server/routers.ts index ff198e4..b023159 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -1167,8 +1167,9 @@ export const appRouter = router({ } // Récupérer toutes les présences avec signatures pour cette séquence - const { getPresencesBySequence } = await import("./presenceDb"); + const { getPresencesBySequence, getSignaturesFormateursBySequence } = await import("./presenceDb"); const presences = await getPresencesBySequence(input.sequenceId); + const signaturesFormateurs = await getSignaturesFormateursBySequence(input.sequenceId); const data = inscriptions .filter(i => i.inscription.statut === 'confirmee' && i.apprenant) @@ -1204,6 +1205,11 @@ export const appRouter = router({ publicCible: sequence.publicCible, formateur: formateurNom, apprenants: data, + signaturesFormateurs: signaturesFormateurs.map(s => ({ + dateFormationId: s.dateFormationId, + periode: s.periode as 'matin' | 'apres_midi', + signatureUrl: s.signatureUrl, + })), }); return { diff --git a/todo.md b/todo.md index 724af3f..f035c42 100644 --- a/todo.md +++ b/todo.md @@ -1548,3 +1548,12 @@ - [x] Reproduire exactement le même format pour les formateurs - [x] Afficher le nom du formateur, la date/heure de signature et une case verte par ligne - [x] Supprimer l'affichage actuel avec les grandes images de signature + + +## Intégrer les signatures formateurs dans la feuille de présence PDF + +- [x] Analyser le code de génération de la feuille de présence PDF actuelle +- [x] Modifier le backend pour récupérer les signatures formateurs en plus des signatures apprenants +- [x] Ajouter une section "Signature Formateur" dans le PDF avec les signatures matin et après-midi +- [x] Tester la génération PDF avec les signatures formateurs +- [x] Déployer sur recette et production