229 lines
7.6 KiB
Java
229 lines
7.6 KiB
Java
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);
|
|
}
|
|
}
|
|
} |