feat: Système complet de gestion des établissements (backend) - Entités JPA pour Establishment, EstablishmentMedia, EstablishmentRating - DTOs pour création, mise à jour et réponses - Repositories Panache pour accès aux données - Services avec logique métier et validation - Resources REST avec tous les endpoints CRUD - Gestion des médias (photos/vidéos) - Système de notation avec statistiques
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package com.lions.dev.service;
|
||||
|
||||
import com.lions.dev.entity.establishment.Establishment;
|
||||
import com.lions.dev.entity.establishment.EstablishmentMedia;
|
||||
import com.lions.dev.entity.establishment.MediaType;
|
||||
import com.lions.dev.entity.users.Users;
|
||||
import com.lions.dev.repository.EstablishmentMediaRepository;
|
||||
import com.lions.dev.repository.EstablishmentRepository;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Service de gestion des médias d'établissements.
|
||||
* Ce service contient la logique métier pour l'upload, la récupération et la suppression des médias.
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class EstablishmentMediaService {
|
||||
|
||||
@Inject
|
||||
EstablishmentMediaRepository mediaRepository;
|
||||
|
||||
@Inject
|
||||
EstablishmentRepository establishmentRepository;
|
||||
|
||||
@Inject
|
||||
UsersRepository usersRepository;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(EstablishmentMediaService.class);
|
||||
|
||||
/**
|
||||
* Récupère tous les médias d'un établissement.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @return Liste des médias de l'établissement
|
||||
*/
|
||||
public List<EstablishmentMedia> getMediaByEstablishmentId(UUID establishmentId) {
|
||||
LOG.info("Récupération des médias pour l'établissement : " + establishmentId);
|
||||
return mediaRepository.findByEstablishmentId(establishmentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload un nouveau média pour un établissement.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @param mediaUrl L'URL du média
|
||||
* @param mediaType Le type de média (PHOTO ou VIDEO)
|
||||
* @param uploadedByUserId L'ID de l'utilisateur qui upload
|
||||
* @param thumbnailUrl L'URL de la miniature (optionnel, pour les vidéos)
|
||||
* @return Le média créé
|
||||
*/
|
||||
@Transactional
|
||||
public EstablishmentMedia uploadMedia(UUID establishmentId, String mediaUrl, MediaType mediaType, UUID uploadedByUserId, String thumbnailUrl) {
|
||||
LOG.info("Upload d'un média pour l'établissement : " + establishmentId);
|
||||
|
||||
// Vérifier que l'établissement existe
|
||||
Establishment establishment = establishmentRepository.findById(establishmentId);
|
||||
if (establishment == null) {
|
||||
LOG.error("Établissement non trouvé avec l'ID : " + establishmentId);
|
||||
throw new RuntimeException("Établissement non trouvé");
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur existe
|
||||
Users uploadedBy = usersRepository.findById(uploadedByUserId);
|
||||
if (uploadedBy == null) {
|
||||
LOG.error("Utilisateur non trouvé avec l'ID : " + uploadedByUserId);
|
||||
throw new RuntimeException("Utilisateur non trouvé");
|
||||
}
|
||||
|
||||
// Créer le média
|
||||
EstablishmentMedia media = new EstablishmentMedia(establishment, mediaUrl, mediaType, uploadedBy);
|
||||
media.setThumbnailUrl(thumbnailUrl);
|
||||
|
||||
// Déterminer l'ordre d'affichage (dernier média = ordre le plus élevé)
|
||||
List<EstablishmentMedia> existingMedia = mediaRepository.findByEstablishmentId(establishmentId);
|
||||
int maxOrder = existingMedia.stream()
|
||||
.mapToInt(EstablishmentMedia::getDisplayOrder)
|
||||
.max()
|
||||
.orElse(-1);
|
||||
media.setDisplayOrder(maxOrder + 1);
|
||||
|
||||
mediaRepository.persist(media);
|
||||
LOG.info("Média uploadé avec succès : " + media.getId());
|
||||
return media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un média d'un établissement.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @param mediaId L'ID du média à supprimer
|
||||
*/
|
||||
@Transactional
|
||||
public void deleteMedia(UUID establishmentId, UUID mediaId) {
|
||||
LOG.info("Suppression du média " + mediaId + " de l'établissement " + establishmentId);
|
||||
|
||||
EstablishmentMedia media = mediaRepository.findById(mediaId);
|
||||
if (media == null) {
|
||||
LOG.error("Média non trouvé avec l'ID : " + mediaId);
|
||||
throw new RuntimeException("Média non trouvé");
|
||||
}
|
||||
|
||||
// Vérifier que le média appartient à l'établissement
|
||||
if (!media.getEstablishment().getId().equals(establishmentId)) {
|
||||
LOG.error("Le média " + mediaId + " n'appartient pas à l'établissement " + establishmentId);
|
||||
throw new RuntimeException("Le média n'appartient pas à cet établissement");
|
||||
}
|
||||
|
||||
mediaRepository.delete(media);
|
||||
LOG.info("Média supprimé avec succès : " + mediaId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
package com.lions.dev.service;
|
||||
|
||||
import com.lions.dev.dto.request.establishment.EstablishmentRatingRequestDTO;
|
||||
import com.lions.dev.entity.establishment.Establishment;
|
||||
import com.lions.dev.entity.establishment.EstablishmentRating;
|
||||
import com.lions.dev.entity.users.Users;
|
||||
import com.lions.dev.repository.EstablishmentRatingRepository;
|
||||
import com.lions.dev.repository.EstablishmentRepository;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Service de gestion des notations d'établissements.
|
||||
* Ce service contient la logique métier pour soumettre, modifier et récupérer les notes.
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class EstablishmentRatingService {
|
||||
|
||||
@Inject
|
||||
EstablishmentRatingRepository ratingRepository;
|
||||
|
||||
@Inject
|
||||
EstablishmentRepository establishmentRepository;
|
||||
|
||||
@Inject
|
||||
UsersRepository usersRepository;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(EstablishmentRatingService.class);
|
||||
|
||||
/**
|
||||
* Soumet une nouvelle note pour un établissement.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @param userId L'ID de l'utilisateur
|
||||
* @param requestDTO Le DTO contenant la note et le commentaire
|
||||
* @return La note créée
|
||||
*/
|
||||
@Transactional
|
||||
public EstablishmentRating submitRating(UUID establishmentId, UUID userId, EstablishmentRatingRequestDTO requestDTO) {
|
||||
LOG.info("Soumission d'une note pour l'établissement " + establishmentId + " par l'utilisateur " + userId);
|
||||
|
||||
// Vérifier que l'établissement existe
|
||||
Establishment establishment = establishmentRepository.findById(establishmentId);
|
||||
if (establishment == null) {
|
||||
LOG.error("Établissement non trouvé avec l'ID : " + establishmentId);
|
||||
throw new RuntimeException("Établissement non trouvé");
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur existe
|
||||
Users user = usersRepository.findById(userId);
|
||||
if (user == null) {
|
||||
LOG.error("Utilisateur non trouvé avec l'ID : " + userId);
|
||||
throw new RuntimeException("Utilisateur non trouvé");
|
||||
}
|
||||
|
||||
// Vérifier qu'il n'y a pas déjà une note de cet utilisateur
|
||||
EstablishmentRating existingRating = ratingRepository.findByEstablishmentIdAndUserId(establishmentId, userId);
|
||||
if (existingRating != null) {
|
||||
LOG.error("L'utilisateur " + userId + " a déjà noté l'établissement " + establishmentId);
|
||||
throw new RuntimeException("Vous avez déjà noté cet établissement. Utilisez la mise à jour pour modifier votre note.");
|
||||
}
|
||||
|
||||
// Créer la note
|
||||
EstablishmentRating rating = new EstablishmentRating(establishment, user, requestDTO.getRating());
|
||||
rating.setComment(requestDTO.getComment());
|
||||
ratingRepository.persist(rating);
|
||||
|
||||
// Mettre à jour les statistiques de l'établissement
|
||||
updateEstablishmentRatingStats(establishmentId);
|
||||
|
||||
LOG.info("Note soumise avec succès : " + rating.getId());
|
||||
return rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour une note existante.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @param userId L'ID de l'utilisateur
|
||||
* @param requestDTO Le DTO contenant la nouvelle note et le commentaire
|
||||
* @return La note mise à jour
|
||||
*/
|
||||
@Transactional
|
||||
public EstablishmentRating updateRating(UUID establishmentId, UUID userId, EstablishmentRatingRequestDTO requestDTO) {
|
||||
LOG.info("Mise à jour de la note pour l'établissement " + establishmentId + " par l'utilisateur " + userId);
|
||||
|
||||
// Récupérer la note existante
|
||||
EstablishmentRating rating = ratingRepository.findByEstablishmentIdAndUserId(establishmentId, userId);
|
||||
if (rating == null) {
|
||||
LOG.error("Note non trouvée pour l'établissement " + establishmentId + " et l'utilisateur " + userId);
|
||||
throw new RuntimeException("Note non trouvée. Utilisez la soumission pour créer une nouvelle note.");
|
||||
}
|
||||
|
||||
// Mettre à jour la note
|
||||
rating.updateRating(requestDTO.getRating(), requestDTO.getComment());
|
||||
ratingRepository.persist(rating);
|
||||
|
||||
// Mettre à jour les statistiques de l'établissement
|
||||
updateEstablishmentRatingStats(establishmentId);
|
||||
|
||||
LOG.info("Note mise à jour avec succès : " + rating.getId());
|
||||
return rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la note d'un utilisateur pour un établissement.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @param userId L'ID de l'utilisateur
|
||||
* @return La note de l'utilisateur ou null si pas encore noté
|
||||
*/
|
||||
public EstablishmentRating getUserRating(UUID establishmentId, UUID userId) {
|
||||
LOG.info("Récupération de la note de l'utilisateur " + userId + " pour l'établissement " + establishmentId);
|
||||
return ratingRepository.findByEstablishmentIdAndUserId(establishmentId, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les statistiques de notation d'un établissement.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
* @return Map contenant averageRating, totalRatings et distribution
|
||||
*/
|
||||
public Map<String, Object> getRatingStats(UUID establishmentId) {
|
||||
LOG.info("Récupération des statistiques de notation pour l'établissement " + establishmentId);
|
||||
|
||||
Double averageRating = ratingRepository.calculateAverageRating(establishmentId);
|
||||
Long totalRatings = ratingRepository.countByEstablishmentId(establishmentId);
|
||||
Map<Integer, Integer> distribution = ratingRepository.calculateRatingDistribution(establishmentId);
|
||||
|
||||
return Map.of(
|
||||
"averageRating", averageRating,
|
||||
"totalRatingsCount", totalRatings.intValue(),
|
||||
"ratingDistribution", distribution
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour les statistiques de notation d'un établissement.
|
||||
* Cette méthode est appelée après chaque création/modification de note.
|
||||
* Note: Cette méthode est appelée depuis des méthodes déjà transactionnelles,
|
||||
* donc pas besoin de l'annotation @Transactional ici.
|
||||
*
|
||||
* @param establishmentId L'ID de l'établissement
|
||||
*/
|
||||
private void updateEstablishmentRatingStats(UUID establishmentId) {
|
||||
Establishment establishment = establishmentRepository.findById(establishmentId);
|
||||
if (establishment == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Double averageRating = ratingRepository.calculateAverageRating(establishmentId);
|
||||
Long totalRatings = ratingRepository.countByEstablishmentId(establishmentId);
|
||||
|
||||
establishment.setAverageRating(averageRating);
|
||||
establishment.setTotalRatingsCount(totalRatings.intValue());
|
||||
establishmentRepository.persist(establishment);
|
||||
|
||||
LOG.info("Statistiques mises à jour pour l'établissement " + establishmentId + " : moyenne = " + averageRating + ", total = " + totalRatings);
|
||||
}
|
||||
}
|
||||
|
||||
194
src/main/java/com/lions/dev/service/EstablishmentService.java
Normal file
194
src/main/java/com/lions/dev/service/EstablishmentService.java
Normal file
@@ -0,0 +1,194 @@
|
||||
package com.lions.dev.service;
|
||||
|
||||
import com.lions.dev.entity.establishment.Establishment;
|
||||
import com.lions.dev.entity.users.Users;
|
||||
import com.lions.dev.repository.EstablishmentRepository;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Service de gestion des établissements.
|
||||
* Ce service contient la logique métier pour la création, récupération,
|
||||
* mise à jour et suppression des établissements.
|
||||
* Seuls les responsables d'établissement peuvent créer et gérer des établissements.
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class EstablishmentService {
|
||||
|
||||
@Inject
|
||||
EstablishmentRepository establishmentRepository;
|
||||
|
||||
@Inject
|
||||
UsersRepository usersRepository;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(EstablishmentService.class);
|
||||
|
||||
/**
|
||||
* Crée un nouvel établissement.
|
||||
*
|
||||
* @param establishment L'établissement à créer.
|
||||
* @param managerId L'ID du responsable de l'établissement.
|
||||
* @return L'établissement créé.
|
||||
*/
|
||||
@Transactional
|
||||
public Establishment createEstablishment(Establishment establishment, UUID managerId) {
|
||||
LOG.info("[LOG] Création d'un nouvel établissement : " + establishment.getName());
|
||||
|
||||
// Vérifier que le manager existe
|
||||
Users manager = usersRepository.findById(managerId);
|
||||
if (manager == null) {
|
||||
LOG.error("[ERROR] Responsable non trouvé avec l'ID : " + managerId);
|
||||
throw new RuntimeException("Responsable non trouvé avec l'ID fourni");
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur a le rôle de responsable d'établissement
|
||||
String role = manager.getRole() != null ? manager.getRole().toUpperCase() : "";
|
||||
if (!role.equals("ESTABLISHMENT_MANAGER") &&
|
||||
!role.equals("MANAGER") &&
|
||||
!role.equals("ADMIN")) {
|
||||
LOG.error("[ERROR] L'utilisateur " + managerId + " n'a pas les droits pour créer un établissement. Rôle : " + role);
|
||||
throw new RuntimeException("Seuls les responsables d'établissement peuvent créer des établissements");
|
||||
}
|
||||
|
||||
establishment.setManager(manager);
|
||||
establishmentRepository.persist(establishment);
|
||||
LOG.info("[LOG] Établissement créé avec succès : " + establishment.getName());
|
||||
return establishment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère tous les établissements.
|
||||
*
|
||||
* @return Une liste de tous les établissements.
|
||||
*/
|
||||
public List<Establishment> getAllEstablishments() {
|
||||
LOG.info("[LOG] Récupération de tous les établissements");
|
||||
List<Establishment> establishments = establishmentRepository.listAll();
|
||||
LOG.info("[LOG] Nombre d'établissements trouvés : " + establishments.size());
|
||||
return establishments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère un établissement par son ID.
|
||||
*
|
||||
* @param id L'ID de l'établissement.
|
||||
* @return L'établissement trouvé.
|
||||
*/
|
||||
public Establishment getEstablishmentById(UUID id) {
|
||||
LOG.info("[LOG] Récupération de l'établissement avec l'ID : " + id);
|
||||
Establishment establishment = establishmentRepository.findById(id);
|
||||
if (establishment == null) {
|
||||
LOG.warn("[WARN] Établissement non trouvé avec l'ID : " + id);
|
||||
throw new RuntimeException("Établissement non trouvé avec l'ID : " + id);
|
||||
}
|
||||
return establishment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour un établissement existant.
|
||||
*
|
||||
* @param id L'ID de l'établissement à mettre à jour.
|
||||
* @param updatedEstablishment L'établissement avec les nouvelles données.
|
||||
* @return L'établissement mis à jour.
|
||||
*/
|
||||
@Transactional
|
||||
public Establishment updateEstablishment(UUID id, Establishment updatedEstablishment) {
|
||||
LOG.info("[LOG] Mise à jour de l'établissement avec l'ID : " + id);
|
||||
Establishment establishment = establishmentRepository.findById(id);
|
||||
if (establishment == null) {
|
||||
LOG.error("[ERROR] Établissement non trouvé avec l'ID : " + id);
|
||||
throw new RuntimeException("Établissement non trouvé avec l'ID : " + id);
|
||||
}
|
||||
|
||||
// Mettre à jour les champs
|
||||
establishment.setName(updatedEstablishment.getName());
|
||||
establishment.setType(updatedEstablishment.getType());
|
||||
establishment.setAddress(updatedEstablishment.getAddress());
|
||||
establishment.setCity(updatedEstablishment.getCity());
|
||||
establishment.setPostalCode(updatedEstablishment.getPostalCode());
|
||||
establishment.setDescription(updatedEstablishment.getDescription());
|
||||
establishment.setPhoneNumber(updatedEstablishment.getPhoneNumber());
|
||||
establishment.setEmail(updatedEstablishment.getEmail());
|
||||
establishment.setWebsite(updatedEstablishment.getWebsite());
|
||||
establishment.setImageUrl(updatedEstablishment.getImageUrl());
|
||||
establishment.setRating(updatedEstablishment.getRating());
|
||||
establishment.setPriceRange(updatedEstablishment.getPriceRange());
|
||||
establishment.setCapacity(updatedEstablishment.getCapacity());
|
||||
establishment.setAmenities(updatedEstablishment.getAmenities());
|
||||
establishment.setOpeningHours(updatedEstablishment.getOpeningHours());
|
||||
establishment.setLatitude(updatedEstablishment.getLatitude());
|
||||
establishment.setLongitude(updatedEstablishment.getLongitude());
|
||||
|
||||
establishmentRepository.persist(establishment);
|
||||
LOG.info("[LOG] Établissement mis à jour avec succès : " + establishment.getName());
|
||||
return establishment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un établissement.
|
||||
*
|
||||
* @param id L'ID de l'établissement à supprimer.
|
||||
*/
|
||||
@Transactional
|
||||
public void deleteEstablishment(UUID id) {
|
||||
LOG.info("[LOG] Suppression de l'établissement avec l'ID : " + id);
|
||||
Establishment establishment = establishmentRepository.findById(id);
|
||||
if (establishment == null) {
|
||||
LOG.error("[ERROR] Établissement non trouvé avec l'ID : " + id);
|
||||
throw new RuntimeException("Établissement non trouvé avec l'ID : " + id);
|
||||
}
|
||||
establishmentRepository.delete(establishment);
|
||||
LOG.info("[LOG] Établissement supprimé avec succès : " + establishment.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les établissements gérés par un responsable.
|
||||
*
|
||||
* @param managerId L'ID du responsable.
|
||||
* @return Une liste d'établissements gérés par ce responsable.
|
||||
*/
|
||||
public List<Establishment> getEstablishmentsByManager(UUID managerId) {
|
||||
LOG.info("[LOG] Récupération des établissements du responsable : " + managerId);
|
||||
List<Establishment> establishments = establishmentRepository.findByManagerId(managerId);
|
||||
LOG.info("[LOG] Nombre d'établissements trouvés : " + establishments.size());
|
||||
return establishments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recherche des établissements par nom ou ville.
|
||||
*
|
||||
* @param query Le terme de recherche.
|
||||
* @return Une liste d'établissements correspondant à la recherche.
|
||||
*/
|
||||
public List<Establishment> searchEstablishments(String query) {
|
||||
LOG.info("[LOG] Recherche d'établissements avec la requête : " + query);
|
||||
List<Establishment> establishments = establishmentRepository.searchByNameOrCity(query);
|
||||
LOG.info("[LOG] Nombre d'établissements trouvés : " + establishments.size());
|
||||
return establishments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtre les établissements par type, fourchette de prix et/ou ville.
|
||||
*
|
||||
* @param type Le type d'établissement (optionnel).
|
||||
* @param priceRange La fourchette de prix (optionnel).
|
||||
* @param city La ville (optionnel).
|
||||
* @return Une liste d'établissements correspondant aux filtres.
|
||||
*/
|
||||
public List<Establishment> filterEstablishments(String type, String priceRange, String city) {
|
||||
LOG.info("[LOG] Filtrage des établissements : type=" + type + ", priceRange=" + priceRange + ", city=" + city);
|
||||
List<Establishment> allEstablishments = establishmentRepository.listAll();
|
||||
|
||||
return allEstablishments.stream()
|
||||
.filter(e -> type == null || e.getType().equalsIgnoreCase(type))
|
||||
.filter(e -> priceRange == null || (e.getPriceRange() != null && e.getPriceRange().equalsIgnoreCase(priceRange)))
|
||||
.filter(e -> city == null || e.getCity().equalsIgnoreCase(city))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user