Rollback to eebcb648
This commit is contained in:
109
deployment-package/source_server/icsGenerator.ts
Normal file
109
deployment-package/source_server/icsGenerator.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Module de génération de fichiers ICS (iCalendar) pour les invitations Outlook
|
||||
*/
|
||||
|
||||
interface ICSEvent {
|
||||
summary: string;
|
||||
description?: string;
|
||||
location: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
attendeeEmail: string;
|
||||
attendeeName: string;
|
||||
organizerEmail?: string;
|
||||
organizerName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date au format iCalendar (YYYYMMDDTHHMMSSZ)
|
||||
*/
|
||||
function formatICSDate(date: Date): string {
|
||||
const year = date.getUTCFullYear();
|
||||
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getUTCDate()).padStart(2, '0');
|
||||
const hours = String(date.getUTCHours()).padStart(2, '0');
|
||||
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getUTCSeconds()).padStart(2, '0');
|
||||
|
||||
return `${year}${month}${day}T${hours}${minutes}${seconds}Z`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère un UID unique pour l'événement
|
||||
*/
|
||||
function generateUID(): string {
|
||||
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}@itinova.com`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Échappe les caractères spéciaux pour le format ICS
|
||||
*/
|
||||
function escapeICS(text: string): string {
|
||||
return text
|
||||
.replace(/\\/g, '\\\\')
|
||||
.replace(/;/g, '\\;')
|
||||
.replace(/,/g, '\\,')
|
||||
.replace(/\n/g, '\\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère un fichier ICS pour une invitation Outlook
|
||||
*/
|
||||
export function generateICS(event: ICSEvent): string {
|
||||
const now = new Date();
|
||||
const uid = generateUID();
|
||||
|
||||
const icsContent = [
|
||||
'BEGIN:VCALENDAR',
|
||||
'VERSION:2.0',
|
||||
'PRODID:-//Itinova//Formation Manager//FR',
|
||||
'CALSCALE:GREGORIAN',
|
||||
'METHOD:REQUEST',
|
||||
'BEGIN:VEVENT',
|
||||
`UID:${uid}`,
|
||||
`DTSTAMP:${formatICSDate(now)}`,
|
||||
`DTSTART:${formatICSDate(event.startDate)}`,
|
||||
`DTEND:${formatICSDate(event.endDate)}`,
|
||||
`SUMMARY:${escapeICS(event.summary)}`,
|
||||
event.description ? `DESCRIPTION:${escapeICS(event.description)}` : '',
|
||||
`LOCATION:${escapeICS(event.location)}`,
|
||||
'STATUS:CONFIRMED',
|
||||
'TRANSP:OPAQUE', // Marque comme "occupé" dans le calendrier
|
||||
'SEQUENCE:0',
|
||||
`ORGANIZER;CN=${escapeICS(event.organizerName || 'Formation Itinova')}:mailto:${event.organizerEmail || 'formation@itinova.com'}`,
|
||||
`ATTENDEE;CN=${escapeICS(event.attendeeName)};RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:${event.attendeeEmail}`,
|
||||
'BEGIN:VALARM',
|
||||
'TRIGGER:-P1D', // Rappel 1 jour avant
|
||||
'ACTION:DISPLAY',
|
||||
`DESCRIPTION:Rappel: ${escapeICS(event.summary)}`,
|
||||
'END:VALARM',
|
||||
'END:VEVENT',
|
||||
'END:VCALENDAR',
|
||||
].filter(line => line !== '').join('\r\n');
|
||||
|
||||
return icsContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère un fichier ICS pour une session de formation
|
||||
*/
|
||||
export function generateFormationICS(params: {
|
||||
formationNom: string;
|
||||
sessionNom: string;
|
||||
dateDebut: Date;
|
||||
dateFin: Date;
|
||||
lieu: string;
|
||||
apprenantNom: string;
|
||||
apprenantPrenom: string;
|
||||
apprenantEmail: string;
|
||||
}): string {
|
||||
return generateICS({
|
||||
summary: `Formation: ${params.formationNom} - ${params.sessionNom}`,
|
||||
description: `Vous êtes inscrit à la formation "${params.formationNom}".\n\nSession: ${params.sessionNom}\n\nMerci de vous présenter à l'heure indiquée.`,
|
||||
location: params.lieu,
|
||||
startDate: params.dateDebut,
|
||||
endDate: params.dateFin,
|
||||
attendeeEmail: params.apprenantEmail,
|
||||
attendeeName: `${params.apprenantPrenom} ${params.apprenantNom}`,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user