feat: Extension des événements avec 10 nouveaux champs - Ajout de maxParticipants, tags, organizer, participationFee - Ajout de privacyRules, transportInfo, accommodationInfo - Ajout de accessibilityInfo, parkingInfo, securityProtocol - Mise à jour des DTOs et services - Vérification des permissions pour le CRUD (créateur uniquement) - Ajout de creatorId dans EventCreateResponseDTO
This commit is contained in:
@@ -33,6 +33,17 @@ public class EventCreateRequestDTO {
|
|||||||
private String link; // Lien d'information supplémentaire
|
private String link; // Lien d'information supplémentaire
|
||||||
private String imageUrl; // URL de l'image associée à l'événement
|
private String imageUrl; // URL de l'image associée à l'événement
|
||||||
|
|
||||||
|
private Integer maxParticipants; // Nombre maximum de participants autorisés
|
||||||
|
private String tags; // Tags/mots-clés associés à l'événement (séparés par des virgules)
|
||||||
|
private String organizer; // Nom de l'organisateur de l'événement
|
||||||
|
private Integer participationFee; // Frais de participation en centimes
|
||||||
|
private String privacyRules; // Règles de confidentialité de l'événement
|
||||||
|
private String transportInfo; // Informations sur les transports disponibles
|
||||||
|
private String accommodationInfo; // Informations sur l'hébergement
|
||||||
|
private String accessibilityInfo; // Informations sur l'accessibilité
|
||||||
|
private String parkingInfo; // Informations sur le parking
|
||||||
|
private String securityProtocol; // Protocole de sécurité de l'événement
|
||||||
|
|
||||||
@NotNull(message = "L'identifiant du créateur est obligatoire.")
|
@NotNull(message = "L'identifiant du créateur est obligatoire.")
|
||||||
private UUID creatorId; // Identifiant du créateur de l'événement
|
private UUID creatorId; // Identifiant du créateur de l'événement
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public class EventCreateResponseDTO {
|
|||||||
private String category; // Catégorie de l'événement
|
private String category; // Catégorie de l'événement
|
||||||
private String link; // Lien vers plus d'informations
|
private String link; // Lien vers plus d'informations
|
||||||
private String imageUrl; // URL d'une image pour l'événement
|
private String imageUrl; // URL d'une image pour l'événement
|
||||||
|
private String creatorId; // ID du créateur de l'événement
|
||||||
private String creatorEmail; // Email du créateur de l'événement
|
private String creatorEmail; // Email du créateur de l'événement
|
||||||
private String creatorFirstName; // Prénom du créateur de l'événement
|
private String creatorFirstName; // Prénom du créateur de l'événement
|
||||||
private String creatorLastName; // Nom de famille du création de l'événement
|
private String creatorLastName; // Nom de famille du création de l'événement
|
||||||
@@ -40,6 +41,7 @@ public class EventCreateResponseDTO {
|
|||||||
this.category = event.getCategory();
|
this.category = event.getCategory();
|
||||||
this.link = event.getLink();
|
this.link = event.getLink();
|
||||||
this.imageUrl = event.getImageUrl();
|
this.imageUrl = event.getImageUrl();
|
||||||
|
this.creatorId = event.getCreator().getId().toString();
|
||||||
this.creatorEmail = event.getCreator().getEmail();
|
this.creatorEmail = event.getCreator().getEmail();
|
||||||
this.creatorFirstName = event.getCreator().getPrenoms();
|
this.creatorFirstName = event.getCreator().getPrenoms();
|
||||||
this.creatorLastName = event.getCreator().getNom();
|
this.creatorLastName = event.getCreator().getNom();
|
||||||
|
|||||||
@@ -55,6 +55,36 @@ public class Events extends BaseEntity {
|
|||||||
@Column(name = "status", nullable = false)
|
@Column(name = "status", nullable = false)
|
||||||
private String status = "ouvert"; // Le statut de l'événement (en cours, terminé, annulé, etc.)
|
private String status = "ouvert"; // Le statut de l'événement (en cours, terminé, annulé, etc.)
|
||||||
|
|
||||||
|
@Column(name = "max_participants")
|
||||||
|
private Integer maxParticipants; // Nombre maximum de participants autorisés
|
||||||
|
|
||||||
|
@Column(name = "tags", length = 500)
|
||||||
|
private String tags; // Tags/mots-clés associés à l'événement (séparés par des virgules)
|
||||||
|
|
||||||
|
@Column(name = "organizer", length = 200)
|
||||||
|
private String organizer; // Nom de l'organisateur de l'événement
|
||||||
|
|
||||||
|
@Column(name = "participation_fee")
|
||||||
|
private Integer participationFee; // Frais de participation en centimes
|
||||||
|
|
||||||
|
@Column(name = "privacy_rules", length = 1000)
|
||||||
|
private String privacyRules; // Règles de confidentialité de l'événement
|
||||||
|
|
||||||
|
@Column(name = "transport_info", length = 1000)
|
||||||
|
private String transportInfo; // Informations sur les transports disponibles
|
||||||
|
|
||||||
|
@Column(name = "accommodation_info", length = 1000)
|
||||||
|
private String accommodationInfo; // Informations sur l'hébergement
|
||||||
|
|
||||||
|
@Column(name = "accessibility_info", length = 1000)
|
||||||
|
private String accessibilityInfo; // Informations sur l'accessibilité
|
||||||
|
|
||||||
|
@Column(name = "parking_info", length = 1000)
|
||||||
|
private String parkingInfo; // Informations sur le parking
|
||||||
|
|
||||||
|
@Column(name = "security_protocol", length = 1000)
|
||||||
|
private String securityProtocol; // Protocole de sécurité de l'événement
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "creator_id", nullable = false)
|
@JoinColumn(name = "creator_id", nullable = false)
|
||||||
private Users creator; // L'utilisateur créateur de l'événement
|
private Users creator; // L'utilisateur créateur de l'événement
|
||||||
|
|||||||
@@ -66,11 +66,25 @@ public class EventsResource {
|
|||||||
@Operation(summary = "Créer un nouvel événement", description = "Crée un nouvel événement et retourne ses détails")
|
@Operation(summary = "Créer un nouvel événement", description = "Crée un nouvel événement et retourne ses détails")
|
||||||
public Response createEvent(EventCreateRequestDTO eventCreateRequestDTO) {
|
public Response createEvent(EventCreateRequestDTO eventCreateRequestDTO) {
|
||||||
LOG.info("[LOG] Tentative de création d'un nouvel événement : " + eventCreateRequestDTO.getTitle());
|
LOG.info("[LOG] Tentative de création d'un nouvel événement : " + eventCreateRequestDTO.getTitle());
|
||||||
|
|
||||||
|
// Valider que creatorId est fourni
|
||||||
|
if (eventCreateRequestDTO.getCreatorId() == null) {
|
||||||
|
LOG.error("[ERROR] creatorId est obligatoire pour créer un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
.entity("L'identifiant du créateur (creatorId) est obligatoire")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupérer le créateur par son ID
|
||||||
Users creator = usersRepository.findById(eventCreateRequestDTO.getCreatorId());
|
Users creator = usersRepository.findById(eventCreateRequestDTO.getCreatorId());
|
||||||
if (creator == null) {
|
if (creator == null) {
|
||||||
LOG.error("[ERROR] Créateur non trouvé avec l'ID : " + eventCreateRequestDTO.getCreatorId());
|
LOG.error("[ERROR] Créateur non trouvé avec l'ID : " + eventCreateRequestDTO.getCreatorId());
|
||||||
return Response.status(Response.Status.BAD_REQUEST).entity("Créateur non trouvé").build();
|
return Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
.entity("Créateur non trouvé avec l'ID fourni")
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Créer l'événement
|
||||||
Events event = eventService.createEvent(eventCreateRequestDTO, creator);
|
Events event = eventService.createEvent(eventCreateRequestDTO, creator);
|
||||||
LOG.info("[LOG] Événement créé avec succès : " + event.getTitle());
|
LOG.info("[LOG] Événement créé avec succès : " + event.getTitle());
|
||||||
EventCreateResponseDTO responseDTO = new EventCreateResponseDTO(event);
|
EventCreateResponseDTO responseDTO = new EventCreateResponseDTO(event);
|
||||||
@@ -100,10 +114,16 @@ public class EventsResource {
|
|||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
@Transactional
|
@Transactional
|
||||||
@Operation(summary = "Supprimer un événement", description = "Supprime un événement de la base de données")
|
@Operation(summary = "Supprimer un événement", description = "Supprime un événement de la base de données")
|
||||||
public Response deleteEvent(@PathParam("id") UUID id) {
|
public Response deleteEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId) {
|
||||||
LOG.info("Tentative de suppression de l'événement avec l'ID : " + id);
|
LOG.info("Tentative de suppression de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
LOG.error("[ERROR] userId est obligatoire pour supprimer un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean deleted = eventService.deleteEvent(id);
|
boolean deleted = eventService.deleteEvent(id, userId);
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
LOG.info("Événement supprimé avec succès.");
|
LOG.info("Événement supprimé avec succès.");
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
@@ -114,6 +134,9 @@ public class EventsResource {
|
|||||||
} catch (EventNotFoundException e) {
|
} catch (EventNotFoundException e) {
|
||||||
LOG.error("[ERROR] Échec de la suppression : " + e.getMessage());
|
LOG.error("[ERROR] Échec de la suppression : " + e.getMessage());
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
LOG.error("[ERROR] Permissions insuffisantes : " + e.getMessage());
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity(e.getMessage()).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,13 +189,26 @@ public class EventsResource {
|
|||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
@Transactional
|
@Transactional
|
||||||
@Operation(summary = "Mettre à jour un événement", description = "Modifie un événement existant")
|
@Operation(summary = "Mettre à jour un événement", description = "Modifie un événement existant")
|
||||||
public Response updateEvent(@PathParam("id") UUID id, EventUpdateRequestDTO eventUpdateRequestDTO) {
|
public Response updateEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId, EventUpdateRequestDTO eventUpdateRequestDTO) {
|
||||||
LOG.info("[LOG] Tentative de mise à jour de l'événement avec l'ID : " + id);
|
LOG.info("[LOG] Tentative de mise à jour de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
LOG.error("[ERROR] userId est obligatoire pour mettre à jour un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
|
||||||
|
}
|
||||||
|
|
||||||
Events event = eventsRepository.findById(id);
|
Events event = eventsRepository.findById(id);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
|
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!eventService.canModifyEvent(event, userId)) {
|
||||||
|
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier l'événement " + id);
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
|
||||||
|
}
|
||||||
|
|
||||||
// Mise à jour des attributs de l'événement
|
// Mise à jour des attributs de l'événement
|
||||||
event.setTitle(eventUpdateRequestDTO.getTitle());
|
event.setTitle(eventUpdateRequestDTO.getTitle());
|
||||||
event.setStartDate(eventUpdateRequestDTO.getStartDate());
|
event.setStartDate(eventUpdateRequestDTO.getStartDate());
|
||||||
@@ -206,18 +242,20 @@ public class EventsResource {
|
|||||||
try {
|
try {
|
||||||
List<FriendshipReadFriendDetailsResponseDTO> friends = friendshipService.listFriends(userId, 0, Integer.MAX_VALUE);
|
List<FriendshipReadFriendDetailsResponseDTO> friends = friendshipService.listFriends(userId, 0, Integer.MAX_VALUE);
|
||||||
Set<UUID> friendIds = friends.stream().map(FriendshipReadFriendDetailsResponseDTO::getFriendId).collect(Collectors.toSet());
|
Set<UUID> friendIds = friends.stream().map(FriendshipReadFriendDetailsResponseDTO::getFriendId).collect(Collectors.toSet());
|
||||||
//friendIds = friendIds.stream().distinct().collect(Collectors.toSet());
|
|
||||||
LOG.info("[LOG] IDs d'amis + utilisateur (taille attendue: " + friendIds.size() + ") : " + friendIds);
|
// IMPORTANT: Ajouter l'ID de l'utilisateur lui-même pour inclure ses propres événements
|
||||||
if (friendIds.isEmpty()) {
|
friendIds.add(userId);
|
||||||
LOG.warn("[LOG] Aucun ami trouvé.");
|
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity("Aucun ami trouvé.").build();
|
LOG.info("[LOG] IDs d'amis + utilisateur (taille: " + friendIds.size() + ") : " + friendIds);
|
||||||
}
|
|
||||||
|
// Rechercher les événements créés par l'utilisateur et ses amis
|
||||||
List<Events> events = eventsRepository.find("creator.id IN ?1", friendIds).list();
|
List<Events> events = eventsRepository.find("creator.id IN ?1", friendIds).list();
|
||||||
LOG.info("[LOG] Nombre d'événements récupérés dans la requête : " + events.size());
|
LOG.info("[LOG] Nombre d'événements récupérés dans la requête : " + events.size());
|
||||||
if (events.isEmpty()) {
|
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity("Aucun événement trouvé.").build();
|
// Retourner une liste vide si aucun événement trouvé (pas d'erreur 404)
|
||||||
}
|
List<EventReadManyByIdResponseDTO> responseDTOs = events.stream()
|
||||||
List<EventReadManyByIdResponseDTO> responseDTOs = events.stream().map(EventReadManyByIdResponseDTO::new).toList();
|
.map(EventReadManyByIdResponseDTO::new)
|
||||||
|
.toList();
|
||||||
return Response.ok(responseDTOs).build();
|
return Response.ok(responseDTOs).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("[ERROR] Erreur de récupération des événements : ", e);
|
LOG.error("[ERROR] Erreur de récupération des événements : ", e);
|
||||||
@@ -366,13 +404,26 @@ public class EventsResource {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Mettre à jour le statut d'un événement",
|
summary = "Mettre à jour le statut d'un événement",
|
||||||
description = "Modifie le statut d'un événement (ouvert, fermé, annulé, etc.)")
|
description = "Modifie le statut d'un événement (ouvert, fermé, annulé, etc.)")
|
||||||
public Response updateEventStatus(@PathParam("id") UUID id, @QueryParam("status") String status) {
|
public Response updateEventStatus(@PathParam("id") UUID id, @QueryParam("status") String status, @QueryParam("userId") UUID userId) {
|
||||||
LOG.info("[LOG] Mise à jour du statut de l'événement avec l'ID : " + id);
|
LOG.info("[LOG] Mise à jour du statut de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
LOG.error("[ERROR] userId est obligatoire pour mettre à jour le statut d'un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
|
||||||
|
}
|
||||||
|
|
||||||
Events event = eventsRepository.findById(id);
|
Events event = eventsRepository.findById(id);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
|
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
|
||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!eventService.canModifyEvent(event, userId)) {
|
||||||
|
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier le statut de l'événement " + id);
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
|
||||||
|
}
|
||||||
|
|
||||||
event.setStatus(status);
|
event.setStatus(status);
|
||||||
eventsRepository.persist(event);
|
eventsRepository.persist(event);
|
||||||
LOG.info("[LOG] Statut de l'événement mis à jour avec succès : " + status);
|
LOG.info("[LOG] Statut de l'événement mis à jour avec succès : " + status);
|
||||||
@@ -423,8 +474,13 @@ public class EventsResource {
|
|||||||
*/
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/{id}/image")
|
@Path("/{id}/image")
|
||||||
public Response updateEventImage(@PathParam("id") UUID id, String imageFilePath) {
|
public Response updateEventImage(@PathParam("id") UUID id, @QueryParam("userId") UUID userId, String imageFilePath) {
|
||||||
LOG.info("[LOG] Tentative de mise à jour de l'image pour l'événement avec l'ID : " + id);
|
LOG.info("[LOG] Tentative de mise à jour de l'image pour l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
LOG.error("[ERROR] userId est obligatoire pour mettre à jour l'image d'un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (imageFilePath == null || imageFilePath.isEmpty()) {
|
if (imageFilePath == null || imageFilePath.isEmpty()) {
|
||||||
@@ -444,9 +500,15 @@ public class EventsResource {
|
|||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!eventService.canModifyEvent(event, userId)) {
|
||||||
|
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier l'image de l'événement " + id);
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
|
||||||
|
}
|
||||||
|
|
||||||
String imageUrl = file.getAbsolutePath();
|
String imageUrl = file.getAbsolutePath();
|
||||||
event.setImageUrl(imageUrl);
|
event.setImageUrl(imageUrl);
|
||||||
eventService.updateEvent(event);
|
eventService.updateEvent(event, userId);
|
||||||
|
|
||||||
LOG.info("[LOG] Image de l'événement mise à jour avec succès pour : " + event.getTitle());
|
LOG.info("[LOG] Image de l'événement mise à jour avec succès pour : " + event.getTitle());
|
||||||
return Response.ok("Image de l'événement mise à jour avec succès.").build();
|
return Response.ok("Image de l'événement mise à jour avec succès.").build();
|
||||||
@@ -461,8 +523,13 @@ public class EventsResource {
|
|||||||
@Path("/{id}/partial-update")
|
@Path("/{id}/partial-update")
|
||||||
@Transactional
|
@Transactional
|
||||||
@Operation(summary = "Mettre à jour partiellement un événement", description = "Mise à jour partielle des informations d'un événement")
|
@Operation(summary = "Mettre à jour partiellement un événement", description = "Mise à jour partielle des informations d'un événement")
|
||||||
public Response partialUpdateEvent(@PathParam("id") UUID id, Map<String, Object> updates) {
|
public Response partialUpdateEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId, Map<String, Object> updates) {
|
||||||
LOG.info("[LOG] Tentative de mise à jour partielle de l'événement avec l'ID : " + id);
|
LOG.info("[LOG] Tentative de mise à jour partielle de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
LOG.error("[ERROR] userId est obligatoire pour mettre à jour un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
|
||||||
|
}
|
||||||
|
|
||||||
Events event = eventsRepository.findById(id);
|
Events event = eventsRepository.findById(id);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
@@ -470,9 +537,39 @@ public class EventsResource {
|
|||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!eventService.canModifyEvent(event, userId)) {
|
||||||
|
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier l'événement " + id);
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mise à jour des champs dynamiquement
|
||||||
updates.forEach((field, value) -> {
|
updates.forEach((field, value) -> {
|
||||||
// Mise à jour des champs dynamiquement, à adapter selon la structure de l'événement
|
switch (field) {
|
||||||
// Exemple d'utilisation de réflexion si applicable
|
case "title":
|
||||||
|
event.setTitle(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
case "description":
|
||||||
|
event.setDescription(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
case "location":
|
||||||
|
event.setLocation(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
case "category":
|
||||||
|
event.setCategory(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
case "link":
|
||||||
|
event.setLink(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
case "imageUrl":
|
||||||
|
event.setImageUrl(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
case "status":
|
||||||
|
event.setStatus(value != null ? value.toString() : null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG.warn("[LOG] Champ inconnu ignoré lors de la mise à jour partielle : " + field);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
eventsRepository.persist(event);
|
eventsRepository.persist(event);
|
||||||
@@ -519,8 +616,13 @@ public class EventsResource {
|
|||||||
@Path("/{id}/cancel")
|
@Path("/{id}/cancel")
|
||||||
@Transactional
|
@Transactional
|
||||||
@Operation(summary = "Annuler un événement", description = "Annule un événement sans le supprimer.")
|
@Operation(summary = "Annuler un événement", description = "Annule un événement sans le supprimer.")
|
||||||
public Response cancelEvent(@PathParam("id") UUID id) {
|
public Response cancelEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId) {
|
||||||
LOG.info("[LOG] Annulation de l'événement avec l'ID : " + id);
|
LOG.info("[LOG] Annulation de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
LOG.error("[ERROR] userId est obligatoire pour annuler un événement");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
|
||||||
|
}
|
||||||
|
|
||||||
Events event = eventsRepository.findById(id);
|
Events event = eventsRepository.findById(id);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
@@ -528,6 +630,12 @@ public class EventsResource {
|
|||||||
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!eventService.canModifyEvent(event, userId)) {
|
||||||
|
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour annuler l'événement " + id);
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour annuler cet événement").build();
|
||||||
|
}
|
||||||
|
|
||||||
event.setStatus("Annulé");
|
event.setStatus("Annulé");
|
||||||
eventsRepository.persist(event);
|
eventsRepository.persist(event);
|
||||||
LOG.info("[LOG] Événement annulé avec succès : " + event.getTitle());
|
LOG.info("[LOG] Événement annulé avec succès : " + event.getTitle());
|
||||||
@@ -716,6 +824,50 @@ public class EventsResource {
|
|||||||
return Response.ok(responseDTOs).build();
|
return Response.ok(responseDTOs).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{id}/comments")
|
||||||
|
@Transactional
|
||||||
|
@Operation(summary = "Ajouter un commentaire à un événement", description = "Crée un nouveau commentaire pour un événement.")
|
||||||
|
public Response addComment(
|
||||||
|
@PathParam("id") UUID eventId,
|
||||||
|
@QueryParam("userId") UUID userId,
|
||||||
|
Map<String, String> requestBody) {
|
||||||
|
LOG.info("[LOG] Ajout d'un commentaire à l'événement ID : " + eventId + " par l'utilisateur ID : " + userId);
|
||||||
|
|
||||||
|
Events event = eventsRepository.findById(eventId);
|
||||||
|
if (event == null) {
|
||||||
|
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + eventId);
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
Users user = usersRepository.findById(userId);
|
||||||
|
if (user == null) {
|
||||||
|
LOG.warn("[LOG] Utilisateur non trouvé avec l'ID : " + userId);
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).entity("Utilisateur non trouvé.").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
String text = requestBody.get("text");
|
||||||
|
if (text == null || text.trim().isEmpty()) {
|
||||||
|
LOG.warn("[LOG] Le texte du commentaire est vide");
|
||||||
|
return Response.status(Response.Status.BAD_REQUEST).entity("Le texte du commentaire est requis.").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Comment comment = new Comment(user, event, text);
|
||||||
|
// Le commentaire sera automatiquement ajouté à la liste des commentaires de l'événement via la relation JPA
|
||||||
|
eventsRepository.persist(event);
|
||||||
|
|
||||||
|
LOG.info("[LOG] Commentaire ajouté avec succès à l'événement : " + event.getTitle());
|
||||||
|
|
||||||
|
CommentResponseDTO responseDTO = new CommentResponseDTO(comment);
|
||||||
|
return Response.status(Response.Status.CREATED).entity(responseDTO).build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("[ERROR] Erreur lors de l'ajout du commentaire : " + e.getMessage(), e);
|
||||||
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||||
|
.entity("Erreur lors de l'ajout du commentaire.").build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/recommendations/{userId}")
|
@Path("/recommendations/{userId}")
|
||||||
@Operation(summary = "Recommander des événements basés sur les intérêts", description = "Retourne une liste d'événements recommandés pour un utilisateur.")
|
@Operation(summary = "Recommander des événements basés sur les intérêts", description = "Retourne une liste d'événements recommandés pour un utilisateur.")
|
||||||
|
|||||||
@@ -59,6 +59,16 @@ public class EventService {
|
|||||||
event.setCategory(eventCreateRequestDTO.getCategory());
|
event.setCategory(eventCreateRequestDTO.getCategory());
|
||||||
event.setLink(eventCreateRequestDTO.getLink());
|
event.setLink(eventCreateRequestDTO.getLink());
|
||||||
event.setImageUrl(eventCreateRequestDTO.getImageUrl());
|
event.setImageUrl(eventCreateRequestDTO.getImageUrl());
|
||||||
|
event.setMaxParticipants(eventCreateRequestDTO.getMaxParticipants());
|
||||||
|
event.setTags(eventCreateRequestDTO.getTags());
|
||||||
|
event.setOrganizer(eventCreateRequestDTO.getOrganizer());
|
||||||
|
event.setParticipationFee(eventCreateRequestDTO.getParticipationFee());
|
||||||
|
event.setPrivacyRules(eventCreateRequestDTO.getPrivacyRules());
|
||||||
|
event.setTransportInfo(eventCreateRequestDTO.getTransportInfo());
|
||||||
|
event.setAccommodationInfo(eventCreateRequestDTO.getAccommodationInfo());
|
||||||
|
event.setAccessibilityInfo(eventCreateRequestDTO.getAccessibilityInfo());
|
||||||
|
event.setParkingInfo(eventCreateRequestDTO.getParkingInfo());
|
||||||
|
event.setSecurityProtocol(eventCreateRequestDTO.getSecurityProtocol());
|
||||||
event.setCreator(creator);
|
event.setCreator(creator);
|
||||||
event.setStatus("ouvert");
|
event.setStatus("ouvert");
|
||||||
|
|
||||||
@@ -132,33 +142,60 @@ public class EventService {
|
|||||||
* Supprime un événement par son ID.
|
* Supprime un événement par son ID.
|
||||||
*
|
*
|
||||||
* @param id L'ID de l'événement à supprimer.
|
* @param id L'ID de l'événement à supprimer.
|
||||||
|
* @param userId L'ID de l'utilisateur qui tente de supprimer l'événement.
|
||||||
* @return true si l'événement a été supprimé, false sinon.
|
* @return true si l'événement a été supprimé, false sinon.
|
||||||
* @throws EventNotFoundException Si l'événement n'est pas trouvé.
|
* @throws EventNotFoundException Si l'événement n'est pas trouvé.
|
||||||
|
* @throws SecurityException Si l'utilisateur n'est pas le créateur de l'événement.
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public boolean deleteEvent(UUID id) {
|
public boolean deleteEvent(UUID id, UUID userId) {
|
||||||
logger.info("[logger] Tentative de suppression de l'événement avec l'ID : {}", id);
|
logger.info("[logger] Tentative de suppression de l'événement avec l'ID : {} par l'utilisateur : {}", id, userId);
|
||||||
|
|
||||||
|
Events event = eventsRepository.findById(id);
|
||||||
|
if (event == null) {
|
||||||
|
logger.warn("[logger] Échec de la suppression : événement avec l'ID {} introuvable.", id);
|
||||||
|
throw new EventNotFoundException(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!canModifyEvent(event, userId)) {
|
||||||
|
logger.error("[ERROR] L'utilisateur {} n'a pas les permissions pour supprimer l'événement {}", userId, id);
|
||||||
|
throw new SecurityException("Vous n'avez pas les permissions pour supprimer cet événement");
|
||||||
|
}
|
||||||
|
|
||||||
boolean deleted = eventsRepository.deleteById(id);
|
boolean deleted = eventsRepository.deleteById(id);
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
logger.info("[logger] Événement avec l'ID {} supprimé avec succès.", id);
|
logger.info("[logger] Événement avec l'ID {} supprimé avec succès.", id);
|
||||||
} else {
|
|
||||||
logger.warn("[logger] Échec de la suppression : événement avec l'ID {} introuvable.", id);
|
|
||||||
throw new EventNotFoundException(id);
|
|
||||||
}
|
}
|
||||||
return deleted;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si un utilisateur peut modifier un événement.
|
||||||
|
*
|
||||||
|
* @param event L'événement à vérifier.
|
||||||
|
* @param userId L'ID de l'utilisateur.
|
||||||
|
* @return true si l'utilisateur peut modifier l'événement, false sinon.
|
||||||
|
*/
|
||||||
|
public boolean canModifyEvent(Events event, UUID userId) {
|
||||||
|
if (event == null || event.getCreator() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return event.getCreator().getId().equals(userId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Met à jour un événement dans le système.
|
* Met à jour un événement dans le système.
|
||||||
*
|
*
|
||||||
* @param event L'événement contenant les détails mis à jour.
|
* @param event L'événement contenant les détails mis à jour.
|
||||||
|
* @param userId L'ID de l'utilisateur qui tente de mettre à jour l'événement.
|
||||||
* @return L'événement mis à jour.
|
* @return L'événement mis à jour.
|
||||||
* @throws EventNotFoundException Si l'événement n'est pas trouvé.
|
* @throws EventNotFoundException Si l'événement n'est pas trouvé.
|
||||||
|
* @throws SecurityException Si l'utilisateur n'est pas le créateur de l'événement.
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public Events updateEvent(Events event) {
|
public Events updateEvent(Events event, UUID userId) {
|
||||||
logger.info("[logger] Tentative de mise à jour de l'événement avec l'ID : {}", event.getId());
|
logger.info("[logger] Tentative de mise à jour de l'événement avec l'ID : {} par l'utilisateur : {}", event.getId(), userId);
|
||||||
|
|
||||||
Events existingEvent = eventsRepository.findById(event.getId());
|
Events existingEvent = eventsRepository.findById(event.getId());
|
||||||
if (existingEvent == null) {
|
if (existingEvent == null) {
|
||||||
@@ -166,6 +203,12 @@ public class EventService {
|
|||||||
throw new EventNotFoundException(event.getId());
|
throw new EventNotFoundException(event.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifier que l'utilisateur est le créateur
|
||||||
|
if (!canModifyEvent(existingEvent, userId)) {
|
||||||
|
logger.error("[ERROR] L'utilisateur {} n'a pas les permissions pour modifier l'événement {}", userId, event.getId());
|
||||||
|
throw new SecurityException("Vous n'avez pas les permissions pour modifier cet événement");
|
||||||
|
}
|
||||||
|
|
||||||
// Mettre à jour les détails de l'événement
|
// Mettre à jour les détails de l'événement
|
||||||
existingEvent.setTitle(event.getTitle());
|
existingEvent.setTitle(event.getTitle());
|
||||||
existingEvent.setDescription(event.getDescription());
|
existingEvent.setDescription(event.getDescription());
|
||||||
@@ -175,6 +218,16 @@ public class EventService {
|
|||||||
existingEvent.setCategory(event.getCategory());
|
existingEvent.setCategory(event.getCategory());
|
||||||
existingEvent.setLink(event.getLink());
|
existingEvent.setLink(event.getLink());
|
||||||
existingEvent.setImageUrl(event.getImageUrl());
|
existingEvent.setImageUrl(event.getImageUrl());
|
||||||
|
existingEvent.setMaxParticipants(event.getMaxParticipants());
|
||||||
|
existingEvent.setTags(event.getTags());
|
||||||
|
existingEvent.setOrganizer(event.getOrganizer());
|
||||||
|
existingEvent.setParticipationFee(event.getParticipationFee());
|
||||||
|
existingEvent.setPrivacyRules(event.getPrivacyRules());
|
||||||
|
existingEvent.setTransportInfo(event.getTransportInfo());
|
||||||
|
existingEvent.setAccommodationInfo(event.getAccommodationInfo());
|
||||||
|
existingEvent.setAccessibilityInfo(event.getAccessibilityInfo());
|
||||||
|
existingEvent.setParkingInfo(event.getParkingInfo());
|
||||||
|
existingEvent.setSecurityProtocol(event.getSecurityProtocol());
|
||||||
existingEvent.setStatus(event.getStatus());
|
existingEvent.setStatus(event.getStatus());
|
||||||
|
|
||||||
// Persiste les modifications dans la base de données
|
// Persiste les modifications dans la base de données
|
||||||
|
|||||||
Reference in New Issue
Block a user