Files
afterwork-server-impl-quarkus/src/main/java/com/lions/dev/service/EstablishmentRatingService.java

168 lines
7.0 KiB
Java

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);
}
}