diff --git a/server/routers.ts b/server/routers.ts index 04d4dea..db259fb 100644 --- a/server/routers.ts +++ b/server/routers.ts @@ -1424,48 +1424,64 @@ export const appRouter = router({ throw new TRPCError({ code: 'BAD_REQUEST', message: 'Aucun apprenant inscrit confirmé pour cette séquence' }); } - // Envoyer le rappel de test au premier inscrit uniquement - const premierInscrit = inscritsConfirmes[0]; - const apprenant = premierInscrit.apprenant; - - if (!apprenant || !apprenant.email) { - throw new TRPCError({ code: 'BAD_REQUEST', message: 'Apprenant introuvable ou sans email' }); - } - + // Envoyer le rappel de test à l'administrateur connecté + // Envoyer le rappel de test à tous les inscrits confirmés const { sendRappelEmail } = await import('./emailService'); - try { - 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, - }); + let nbEnvoyes = 0; + let nbEchecs = 0; + const erreurs: string[] = []; - return { - success: true, - message: `Rappel de test envoyé à ${apprenant.email}`, - destinataire: apprenant.email, - }; - } catch (error: any) { + for (const inscrit of inscritsConfirmes) { + const apprenant = inscrit.apprenant; + + if (!apprenant || !apprenant.email) { + nbEchecs++; + erreurs.push(`Apprenant ${apprenant?.nom || 'inconnu'}: email manquant`); + continue; + } + + try { + 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, + }); + nbEnvoyes++; + } catch (error: any) { + nbEchecs++; + erreurs.push(`${apprenant.email}: ${error.message}`); + } + } + + if (nbEnvoyes === 0) { throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', - message: `Erreur lors de l'envoi: ${error.message}`, + message: `Aucun email envoyé. Erreurs: ${erreurs.join(', ')}`, }); } + + return { + success: true, + message: `Rappel de test envoyé à ${nbEnvoyes} apprenant(s)${nbEchecs > 0 ? ` (${nbEchecs} échec(s))` : ''}`, + nbEnvoyes, + nbEchecs, + erreurs: nbEchecs > 0 ? erreurs : undefined, + }; }), historique: adminProcedure diff --git a/todo.md b/todo.md index 42815ee..4c6e31e 100644 --- a/todo.md +++ b/todo.md @@ -820,3 +820,4 @@ - [x] Corriger l'erreur de validation du type de rappel dans la procédure testerRappel (typeRappel invalide) - [x] Corriger l'erreur "Cannot read properties of undefined (reading 'replace')" lors de l'envoi de test de rappel - [x] Améliorer le bouton "Tester le rappel" pour utiliser automatiquement le bon template configuré pour la séquence (au lieu de toujours envoyer rappel J-7) +- [x] Modifier la procédure testerRappel pour envoyer le rappel à tous les inscrits confirmés (au lieu du premier uniquement)