Checkpoint: Modification de la procédure testerRappel pour envoyer le rappel à tous les inscrits confirmés :
- Remplacement de l'envoi au premier inscrit uniquement par un envoi à tous les inscrits confirmés - Ajout d'un compteur de succès et d'échecs - Gestion des erreurs individuelles pour chaque envoi - Message de retour détaillé avec le nombre d'envois réussis et échoués - Déploiement sur le VPS de production - Mise à jour du fichier todo.md
This commit is contained in:
@@ -1424,48 +1424,64 @@ export const appRouter = router({
|
|||||||
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Aucun apprenant inscrit confirmé pour cette séquence' });
|
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Aucun apprenant inscrit confirmé pour cette séquence' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Envoyer le rappel de test au premier inscrit uniquement
|
// Envoyer le rappel de test à l'administrateur connecté
|
||||||
const premierInscrit = inscritsConfirmes[0];
|
// Envoyer le rappel de test à tous les inscrits confirmés
|
||||||
const apprenant = premierInscrit.apprenant;
|
|
||||||
|
|
||||||
if (!apprenant || !apprenant.email) {
|
|
||||||
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Apprenant introuvable ou sans email' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const { sendRappelEmail } = await import('./emailService');
|
const { sendRappelEmail } = await import('./emailService');
|
||||||
|
|
||||||
try {
|
let nbEnvoyes = 0;
|
||||||
await sendRappelEmail({
|
let nbEchecs = 0;
|
||||||
apprenantEmail: apprenant.email,
|
const erreurs: string[] = [];
|
||||||
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 {
|
for (const inscrit of inscritsConfirmes) {
|
||||||
success: true,
|
const apprenant = inscrit.apprenant;
|
||||||
message: `Rappel de test envoyé à ${apprenant.email}`,
|
|
||||||
destinataire: apprenant.email,
|
if (!apprenant || !apprenant.email) {
|
||||||
};
|
nbEchecs++;
|
||||||
} catch (error: any) {
|
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({
|
throw new TRPCError({
|
||||||
code: 'INTERNAL_SERVER_ERROR',
|
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
|
historique: adminProcedure
|
||||||
|
|||||||
1
todo.md
1
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 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] 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] 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)
|
||||||
|
|||||||
Reference in New Issue
Block a user