Checkpoint: Amélioration du bouton "Tester le rappel" pour utiliser automatiquement le bon template configuré :

- Modification de la procédure testerRappel pour détecter automatiquement le premier rappel actif configuré pour la séquence
- Suppression du paramètre typeRappel (n'est plus nécessaire)
- Création de la fonction sendRappelEmail générique qui utilise le templateType du rappel configuré
- Le bouton frontend envoie maintenant le bon template (rappel 1, 3, 4, 5, 6, etc.) selon la configuration de la séquence
- Gestion des pièces jointes configurées dans le rappel
- Mise à jour du fichier todo.md pour marquer la tâche comme terminée
This commit is contained in:
Manus
2026-01-15 12:22:24 -05:00
parent d3645ec1cb
commit e642f23170
4 changed files with 136 additions and 37 deletions

View File

@@ -1379,7 +1379,6 @@ export const appRouter = router({
testerRappel: adminProcedure
.input(z.object({
sequenceId: z.number(),
typeRappel: z.enum(['rappel', 'rappelJ1']),
}))
.mutation(async ({ input }) => {
const sequence = await db.getSequenceById(input.sequenceId);
@@ -1402,6 +1401,21 @@ export const appRouter = router({
// Récupérer les dates de la séquence
const dates = await db.getDatesBySequence(input.sequenceId);
// Récupérer les rappels configurés pour la première date de la séquence
if (dates.length === 0) {
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Cette séquence n\'a pas de dates configurées' });
}
const rappelsConfigures = await db.getRappelsByDateFormation(dates[0].id);
const rappelsActifs = rappelsConfigures.filter((r: any) => r.actif);
if (rappelsActifs.length === 0) {
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Aucun rappel actif configuré pour cette séquence' });
}
// Utiliser le premier rappel actif trouvé
const rappelAUtiliser = rappelsActifs[0];
// Récupérer les inscrits
const inscrits = await db.getInscriptionsBySequence(input.sequenceId);
const inscritsConfirmes = inscrits.filter(i => i.inscription.statut === 'confirmee');
@@ -1418,42 +1432,28 @@ export const appRouter = router({
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Apprenant introuvable ou sans email' });
}
const { sendRappelJ7Email, sendRappelJ1Email } = await import('./emailService');
const { sendRappelEmail } = await import('./emailService');
try {
if (input.typeRappel === 'rappel') {
await sendRappelJ7Email({
apprenantEmail: apprenant.email,
apprenantPrenom: apprenant.prenom,
apprenantNom: apprenant.nom,
apprenantFonction: apprenant.fonction || '',
formationNom: formation.nom,
sequenceNom: sequence.nom,
dates: dates.map((d: any) => ({
dateDebut: d.dateDebut,
dateFin: d.dateFin,
ordre: d.ordre
})),
lieu: sequence.lieu || '',
formateur: formateurNom,
});
} else {
await sendRappelJ1Email({
apprenantEmail: apprenant.email,
apprenantPrenom: apprenant.prenom,
apprenantNom: apprenant.nom,
apprenantFonction: apprenant.fonction || '',
formationNom: formation.nom,
sequenceNom: sequence.nom,
dates: dates.map((d: any) => ({
dateDebut: d.dateDebut,
dateFin: d.dateFin,
ordre: d.ordre
})),
lieu: sequence.lieu || '',
formateur: formateurNom,
});
}
await sendRappelEmail({
apprenantEmail: apprenant.email,
apprenantPrenom: apprenant.prenom,
apprenantNom: apprenant.nom,
apprenantFonction: apprenant.fonction || '',
formationNom: formation.nom,
sequenceNom: sequence.nom,
dates: dates.map((d: any) => ({
dateDebut: d.dateDebut,
dateFin: d.dateFin,
ordre: d.ordre
})),
lieu: sequence.lieu || '',
formateur: formateurNom,
templateType: rappelAUtiliser.templateType,
attachmentUrl: rappelAUtiliser.urlFichier || undefined,
attachmentFilename: rappelAUtiliser.nomFichier || undefined,
attachmentMimeType: rappelAUtiliser.typeFichier || undefined,
});
return {
success: true,