Versions stable (inachevée mais prête à un déploiement en prod)

This commit is contained in:
DahoudG
2024-12-15 16:35:50 +00:00
parent a276ac2318
commit d2cb9da730
126 changed files with 13559 additions and 631 deletions

View File

@@ -0,0 +1,229 @@
package dev.lions.services;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import dev.lions.models.Contact;
import dev.lions.models.ContactForm;
import dev.lions.models.ContactStatus;
import dev.lions.models.EmailTemplate;
import dev.lions.repositories.ContactRepository;
import dev.lions.events.ContactSubmissionEvent;
import dev.lions.exceptions.BusinessException;
import java.time.LocalDateTime;
import java.util.Map;
/**
* Service gérant la logique métier des contacts.
* Cette classe assure le traitement des demandes de contact, leur validation,
* et la notification des parties concernées.
*/
@Slf4j
@ApplicationScoped
public class ContactService {
@Inject
private ContactRepository contactRepository;
@Inject
private EmailService emailService;
@Inject
private Event<ContactSubmissionEvent> contactEvent;
/**
* Traite un nouveau formulaire de contact.
* Cette méthode valide les données, enregistre le contact et envoie
* les notifications appropriées.
*
* @param form Formulaire de contact à traiter
* @return Contact créé
*/
@Transactional
public Contact processContactForm(@Valid @NotNull ContactForm form) {
log.info("Traitement d'une nouvelle demande de contact");
try {
validateContactForm(form);
Contact contact = createContact(form);
sendConfirmationEmails(contact);
notifyContactSubmission(contact);
log.info("Demande de contact traitée avec succès - ID: {}",
contact.getId());
return contact;
} catch (BusinessException be) {
log.warn("Erreur de validation du formulaire de contact", be);
throw be;
} catch (Exception e) {
log.error("Erreur lors du traitement de la demande de contact", e);
throw new BusinessException(
"Impossible de traiter la demande de contact", e);
}
}
/**
* Valide les données du formulaire de contact.
*/
private void validateContactForm(ContactForm form) {
if (form.getName() == null || form.getName().trim().length() < 2) {
throw new BusinessException("Le nom doit contenir au moins 2 caractères");
}
if (!isValidEmail(form.getEmail())) {
throw new BusinessException("L'adresse email n'est pas valide");
}
if (form.getMessage() == null ||
form.getMessage().trim().length() < 10 ||
form.getMessage().length() > 1000) {
throw new BusinessException(
"Le message doit contenir entre 10 et 1000 caractères");
}
}
/**
* Crée une nouvelle entité Contact à partir du formulaire.
*/
private Contact createContact(ContactForm form) {
Contact contact = new Contact(
form.getName(),
form.getEmail(),
form.getSubject(),
form.getMessage()
);
contact.setStatus(ContactStatus.NEW);
contact.setSubmitDate(LocalDateTime.now());
return contactRepository.save(contact);
}
/**
* Envoie les emails de confirmation.
*/
private void sendConfirmationEmails(Contact contact) {
sendCustomerConfirmation(contact);
sendAdminNotification(contact);
}
/**
* Envoie l'email de confirmation au client.
*/
private void sendCustomerConfirmation(Contact contact) {
EmailTemplate template = EmailTemplate.builder()
.templateName("contact-confirmation")
.recipient(contact.getEmail())
.subject("Confirmation de votre message")
.parameters(Map.of(
"name", contact.getName(),
"subject", contact.getSubject(),
"message", contact.getMessage(),
"contactId", contact.getId().toString()
))
.build();
emailService.sendTemplatedEmail(template);
}
/**
* Envoie l'email de notification à l'administrateur.
*/
private void sendAdminNotification(Contact contact) {
EmailTemplate template = EmailTemplate.builder()
.templateName("admin-contact-notification")
.recipient(emailService.config.getAdminEmailAddress())
.subject("Nouvelle demande de contact")
.parameters(Map.of(
"name", contact.getName(),
"email", contact.getEmail(),
"subject", contact.getSubject(),
"message", contact.getMessage(),
"timestamp", contact.getSubmitDate().toString(),
"contactId", contact.getId().toString()
))
.build();
emailService.sendTemplatedEmail(template);
}
/**
* Notifie le système de la soumission d'un nouveau contact.
*/
private void notifyContactSubmission(Contact contact) {
contactEvent.fire(new ContactSubmissionEvent(contact));
}
/**
* Vérifie si une adresse email est valide.
*/
private boolean isValidEmail(String email) {
if (email == null || email.trim().isEmpty()) {
return false;
}
String emailRegex = "^[A-Za-z0-9+_.-]+@(.+)$";
return email.matches(emailRegex);
}
/**
* Met à jour le statut d'un contact.
*
* @param contactId Identifiant du contact
* @param newStatus Nouveau statut
* @param note Note optionnelle sur la mise à jour
*/
@Transactional
public void updateContactStatus(
@NotNull Long contactId,
@NotNull ContactStatus newStatus,
String note) {
log.info("Mise à jour du statut du contact {} vers {}",
contactId, newStatus);
try {
Contact contact = contactRepository.findById(contactId)
.orElseThrow(() -> new BusinessException("Contact non trouvé"));
contact.setStatus(newStatus);
contact.setProcessDate(LocalDateTime.now());
if (note != null && !note.trim().isEmpty()) {
addInternalNote(contact, note);
}
contactRepository.update(contact);
log.info("Statut du contact mis à jour avec succès");
} catch (Exception e) {
log.error("Erreur lors de la mise à jour du statut du contact", e);
throw new BusinessException(
"Impossible de mettre à jour le statut du contact", e);
}
}
/**
* Ajoute une note interne à un contact.
*/
private void addInternalNote(Contact contact, String note) {
String currentNotes = contact.getInternalNotes();
String timestamp = LocalDateTime.now().toString();
String newNote = String.format("[%s] %s", timestamp, note);
if (currentNotes == null || currentNotes.trim().isEmpty()) {
contact.setInternalNotes(newNote);
} else {
contact.setInternalNotes(currentNotes + "\n" + newNote);
}
}
}