Module JEMA - inscriptions, capacite, rappels
JEMA (Journees Europeennes des Metiers d'Art) est le coeur fonctionnel du site : des artisans ouvrent leur atelier, les visiteurs s'inscrivent en ligne a des creneaux horaires.
Structure de noeuds
Les inscriptions sont stockees comme contenu Umbraco (pas de table SQL custom), sous chaque artisan JEMA (jemaCraftsman) :
jemaCraftsman (porte nbPlaces)
└── registrationDayJema (un jour ; nom "Jour - JJ.MM.AAAA", propriete date en ticks)
└── registrationTimeSlotJema (un creneau ; nom "HH:mm - HH:mm", timestampStart/End, nbRegistrations)
└── participantJema (un inscrit : firstName, lastName, email, phone, language, nbParticipants)Le contexte editorial : jemaPage (reference l'jemaEdition courante via CurrentJemaEdition, avec jemaStartDate/jemaEndDate), pages par ville (cityJemaPage, localisationJemaPage), categories et lieux.
Inscription en ligne (JemaRegistrationController)
Controllers/JemaRegistrationController.cs, action Submit (POST JSON, modele JemaRegistrationRequestRecord) :
- Valide la langue (
fr/de/it; sinon message d'erreur enen), leModelState, etParticipants > 0. - Charge l'artisan par
ArtisanIdet verifieContentType.Alias == "jemaCraftsman". GetOrCreateDay: retrouve ou cree leregistrationDayJemacorrespondant a la date (compare les ticks dedate).ParseTimeRange+GetOrCreateTimeSlot: retrouve ou cree leregistrationTimeSlotJema(comparetimestampStart/timestampEnd).- Capacite : refuse si
nbRegistrations + Participants > nbPlaces(messageCraftsmanPage.RegistrationJema.Error.TimeSlotFull). - Incremente
nbRegistrations, sauve + publie le creneau. CreateParticipant: cree leparticipantJemasous le creneau.- Mails (
EmailService) : confirmation au visiteur (toujours) ; confirmation a l'artisan uniquement si on est entrejemaStartDateetjemaEndDatede l'edition courante (IsWithinJemaEventPeriod).
Etat du code (a surveiller) : action en [IgnoreAntiforgeryToken] // TEMP, TODO sur la verification de disponibilite reelle du creneau et l'anti-robot. A traiter comme provisoire.
Validation / derivation a la sauvegarde (JemaScheduleChangeNotificationHandler)
Handler ContentSavingNotification (Notifications/JemaScheduleChangeNotificationHandler.cs), enregistre dans Program.cs :
registrationDayJema: le nom doit matcher... - JJ.MM.AAAA. Derive la date dansdate(ticks). Format invalide ->CancelOperation.registrationTimeSlotJema: le nom doit matcherHH:mm [-/–] HH:mm. DerivetimestampStart/timestampEnd(ticks). Refuse si fin <= debut.
Si tu modifies ces doctypes ou leurs alias de propriete, mets a jour ce handler et JemaRegistrationController (qui lit/ecrit les memes alias). JemaDurationCalculationHandler complete le calcul de durees a la sauvegarde.
Mails JEMA (EmailService)
Methodes dediees, via le SMTP JEMA (JemaSmtpOptions, isJema: true), templates Razor embarques :
SendConfirmJemaRegistrationToUserAsync->GenericJemaRegistrationConfirmation.cshtml(visiteur).SendConfirmJemaRegistrationToCraftsmanAsync-> meme template (artisan ; resout les emails desrelatedCraftsman). En staging/dev, redirige vers une adresse de test.SendJemaReminderEmailAsync->JemaReminderCraftsman.cshtml(rappel artisan, CSV des inscrits en piece jointe).SendJemaReminderEmailToVisitorAsync->JemaReminderVisitor.cshtml(rappel visiteur).
Les sujets/contenus proviennent de la composition jemaRegistrationConfirmationEmailSettings (multilingue, lecture Value<...>(alias, culture)), avec tokens {donnees}, {prenom}, {nom}, {nom-complet}, {email}, {ville}. Le visuel d'en-tete depend de la langue (JEMA_{FR|DE|IT|EN}.png).
Rappels automatiques (JemaEmailReminderJob + JemaReminderService)
- Job Quartz
JemaEmailReminderJob, cron0 0 9 * * ?(09:00 quotidien), enregistre dansProgram.cs. - Ne s'execute qu'en production (
returnimmediat en Development/Staging). - Appelle
JemaReminderService.SendRemindersAsync(false)puis(true)(rappels generaux puis JEMA du jour). - Fichier CSV des inscrits localise :
inscrits.csv/registrations.csv/anmeldungen.csv/iscritti.csv.
Corbeille JEMA
Controllers/JemaTrashApiController.cs : API d'administration des noeuds JEMA (outillage interne).

