Versions stable (inachevée mais prête à un déploiement en prod)
This commit is contained in:
229
src/main/java/dev/lions/services/ContactService.java
Normal file
229
src/main/java/dev/lions/services/ContactService.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user