241 lines
7.0 KiB
Java
241 lines
7.0 KiB
Java
package dev.lions.services;
|
|
|
|
import dev.lions.events.ProjectUpdateEvent;
|
|
import dev.lions.exceptions.BusinessException;
|
|
import dev.lions.models.Project;
|
|
import dev.lions.models.Testimonial;
|
|
import dev.lions.repositories.ProjectRepository;
|
|
import dev.lions.utils.ImageProcessor;
|
|
import dev.lions.config.ApplicationConfig;
|
|
|
|
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 java.util.Set;
|
|
import lombok.Builder;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.time.LocalDateTime;
|
|
|
|
/**
|
|
* Service gérant la logique métier des projets.
|
|
* Cette classe assure la gestion complète du cycle de vie des projets,
|
|
* incluant leur création, mise à jour, recherche et validation.
|
|
*/
|
|
@Slf4j
|
|
@ApplicationScoped
|
|
@Builder
|
|
public class ProjectService {
|
|
|
|
@Inject
|
|
ProjectRepository projectRepository;
|
|
|
|
@Inject
|
|
ImageProcessor imageProcessor;
|
|
|
|
@Inject
|
|
ApplicationConfig config;
|
|
|
|
@Inject
|
|
Event<ProjectUpdateEvent> projectUpdateEvent;
|
|
|
|
/**
|
|
* Crée un nouveau projet avec son image associée.
|
|
*
|
|
* @param project Données du projet
|
|
* @param imageData Image du projet en bytes
|
|
* @return Projet créé
|
|
*/
|
|
@Transactional
|
|
public Project createProject(@Valid @NotNull Project project, byte[] imageData) {
|
|
log.info("Création d'un nouveau projet : {}", project.getTitle());
|
|
|
|
try {
|
|
validateProject(project);
|
|
processProjectImage(project, imageData);
|
|
|
|
Project savedProject = projectRepository.save(project);
|
|
notifyProjectCreation(savedProject);
|
|
|
|
log.info("Projet créé avec succès - ID: {}", savedProject.getId());
|
|
return savedProject;
|
|
|
|
} catch (BusinessException be) {
|
|
log.warn("Validation échouée pour le projet", be);
|
|
throw be;
|
|
} catch (Exception e) {
|
|
log.error("Erreur lors de la création du projet", e);
|
|
throw new BusinessException("Impossible de créer le projet", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Met à jour un projet existant.
|
|
*
|
|
* @param project Projet à mettre à jour
|
|
* @param imageData Nouvelle image optionnelle
|
|
* @return Projet mis à jour
|
|
*/
|
|
@Transactional
|
|
public Project updateProject(@Valid @NotNull Project project, byte[] imageData) {
|
|
log.info("Mise à jour du projet : {}", project.getId());
|
|
|
|
try {
|
|
validateProject(project);
|
|
|
|
if (imageData != null) {
|
|
processProjectImage(project, imageData);
|
|
}
|
|
|
|
Project updatedProject = projectRepository.update(project);
|
|
notifyProjectUpdate(updatedProject);
|
|
|
|
log.info("Projet mis à jour avec succès - ID: {}", updatedProject.getId());
|
|
return updatedProject;
|
|
|
|
} catch (Exception e) {
|
|
log.error("Erreur lors de la mise à jour du projet", e);
|
|
throw new BusinessException("Impossible de mettre à jour le projet", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Traite et stocke l'image du projet.
|
|
*/
|
|
private void processProjectImage(Project project, byte[] imageData) {
|
|
if (imageData == null || imageData.length == 0) {
|
|
throw new BusinessException("L'image du projet est requise");
|
|
}
|
|
|
|
String imageUrl = imageProcessor.processAndStoreProjectImage(
|
|
imageData,
|
|
project.getTitle(),
|
|
config.getImageStoragePath()
|
|
);
|
|
|
|
project.setImageUrl(imageUrl);
|
|
}
|
|
|
|
/**
|
|
* Récupère un projet par son identifiant.
|
|
*/
|
|
public Optional<Project> findById(@NotNull String projectId) {
|
|
log.debug("Recherche du projet : {}", projectId);
|
|
return projectRepository.findById(projectId);
|
|
}
|
|
|
|
/**
|
|
* Vérifie l'existence d'un projet.
|
|
*/
|
|
public boolean existsById(@NotNull String projectId) {
|
|
return projectRepository.existsById(projectId);
|
|
}
|
|
|
|
/**
|
|
* Récupère les projets filtrés par tag.
|
|
*/
|
|
public List<Project> getFilteredProjects(String filter) {
|
|
log.debug("Filtrage des projets avec le critère : {}", filter);
|
|
|
|
if ("all".equalsIgnoreCase(filter)) {
|
|
return projectRepository.findAll();
|
|
}
|
|
|
|
return projectRepository.findByTags(Set.of(filter.toLowerCase()));
|
|
}
|
|
|
|
/**
|
|
* Récupère les projets mis en avant.
|
|
*/
|
|
public List<Project> getFeaturedProjects() {
|
|
log.debug("Récupération des projets mis en avant");
|
|
return projectRepository.findByFeatured(true);
|
|
}
|
|
|
|
/**
|
|
* Récupère les projets récents.
|
|
*/
|
|
public List<Project> getRecentProjects(int limit) {
|
|
log.debug("Récupération des {} projets les plus récents", limit);
|
|
return projectRepository.findRecentProjects(limit);
|
|
}
|
|
|
|
/**
|
|
* Récupère le nombre total de projets.
|
|
*/
|
|
public long getProjectCount() {
|
|
log.debug("Récupération du nombre total de projets");
|
|
return projectRepository.count();
|
|
}
|
|
|
|
|
|
/**
|
|
* Récupère les témoignages mis en avant.
|
|
*/
|
|
public List<Testimonial> getFeaturedTestimonials() {
|
|
log.debug("Récupération des témoignages mis en avant");
|
|
|
|
return projectRepository.findByFeatured(true).stream()
|
|
.filter(project -> !project.getTestimonials().isEmpty())
|
|
.map(this::createTestimonialFromProject)
|
|
.limit(3)
|
|
.toList();
|
|
}
|
|
|
|
/**
|
|
* Valide les données d'un projet.
|
|
*/
|
|
private void validateProject(Project project) {
|
|
if (project.getTitle() == null || project.getTitle().trim().isEmpty()) {
|
|
throw new BusinessException("Le titre du projet est requis");
|
|
}
|
|
if (project.getDescription() == null || project.getDescription().trim().isEmpty()) {
|
|
throw new BusinessException("La description du projet est requise");
|
|
}
|
|
if (project.getShortDescription() == null ||
|
|
project.getShortDescription().trim().isEmpty()) {
|
|
throw new BusinessException("La description courte du projet est requise");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Crée un témoignage à partir d'un projet.
|
|
*/
|
|
private Testimonial createTestimonialFromProject(Project project) {
|
|
return Testimonial.builder()
|
|
.clientName(project.getClientName())
|
|
.content(project.getTestimonials().get(0))
|
|
.projectTitle(project.getTitle())
|
|
.date(project.getCompletionDate())
|
|
.build();
|
|
|
|
}
|
|
|
|
/**
|
|
* Notifie la création d'un projet.
|
|
*/
|
|
private void notifyProjectCreation(Project project) {
|
|
projectUpdateEvent.fire(new ProjectUpdateEvent(
|
|
project.getId(),
|
|
"CREATE",
|
|
LocalDateTime.now()
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Notifie la mise à jour d'un projet.
|
|
*/
|
|
private void notifyProjectUpdate(Project project) {
|
|
projectUpdateEvent.fire(new ProjectUpdateEvent(
|
|
project.getId(),
|
|
"UPDATE",
|
|
LocalDateTime.now()
|
|
));
|
|
}
|
|
} |