Initial commit
This commit is contained in:
@@ -0,0 +1,588 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.BonCommandeService;
|
||||
import dev.lions.btpxpress.domain.core.entity.BonCommande;
|
||||
import dev.lions.btpxpress.domain.core.entity.PrioriteBonCommande;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutBonCommande;
|
||||
import dev.lions.btpxpress.domain.core.entity.TypeBonCommande;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Controller REST pour la gestion des bons de commande */
|
||||
@Path("/api/v1/bons-commande")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Bons de Commande", description = "Gestion des bons de commande")
|
||||
public class BonCommandeController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BonCommandeController.class);
|
||||
|
||||
@Inject BonCommandeService bonCommandeService;
|
||||
|
||||
/** Récupère tous les bons de commande */
|
||||
@GET
|
||||
public Response getAllBonsCommande() {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findAll();
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un bon de commande par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getBonCommandeById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
BonCommande bonCommande = bonCommandeService.findById(id);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un bon de commande par son numéro */
|
||||
@GET
|
||||
@Path("/numero/{numero}")
|
||||
public Response getBonCommandeByNumero(@PathParam("numero") String numero) {
|
||||
try {
|
||||
BonCommande bonCommande = bonCommandeService.findByNumero(numero);
|
||||
if (bonCommande == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Bon de commande non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du bon de commande par numéro: " + numero, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getBonsCommandeByStatut(@PathParam("statut") StatutBonCommande statut) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findByStatut(statut);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande par fournisseur */
|
||||
@GET
|
||||
@Path("/fournisseur/{fournisseurId}")
|
||||
public Response getBonsCommandeByFournisseur(@PathParam("fournisseurId") UUID fournisseurId) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findByFournisseur(fournisseurId);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des bons de commande du fournisseur: " + fournisseurId,
|
||||
e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande par chantier */
|
||||
@GET
|
||||
@Path("/chantier/{chantierId}")
|
||||
public Response getBonsCommandeByChantier(@PathParam("chantierId") UUID chantierId) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findByChantier(chantierId);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des bons de commande du chantier: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande par demandeur */
|
||||
@GET
|
||||
@Path("/demandeur/{demandeurId}")
|
||||
public Response getBonsCommandeByDemandeur(@PathParam("demandeurId") UUID demandeurId) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findByDemandeur(demandeurId);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des bons de commande du demandeur: " + demandeurId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande par priorité */
|
||||
@GET
|
||||
@Path("/priorite/{priorite}")
|
||||
public Response getBonsCommandeByPriorite(@PathParam("priorite") PrioriteBonCommande priorite) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findByPriorite(priorite);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des bons de commande par priorité: " + priorite, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande urgents */
|
||||
@GET
|
||||
@Path("/urgents")
|
||||
public Response getBonsCommandeUrgents() {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findUrgents();
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande urgents", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande par type */
|
||||
@GET
|
||||
@Path("/type/{type}")
|
||||
public Response getBonsCommandeByType(@PathParam("type") TypeBonCommande type) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findByType(type);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande par type: " + type, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande en cours */
|
||||
@GET
|
||||
@Path("/en-cours")
|
||||
public Response getBonsCommandeEnCours() {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findEnCours();
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande en cours", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande en retard */
|
||||
@GET
|
||||
@Path("/en-retard")
|
||||
public Response getBonsCommandeEnRetard() {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findCommandesEnRetard();
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande en retard", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande à livrer prochainement */
|
||||
@GET
|
||||
@Path("/livraisons-prochaines")
|
||||
public Response getLivraisonsProchaines(@QueryParam("nbJours") @DefaultValue("7") int nbJours) {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findLivraisonsProchainess(nbJours);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons prochaines", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande en attente de validation */
|
||||
@GET
|
||||
@Path("/attente-validation")
|
||||
public Response getBonsCommandeAttenteValidation() {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findEnAttenteValidation();
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande en attente", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les bons de commande validés non envoyés */
|
||||
@GET
|
||||
@Path("/valides-non-envoyes")
|
||||
public Response getBonsCommandeValidesNonEnvoyes() {
|
||||
try {
|
||||
List<BonCommande> bonsCommande = bonCommandeService.findValideesNonEnvoyees();
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des bons de commande validés non envoyés", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des bons de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un nouveau bon de commande */
|
||||
@POST
|
||||
public Response createBonCommande(@Valid BonCommande bonCommande) {
|
||||
try {
|
||||
BonCommande nouveauBonCommande = bonCommandeService.create(bonCommande);
|
||||
return Response.status(Response.Status.CREATED).entity(nouveauBonCommande).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du bon de commande", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour un bon de commande */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateBonCommande(@PathParam("id") UUID id, @Valid BonCommande bonCommandeData) {
|
||||
try {
|
||||
BonCommande bonCommande = bonCommandeService.update(id, bonCommandeData);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Valide un bon de commande */
|
||||
@POST
|
||||
@Path("/{id}/valider")
|
||||
public Response validerBonCommande(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String commentaires = payload != null ? payload.get("commentaires") : null;
|
||||
BonCommande bonCommande = bonCommandeService.validerBonCommande(id, commentaires);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la validation du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la validation du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Rejette un bon de commande */
|
||||
@POST
|
||||
@Path("/{id}/rejeter")
|
||||
public Response rejeterBonCommande(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
BonCommande bonCommande = bonCommandeService.rejeterBonCommande(id, motif);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du rejet du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du rejet du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Envoie un bon de commande */
|
||||
@POST
|
||||
@Path("/{id}/envoyer")
|
||||
public Response envoyerBonCommande(@PathParam("id") UUID id) {
|
||||
try {
|
||||
BonCommande bonCommande = bonCommandeService.envoyerBonCommande(id);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'envoi du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'envoi du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Confirme la réception d'un accusé de réception */
|
||||
@POST
|
||||
@Path("/{id}/accuse-reception")
|
||||
public Response confirmerAccuseReception(@PathParam("id") UUID id) {
|
||||
try {
|
||||
BonCommande bonCommande = bonCommandeService.confirmerAccuseReception(id);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la confirmation d'accusé de réception: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la confirmation d'accusé de réception"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Marque un bon de commande comme livré */
|
||||
@POST
|
||||
@Path("/{id}/livrer")
|
||||
public Response livrerBonCommande(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
LocalDate dateLivraison =
|
||||
payload != null && payload.get("dateLivraison") != null
|
||||
? LocalDate.parse(payload.get("dateLivraison").toString())
|
||||
: LocalDate.now();
|
||||
String commentaires =
|
||||
payload != null && payload.get("commentaires") != null
|
||||
? payload.get("commentaires").toString()
|
||||
: null;
|
||||
|
||||
BonCommande bonCommande =
|
||||
bonCommandeService.livrerBonCommande(id, dateLivraison, commentaires);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la livraison du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la livraison du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Annule un bon de commande */
|
||||
@POST
|
||||
@Path("/{id}/annuler")
|
||||
public Response annulerBonCommande(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
BonCommande bonCommande = bonCommandeService.annulerBonCommande(id, motif);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'annulation du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'annulation du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Clôture un bon de commande */
|
||||
@POST
|
||||
@Path("/{id}/cloturer")
|
||||
public Response cloturerBonCommande(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String commentaires = payload != null ? payload.get("commentaires") : null;
|
||||
BonCommande bonCommande = bonCommandeService.cloturerBonCommande(id, commentaires);
|
||||
return Response.ok(bonCommande).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la clôture du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la clôture du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime un bon de commande */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteBonCommande(@PathParam("id") UUID id) {
|
||||
try {
|
||||
bonCommandeService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression du bon de commande: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression du bon de commande"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche de bons de commande par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchBonsCommande(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<BonCommande> bonsCommande = bonCommandeService.searchCommandes(searchTerm);
|
||||
return Response.ok(bonsCommande).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche de bons de commande: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des bons de commande */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = bonCommandeService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Génère le prochain numéro de commande */
|
||||
@GET
|
||||
@Path("/numero-suivant")
|
||||
public Response getProchainNumero(@QueryParam("prefixe") @DefaultValue("BC") String prefixe) {
|
||||
try {
|
||||
String numeroSuivant = bonCommandeService.genererProchainNumero(prefixe);
|
||||
return Response.ok(Map.of("numeroSuivant", numeroSuivant)).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération du numéro suivant", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la génération du numéro"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les top fournisseurs par montant de commandes */
|
||||
@GET
|
||||
@Path("/top-fournisseurs")
|
||||
public Response getTopFournisseurs(@QueryParam("limit") @DefaultValue("10") int limit) {
|
||||
try {
|
||||
List<Object[]> topFournisseurs = bonCommandeService.findTopFournisseursByMontant(limit);
|
||||
return Response.ok(topFournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des top fournisseurs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des top fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques mensuelles */
|
||||
@GET
|
||||
@Path("/statistiques/mensuelles/{annee}")
|
||||
public Response getStatistiquesMensuelles(@PathParam("annee") int annee) {
|
||||
try {
|
||||
List<Object[]> stats = bonCommandeService.findStatistiquesMensuelles(annee);
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques mensuelles", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.ChantierService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Chantier;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutChantier;
|
||||
import dev.lions.btpxpress.domain.shared.dto.ChantierCreateDTO;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Controller REST pour la gestion des chantiers */
|
||||
@Path("/api/v1/chantiers-controller") // Contrôleur alternatif pour éviter conflit
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Chantiers", description = "Gestion des chantiers BTP")
|
||||
public class ChantierController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ChantierController.class);
|
||||
|
||||
@Inject ChantierService chantierService;
|
||||
|
||||
/** Récupère tous les chantiers */
|
||||
@GET
|
||||
public Response getAllChantiers() {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findAll();
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un chantier par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getChantierById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Optional<Chantier> chantierOpt = chantierService.findById(id);
|
||||
if (chantierOpt.isEmpty()) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Chantier non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(chantierOpt.get()).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du chantier: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getChantiersByStatut(@PathParam("statut") StatutChantier statut) {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findByStatut(statut);
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers actifs */
|
||||
@GET
|
||||
@Path("/actifs")
|
||||
public Response getChantiersActifs() {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findActifs();
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers actifs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers par client */
|
||||
@GET
|
||||
@Path("/client/{clientId}")
|
||||
public Response getChantiersByClient(@PathParam("clientId") UUID clientId) {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findByClient(clientId);
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers du client: " + clientId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers par chef de chantier */
|
||||
@GET
|
||||
@Path("/chef-chantier/{chefId}")
|
||||
public Response getChantiersByChefChantier(@PathParam("chefId") UUID chefId) {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findByChefChantier(chefId);
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers du chef: " + chefId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers en retard */
|
||||
@GET
|
||||
@Path("/en-retard")
|
||||
public Response getChantiersEnRetard() {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findChantiersEnRetard();
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers en retard", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers à démarrer prochainement */
|
||||
@GET
|
||||
@Path("/prochains-demarrages")
|
||||
public Response getProchainsDemarrages(@QueryParam("nbJours") @DefaultValue("30") int nbJours) {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findProchainsDemarrages(nbJours);
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des prochains démarrages", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les chantiers par ville */
|
||||
@GET
|
||||
@Path("/ville/{ville}")
|
||||
public Response getChantiersByVille(@PathParam("ville") String ville) {
|
||||
try {
|
||||
List<Chantier> chantiers = chantierService.findByVille(ville);
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des chantiers par ville: " + ville, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des chantiers"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un nouveau chantier */
|
||||
@POST
|
||||
public Response createChantier(@Valid ChantierCreateDTO chantierDto) {
|
||||
try {
|
||||
Chantier nouveauChantier = chantierService.create(chantierDto);
|
||||
return Response.status(Response.Status.CREATED).entity(nouveauChantier).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du chantier", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour un chantier */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateChantier(@PathParam("id") UUID id, @Valid ChantierCreateDTO chantierDto) {
|
||||
try {
|
||||
Chantier chantier = chantierService.update(id, chantierDto);
|
||||
return Response.ok(chantier).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour du chantier: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Démarre un chantier */
|
||||
@POST
|
||||
@Path("/{id}/demarrer")
|
||||
public Response demarrerChantier(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Chantier chantier = chantierService.demarrerChantier(id);
|
||||
return Response.ok(chantier).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du démarrage du chantier: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du démarrage du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Suspend un chantier */
|
||||
@POST
|
||||
@Path("/{id}/suspendre")
|
||||
public Response suspendreChantier(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
Chantier chantier = chantierService.suspendreChantier(id, motif);
|
||||
return Response.ok(chantier).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suspension du chantier: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suspension du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Termine un chantier */
|
||||
@POST
|
||||
@Path("/{id}/terminer")
|
||||
public Response terminerChantier(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
LocalDate dateFinReelle =
|
||||
payload != null && payload.get("dateFinReelle") != null
|
||||
? LocalDate.parse(payload.get("dateFinReelle").toString())
|
||||
: LocalDate.now();
|
||||
String commentaires =
|
||||
payload != null && payload.get("commentaires") != null
|
||||
? payload.get("commentaires").toString()
|
||||
: null;
|
||||
|
||||
Chantier chantier = chantierService.terminerChantier(id, dateFinReelle, commentaires);
|
||||
return Response.ok(chantier).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la terminaison du chantier: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la terminaison du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour l'avancement global du chantier */
|
||||
@POST
|
||||
@Path("/{id}/avancement")
|
||||
public Response updateAvancementGlobal(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal pourcentage = new BigDecimal(payload.get("pourcentage").toString());
|
||||
Chantier chantier = chantierService.updateAvancementGlobal(id, pourcentage);
|
||||
return Response.ok(chantier).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Pourcentage invalide"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de l'avancement: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour de l'avancement"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime un chantier */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteChantier(@PathParam("id") UUID id) {
|
||||
try {
|
||||
chantierService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression du chantier: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche de chantiers par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchChantiers(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Chantier> chantiers = chantierService.searchChantiers(searchTerm);
|
||||
return Response.ok(chantiers).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche de chantiers: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des chantiers */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = chantierService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Calcule le chiffre d'affaires total des chantiers */
|
||||
@GET
|
||||
@Path("/chiffre-affaires")
|
||||
public Response getChiffreAffaires(@QueryParam("annee") Integer annee) {
|
||||
try {
|
||||
Map<String, Object> ca = chantierService.calculerChiffreAffaires(annee);
|
||||
return Response.ok(Map.of("chiffreAffaires", ca)).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du calcul du chiffre d'affaires", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du calcul du chiffre d'affaires"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le tableau de bord du chantier */
|
||||
@GET
|
||||
@Path("/{id}/dashboard")
|
||||
public Response getDashboardChantier(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Map<String, Object> dashboard = chantierService.getDashboardChantier(id);
|
||||
return Response.ok(dashboard).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du dashboard: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du dashboard"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.EmployeService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Employe;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutEmploye;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Controller REST pour la gestion des employés */
|
||||
@Path("/api/employes")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Employés", description = "Gestion des employés")
|
||||
public class EmployeController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EmployeController.class);
|
||||
|
||||
@Inject EmployeService employeService;
|
||||
|
||||
/** Récupère tous les employés */
|
||||
@GET
|
||||
public Response getAllEmployes() {
|
||||
try {
|
||||
List<Employe> employes = employeService.findAll();
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un employé par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getEmployeById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Optional<Employe> employeOpt = employeService.findById(id);
|
||||
if (employeOpt.isEmpty()) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Employé non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(employeOpt.get()).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de l'employé: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getEmployesByStatut(@PathParam("statut") StatutEmploye statut) {
|
||||
try {
|
||||
List<Employe> employes = employeService.findByStatut(statut);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés actifs */
|
||||
@GET
|
||||
@Path("/actifs")
|
||||
public Response getEmployesActifs() {
|
||||
try {
|
||||
List<Employe> employes = employeService.findActifs();
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés actifs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un employé par email */
|
||||
@GET
|
||||
@Path("/email/{email}")
|
||||
public Response getEmployeByEmail(@PathParam("email") String email) {
|
||||
try {
|
||||
Optional<Employe> employeOpt = employeService.findByEmail(email);
|
||||
if (employeOpt.isEmpty()) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Employé non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(employeOpt.get()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de l'employé par email: " + email, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche des employés par nom ou prénom */
|
||||
@GET
|
||||
@Path("/search/nom")
|
||||
public Response searchEmployesByNom(@QueryParam("nom") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Employe> employes = employeService.searchByNom(searchTerm);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche par nom: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés par métier */
|
||||
@GET
|
||||
@Path("/metier/{metier}")
|
||||
public Response getEmployesByMetier(@PathParam("metier") String metier) {
|
||||
try {
|
||||
List<Employe> employes = employeService.findByMetier(metier);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés par métier: " + metier, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés par équipe */
|
||||
@GET
|
||||
@Path("/equipe/{equipeId}")
|
||||
public Response getEmployesByEquipe(@PathParam("equipeId") UUID equipeId) {
|
||||
try {
|
||||
List<Employe> employes = employeService.findByEquipe(equipeId);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés par équipe: " + equipeId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés disponibles pour une période */
|
||||
@GET
|
||||
@Path("/disponibles")
|
||||
public Response getEmployesDisponibles(
|
||||
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateFin") String dateFin) {
|
||||
try {
|
||||
List<Employe> employes = employeService.findDisponibles(dateDebut, dateFin);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés disponibles", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés avec certifications */
|
||||
@GET
|
||||
@Path("/avec-certifications")
|
||||
public Response getEmployesAvecCertifications() {
|
||||
try {
|
||||
List<Employe> employes = employeService.findAvecCertifications();
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés avec certifications", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les employés par niveau d'expérience */
|
||||
@GET
|
||||
@Path("/experience/{niveau}")
|
||||
public Response getEmployesByExperience(@PathParam("niveau") String niveau) {
|
||||
try {
|
||||
List<Employe> employes = employeService.findByNiveauExperience(niveau);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des employés par expérience: " + niveau, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des employés"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un nouveau employé */
|
||||
@POST
|
||||
public Response createEmploye(@Valid Employe employe) {
|
||||
try {
|
||||
Employe nouvelEmploye = employeService.create(employe);
|
||||
return Response.status(Response.Status.CREATED).entity(nouvelEmploye).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création de l'employé", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour un employé */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateEmploye(@PathParam("id") UUID id, @Valid Employe employeData) {
|
||||
try {
|
||||
Employe employe = employeService.update(id, employeData);
|
||||
return Response.ok(employe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de l'employé: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Active un employé */
|
||||
@POST
|
||||
@Path("/{id}/activer")
|
||||
public Response activerEmploye(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Employe employe = employeService.activerEmploye(id);
|
||||
return Response.ok(employe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'activation de l'employé: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'activation de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Désactive un employé */
|
||||
@POST
|
||||
@Path("/{id}/desactiver")
|
||||
public Response desactiverEmploye(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
Employe employe = employeService.desactiverEmploye(id, motif);
|
||||
return Response.ok(employe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la désactivation de l'employé: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la désactivation de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Affecte un employé à une équipe */
|
||||
@POST
|
||||
@Path("/{id}/affecter-equipe")
|
||||
public Response affecterEquipe(@PathParam("id") UUID employeId, Map<String, Object> payload) {
|
||||
try {
|
||||
UUID equipeId =
|
||||
payload.get("equipeId") != null
|
||||
? UUID.fromString(payload.get("equipeId").toString())
|
||||
: null;
|
||||
|
||||
Employe employe = employeService.affecterEquipe(employeId, equipeId);
|
||||
return Response.ok(employe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'affectation d'équipe: " + employeId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'affectation d'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime un employé */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteEmploye(@PathParam("id") UUID id) {
|
||||
try {
|
||||
employeService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression de l'employé: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression de l'employé"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche d'employés par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchEmployes(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Employe> employes = employeService.searchEmployes(searchTerm);
|
||||
return Response.ok(employes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche d'employés: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des employés */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = employeService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le planning d'un employé */
|
||||
@GET
|
||||
@Path("/{id}/planning")
|
||||
public Response getPlanningEmploye(
|
||||
@PathParam("id") UUID id,
|
||||
@QueryParam("dateDebut") String dateDebut,
|
||||
@QueryParam("dateFin") String dateFin) {
|
||||
try {
|
||||
LocalDate debut = LocalDate.parse(dateDebut);
|
||||
LocalDate fin = LocalDate.parse(dateFin);
|
||||
List<Object> planning = employeService.getPlanningEmploye(id, debut, fin);
|
||||
return Response.ok(planning).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du planning"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les compétences d'un employé */
|
||||
@GET
|
||||
@Path("/{id}/competences")
|
||||
public Response getCompetencesEmploye(@PathParam("id") UUID id) {
|
||||
try {
|
||||
List<Object> competences = employeService.getCompetencesEmploye(id);
|
||||
return Response.ok(competences).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des compétences: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des compétences"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,452 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.EquipeService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Equipe;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutEquipe;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Controller REST pour la gestion des équipes */
|
||||
@Path("/api/v1/equipes-controller")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Équipes", description = "Gestion des équipes de travail BTP")
|
||||
public class EquipeController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EquipeController.class);
|
||||
|
||||
@Inject EquipeService equipeService;
|
||||
|
||||
/** Récupère toutes les équipes */
|
||||
@GET
|
||||
public Response getAllEquipes() {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findAll();
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère une équipe par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getEquipeById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Optional<Equipe> equipeOpt = equipeService.findById(id);
|
||||
if (equipeOpt.isEmpty()) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Équipe non trouvée"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(equipeOpt.get()).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de l'équipe: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération de l'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getEquipesByStatut(@PathParam("statut") StatutEquipe statut) {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findByStatut(statut);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes actives */
|
||||
@GET
|
||||
@Path("/actives")
|
||||
public Response getEquipesActives() {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findActives();
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes actives", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes par chef d'équipe */
|
||||
@GET
|
||||
@Path("/chef/{chefId}")
|
||||
public Response getEquipesByChef(@PathParam("chefId") UUID chefId) {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findByChef(chefId);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes du chef: " + chefId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes par spécialité */
|
||||
@GET
|
||||
@Path("/specialite/{specialite}")
|
||||
public Response getEquipesBySpecialite(@PathParam("specialite") String specialite) {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findBySpecialite(specialite);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes par spécialité: " + specialite, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes disponibles pour une période */
|
||||
@GET
|
||||
@Path("/disponibles")
|
||||
public Response getEquipesDisponibles(
|
||||
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateFin") String dateFin) {
|
||||
try {
|
||||
LocalDate debut = LocalDate.parse(dateDebut);
|
||||
LocalDate fin = LocalDate.parse(dateFin);
|
||||
List<Equipe> equipes = equipeService.findDisponibles(debut, fin);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes disponibles", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes par taille minimum */
|
||||
@GET
|
||||
@Path("/taille-minimum/{taille}")
|
||||
public Response getEquipesByTailleMinimum(@PathParam("taille") int taille) {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findByTailleMinimum(taille);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes par taille: " + taille, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les équipes par niveau d'expérience */
|
||||
@GET
|
||||
@Path("/experience/{niveau}")
|
||||
public Response getEquipesByExperience(@PathParam("niveau") String niveau) {
|
||||
try {
|
||||
List<Equipe> equipes = equipeService.findByNiveauExperience(niveau);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des équipes par expérience: " + niveau, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des équipes"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée une nouvelle équipe */
|
||||
@POST
|
||||
public Response createEquipe(@Valid Equipe equipe) {
|
||||
try {
|
||||
Equipe nouvelleEquipe = equipeService.create(equipe);
|
||||
return Response.status(Response.Status.CREATED).entity(nouvelleEquipe).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création de l'équipe", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création de l'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour une équipe */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateEquipe(@PathParam("id") UUID id, @Valid Equipe equipeData) {
|
||||
try {
|
||||
Equipe equipe = equipeService.update(id, equipeData);
|
||||
return Response.ok(equipe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de l'équipe: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour de l'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Active une équipe */
|
||||
@POST
|
||||
@Path("/{id}/activer")
|
||||
public Response activerEquipe(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Equipe equipe = equipeService.activerEquipe(id);
|
||||
return Response.ok(equipe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'activation de l'équipe: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'activation de l'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Désactive une équipe */
|
||||
@POST
|
||||
@Path("/{id}/desactiver")
|
||||
public Response desactiverEquipe(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
Equipe equipe = equipeService.desactiverEquipe(id, motif);
|
||||
return Response.ok(equipe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la désactivation de l'équipe: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la désactivation de l'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Ajoute un membre à l'équipe */
|
||||
@POST
|
||||
@Path("/{id}/ajouter-membre")
|
||||
public Response ajouterMembre(@PathParam("id") UUID equipeId, Map<String, Object> payload) {
|
||||
try {
|
||||
UUID employeId = UUID.fromString(payload.get("employeId").toString());
|
||||
String role = payload.get("role") != null ? payload.get("role").toString() : null;
|
||||
|
||||
Equipe equipe = equipeService.ajouterMembre(equipeId, employeId, role);
|
||||
return Response.ok(equipe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'ajout de membre: " + equipeId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'ajout de membre"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Retire un membre de l'équipe */
|
||||
@POST
|
||||
@Path("/{id}/retirer-membre")
|
||||
public Response retirerMembre(@PathParam("id") UUID equipeId, Map<String, Object> payload) {
|
||||
try {
|
||||
UUID employeId = UUID.fromString(payload.get("employeId").toString());
|
||||
|
||||
Equipe equipe = equipeService.retirerMembre(equipeId, employeId);
|
||||
return Response.ok(equipe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du retrait de membre: " + equipeId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du retrait de membre"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Change le chef d'équipe */
|
||||
@POST
|
||||
@Path("/{id}/changer-chef")
|
||||
public Response changerChef(@PathParam("id") UUID equipeId, Map<String, Object> payload) {
|
||||
try {
|
||||
UUID nouveauChefId = UUID.fromString(payload.get("nouveauChefId").toString());
|
||||
|
||||
Equipe equipe = equipeService.changerChef(equipeId, nouveauChefId);
|
||||
return Response.ok(equipe).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du changement de chef: " + equipeId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du changement de chef"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime une équipe */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteEquipe(@PathParam("id") UUID id) {
|
||||
try {
|
||||
equipeService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression de l'équipe: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression de l'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche d'équipes par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchEquipes(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Equipe> equipes = equipeService.searchEquipes(searchTerm);
|
||||
return Response.ok(equipes).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche d'équipes: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des équipes */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = equipeService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les membres d'une équipe */
|
||||
@GET
|
||||
@Path("/{id}/membres")
|
||||
public Response getMembresEquipe(@PathParam("id") UUID id) {
|
||||
try {
|
||||
List<Object> membres = equipeService.getMembresEquipe(id);
|
||||
return Response.ok(membres).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des membres: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des membres"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le planning d'une équipe */
|
||||
@GET
|
||||
@Path("/{id}/planning")
|
||||
public Response getPlanningEquipe(
|
||||
@PathParam("id") UUID id,
|
||||
@QueryParam("dateDebut") String dateDebut,
|
||||
@QueryParam("dateFin") String dateFin) {
|
||||
try {
|
||||
LocalDate debut = LocalDate.parse(dateDebut);
|
||||
LocalDate fin = LocalDate.parse(dateFin);
|
||||
List<Object> planning = equipeService.getPlanningEquipe(id, debut, fin);
|
||||
return Response.ok(planning).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du planning"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les performances d'une équipe */
|
||||
@GET
|
||||
@Path("/{id}/performances")
|
||||
public Response getPerformancesEquipe(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Map<String, Object> performances = equipeService.getPerformancesEquipe(id);
|
||||
return Response.ok(performances).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des performances: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des performances"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.FournisseurService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Fournisseur;
|
||||
import dev.lions.btpxpress.domain.core.entity.SpecialiteFournisseur;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutFournisseur;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Contrôleur REST pour la gestion des fournisseurs Gère toutes les opérations CRUD et métier liées
|
||||
* aux fournisseurs
|
||||
*/
|
||||
@Path("/api/v1/fournisseurs")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Fournisseurs", description = "Gestion des fournisseurs et partenaires BTP")
|
||||
public class FournisseurController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FournisseurController.class);
|
||||
|
||||
@Inject FournisseurService fournisseurService;
|
||||
|
||||
/** Récupère tous les fournisseurs */
|
||||
@GET
|
||||
public Response getAllFournisseurs() {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findAll();
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un fournisseur par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getFournisseurById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Fournisseur fournisseur = fournisseurService.findById(id);
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère tous les fournisseurs actifs */
|
||||
@GET
|
||||
@Path("/actifs")
|
||||
public Response getFournisseursActifs() {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findActifs();
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs actifs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getFournisseursByStatut(@PathParam("statut") StatutFournisseur statut) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findByStatut(statut);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs par spécialité */
|
||||
@GET
|
||||
@Path("/specialite/{specialite}")
|
||||
public Response getFournisseursBySpecialite(
|
||||
@PathParam("specialite") SpecialiteFournisseur specialite) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findBySpecialite(specialite);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des fournisseurs par spécialité: " + specialite, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un fournisseur par SIRET */
|
||||
@GET
|
||||
@Path("/siret/{siret}")
|
||||
public Response getFournisseurBySiret(@PathParam("siret") String siret) {
|
||||
try {
|
||||
Fournisseur fournisseur = fournisseurService.findBySiret(siret);
|
||||
if (fournisseur == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Fournisseur non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du fournisseur par SIRET: " + siret, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un fournisseur par numéro de TVA */
|
||||
@GET
|
||||
@Path("/tva/{numeroTVA}")
|
||||
public Response getFournisseurByNumeroTVA(@PathParam("numeroTVA") String numeroTVA) {
|
||||
try {
|
||||
Fournisseur fournisseur = fournisseurService.findByNumeroTVA(numeroTVA);
|
||||
if (fournisseur == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Fournisseur non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du fournisseur par TVA: " + numeroTVA, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche de fournisseurs par nom ou raison sociale */
|
||||
@GET
|
||||
@Path("/search/nom")
|
||||
public Response searchFournisseursByNom(@QueryParam("nom") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Fournisseur> fournisseurs = fournisseurService.searchByNom(searchTerm);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche par nom: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs préférés */
|
||||
@GET
|
||||
@Path("/preferes")
|
||||
public Response getFournisseursPreferes() {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findPreferes();
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs préférés", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs avec assurance RC professionnelle */
|
||||
@GET
|
||||
@Path("/avec-assurance")
|
||||
public Response getFournisseursAvecAssurance() {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findAvecAssuranceRC();
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs avec assurance", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs avec assurance expirée ou proche de l'expiration */
|
||||
@GET
|
||||
@Path("/assurance-expire")
|
||||
public Response getFournisseursAssuranceExpiree(
|
||||
@QueryParam("nbJours") @DefaultValue("30") int nbJours) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findAssuranceExpireeOuProche(nbJours);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs assurance expirée", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs par ville */
|
||||
@GET
|
||||
@Path("/ville/{ville}")
|
||||
public Response getFournisseursByVille(@PathParam("ville") String ville) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findByVille(ville);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs par ville: " + ville, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs par code postal */
|
||||
@GET
|
||||
@Path("/code-postal/{codePostal}")
|
||||
public Response getFournisseursByCodePostal(@PathParam("codePostal") String codePostal) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findByCodePostal(codePostal);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des fournisseurs par code postal: " + codePostal, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs dans une zone géographique */
|
||||
@GET
|
||||
@Path("/zone/{prefixeCodePostal}")
|
||||
public Response getFournisseursByZone(@PathParam("prefixeCodePostal") String prefixeCodePostal) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findByZoneGeographique(prefixeCodePostal);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des fournisseurs par zone: " + prefixeCodePostal, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les fournisseurs sans commande depuis X jours */
|
||||
@GET
|
||||
@Path("/sans-commande")
|
||||
public Response getFournisseursSansCommande(
|
||||
@QueryParam("nbJours") @DefaultValue("90") int nbJours) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findSansCommandeDepuis(nbJours);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs sans commande", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les top fournisseurs par montant d'achats */
|
||||
@GET
|
||||
@Path("/top-montant")
|
||||
public Response getTopFournisseursByMontant(@QueryParam("limit") @DefaultValue("10") int limit) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs = fournisseurService.findTopFournisseursByMontant(limit);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des top fournisseurs par montant", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les top fournisseurs par nombre de commandes */
|
||||
@GET
|
||||
@Path("/top-commandes")
|
||||
public Response getTopFournisseursByNombreCommandes(
|
||||
@QueryParam("limit") @DefaultValue("10") int limit) {
|
||||
try {
|
||||
List<Fournisseur> fournisseurs =
|
||||
fournisseurService.findTopFournisseursByNombreCommandes(limit);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des top fournisseurs par commandes", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des fournisseurs"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un nouveau fournisseur */
|
||||
@POST
|
||||
public Response createFournisseur(@Valid Fournisseur fournisseur) {
|
||||
try {
|
||||
Fournisseur nouveauFournisseur = fournisseurService.create(fournisseur);
|
||||
return Response.status(Response.Status.CREATED).entity(nouveauFournisseur).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du fournisseur", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour un fournisseur */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateFournisseur(@PathParam("id") UUID id, @Valid Fournisseur fournisseurData) {
|
||||
try {
|
||||
Fournisseur fournisseur = fournisseurService.update(id, fournisseurData);
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Active un fournisseur */
|
||||
@POST
|
||||
@Path("/{id}/activer")
|
||||
public Response activerFournisseur(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Fournisseur fournisseur = fournisseurService.activerFournisseur(id);
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'activation du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'activation du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Désactive un fournisseur */
|
||||
@POST
|
||||
@Path("/{id}/desactiver")
|
||||
public Response desactiverFournisseur(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
Fournisseur fournisseur = fournisseurService.desactiverFournisseur(id, motif);
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la désactivation du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la désactivation du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour les notes d'évaluation d'un fournisseur */
|
||||
@POST
|
||||
@Path("/{id}/evaluation")
|
||||
public Response evaluerFournisseur(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal noteQualite =
|
||||
payload.get("noteQualite") != null
|
||||
? new BigDecimal(payload.get("noteQualite").toString())
|
||||
: null;
|
||||
BigDecimal noteDelai =
|
||||
payload.get("noteDelai") != null
|
||||
? new BigDecimal(payload.get("noteDelai").toString())
|
||||
: null;
|
||||
BigDecimal notePrix =
|
||||
payload.get("notePrix") != null
|
||||
? new BigDecimal(payload.get("notePrix").toString())
|
||||
: null;
|
||||
String commentaires =
|
||||
payload.get("commentaires") != null ? payload.get("commentaires").toString() : null;
|
||||
|
||||
Fournisseur fournisseur =
|
||||
fournisseurService.evaluerFournisseur(id, noteQualite, noteDelai, notePrix, commentaires);
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Notes d'évaluation invalides"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'évaluation du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'évaluation du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Marque un fournisseur comme préféré */
|
||||
@POST
|
||||
@Path("/{id}/prefere")
|
||||
public Response marquerPrefere(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
boolean prefere =
|
||||
payload != null && payload.get("prefere") != null
|
||||
? Boolean.parseBoolean(payload.get("prefere").toString())
|
||||
: true;
|
||||
|
||||
Fournisseur fournisseur = fournisseurService.marquerPrefere(id, prefere);
|
||||
return Response.ok(fournisseur).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du marquage préféré du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du marquage du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime un fournisseur */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteFournisseur(@PathParam("id") UUID id) {
|
||||
try {
|
||||
fournisseurService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression du fournisseur: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression du fournisseur"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des fournisseurs */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = fournisseurService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche de fournisseurs par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchFournisseurs(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Fournisseur> fournisseurs = fournisseurService.searchFournisseurs(searchTerm);
|
||||
return Response.ok(fournisseurs).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche de fournisseurs: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.MaterielService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Materiel;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutMateriel;
|
||||
import dev.lions.btpxpress.domain.core.entity.TypeMateriel;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Controller REST pour la gestion du matériel */
|
||||
@Path("/api/materiel")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Matériels", description = "Gestion des matériels et équipements")
|
||||
public class MaterielController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MaterielController.class);
|
||||
|
||||
@Inject MaterielService materielService;
|
||||
|
||||
/** Récupère tout le matériel */
|
||||
@GET
|
||||
public Response getAllMateriel() {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findAll();
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un matériel par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getMaterielById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Optional<Materiel> materielOpt = materielService.findById(id);
|
||||
if (materielOpt.isEmpty()) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Matériel non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(materielOpt.get()).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getMaterielByStatut(@PathParam("statut") StatutMateriel statut) {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findByStatut(statut);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel disponible */
|
||||
@GET
|
||||
@Path("/disponible")
|
||||
public Response getMaterielDisponible() {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findDisponible();
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel disponible", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel par type */
|
||||
@GET
|
||||
@Path("/type/{type}")
|
||||
public Response getMaterielByType(@PathParam("type") String type) {
|
||||
try {
|
||||
TypeMateriel typeMateriel = TypeMateriel.valueOf(type.toUpperCase());
|
||||
List<Materiel> materiel = materielService.findByType(typeMateriel);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel par type: " + type, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel par chantier */
|
||||
@GET
|
||||
@Path("/chantier/{chantierId}")
|
||||
public Response getMaterielByChantier(@PathParam("chantierId") UUID chantierId) {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findByChantier(chantierId);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel du chantier: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel par marque */
|
||||
@GET
|
||||
@Path("/marque/{marque}")
|
||||
public Response getMaterielByMarque(@PathParam("marque") String marque) {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findByMarque(marque);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel par marque: " + marque, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel nécessitant une maintenance */
|
||||
@GET
|
||||
@Path("/maintenance-requise")
|
||||
public Response getMaterielMaintenanceRequise() {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findMaintenanceRequise();
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel nécessitant maintenance", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel en panne */
|
||||
@GET
|
||||
@Path("/en-panne")
|
||||
public Response getMaterielEnPanne() {
|
||||
try {
|
||||
List<Materiel> materiel = materielService.findEnPanne();
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel en panne", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le matériel disponible pour une période */
|
||||
@GET
|
||||
@Path("/disponible-periode")
|
||||
public Response getMaterielDisponiblePeriode(
|
||||
@QueryParam("dateDebut") String dateDebut, @QueryParam("dateFin") String dateFin) {
|
||||
try {
|
||||
LocalDate debut = LocalDate.parse(dateDebut);
|
||||
LocalDate fin = LocalDate.parse(dateFin);
|
||||
List<Materiel> materiel = materielService.findDisponiblePeriode(debut, fin);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel disponible pour la période", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un nouveau matériel */
|
||||
@POST
|
||||
public Response createMateriel(@Valid Materiel materiel) {
|
||||
try {
|
||||
Materiel nouveauMateriel = materielService.create(materiel);
|
||||
return Response.status(Response.Status.CREATED).entity(nouveauMateriel).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du matériel", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour un matériel */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateMateriel(@PathParam("id") UUID id, @Valid Materiel materielData) {
|
||||
try {
|
||||
Materiel materiel = materielService.update(id, materielData);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour du matériel: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Affecte un matériel à un chantier */
|
||||
@POST
|
||||
@Path("/{id}/affecter-chantier")
|
||||
public Response affecterChantier(@PathParam("id") UUID materielId, Map<String, Object> payload) {
|
||||
try {
|
||||
UUID chantierId = UUID.fromString(payload.get("chantierId").toString());
|
||||
LocalDate dateDebut = LocalDate.parse(payload.get("dateDebut").toString());
|
||||
LocalDate dateFin =
|
||||
payload.get("dateFin") != null
|
||||
? LocalDate.parse(payload.get("dateFin").toString())
|
||||
: null;
|
||||
|
||||
Materiel materiel =
|
||||
materielService.affecterChantier(materielId, chantierId, dateDebut, dateFin);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'affectation au chantier: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'affectation au chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Libère un matériel du chantier */
|
||||
@POST
|
||||
@Path("/{id}/liberer-chantier")
|
||||
public Response libererChantier(@PathParam("id") UUID materielId) {
|
||||
try {
|
||||
Materiel materiel = materielService.libererChantier(materielId);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la libération du chantier: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la libération du chantier"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Marque un matériel en maintenance */
|
||||
@POST
|
||||
@Path("/{id}/maintenance")
|
||||
public Response marquerMaintenance(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
String description =
|
||||
payload.get("description") != null ? payload.get("description").toString() : null;
|
||||
LocalDate datePrevue =
|
||||
payload.get("datePrevue") != null
|
||||
? LocalDate.parse(payload.get("datePrevue").toString())
|
||||
: null;
|
||||
|
||||
Materiel materiel = materielService.marquerMaintenance(id, description, datePrevue);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du marquage en maintenance: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du marquage en maintenance"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Marque un matériel en panne */
|
||||
@POST
|
||||
@Path("/{id}/panne")
|
||||
public Response marquerPanne(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String description = payload != null ? payload.get("description") : null;
|
||||
Materiel materiel = materielService.marquerPanne(id, description);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du marquage en panne: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du marquage en panne"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Répare un matériel */
|
||||
@POST
|
||||
@Path("/{id}/reparer")
|
||||
public Response reparerMateriel(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
String description =
|
||||
payload != null && payload.get("description") != null
|
||||
? payload.get("description").toString()
|
||||
: null;
|
||||
LocalDate dateReparation =
|
||||
payload != null && payload.get("dateReparation") != null
|
||||
? LocalDate.parse(payload.get("dateReparation").toString())
|
||||
: LocalDate.now();
|
||||
|
||||
Materiel materiel = materielService.reparer(id, description, dateReparation);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la réparation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la réparation"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Retire définitivement un matériel */
|
||||
@POST
|
||||
@Path("/{id}/retirer")
|
||||
public Response retirerMateriel(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload != null ? payload.get("motif") : null;
|
||||
Materiel materiel = materielService.retirerDefinitivement(id, motif);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du retrait définitif: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du retrait définitif"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime un matériel */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteMateriel(@PathParam("id") UUID id) {
|
||||
try {
|
||||
materielService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression du matériel: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression du matériel"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche de matériel par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchMateriel(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Materiel> materiel = materielService.searchMateriel(searchTerm);
|
||||
return Response.ok(materiel).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche de matériel: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques du matériel */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = materielService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère l'historique d'utilisation d'un matériel */
|
||||
@GET
|
||||
@Path("/{id}/historique")
|
||||
public Response getHistoriqueUtilisation(@PathParam("id") UUID id) {
|
||||
try {
|
||||
List<Object> historique = materielService.getHistoriqueUtilisation(id);
|
||||
return Response.ok(historique).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de l'historique: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération de l'historique"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère le planning d'utilisation d'un matériel */
|
||||
@GET
|
||||
@Path("/{id}/planning")
|
||||
public Response getPlanningMateriel(
|
||||
@PathParam("id") UUID id,
|
||||
@QueryParam("dateDebut") String dateDebut,
|
||||
@QueryParam("dateFin") String dateFin) {
|
||||
try {
|
||||
LocalDate debut = LocalDate.parse(dateDebut);
|
||||
LocalDate fin = LocalDate.parse(dateFin);
|
||||
List<Object> planning = materielService.getPlanningMateriel(id, debut, fin);
|
||||
return Response.ok(planning).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du planning"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.PhaseChantierService;
|
||||
import dev.lions.btpxpress.domain.core.entity.PhaseChantier;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutPhaseChantier;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Contrôleur REST pour la gestion des phases de chantier Permet de suivre l'avancement détaillé de
|
||||
* chaque phase d'un chantier
|
||||
*/
|
||||
@Path("/api/v1/phases")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Phases de Chantier", description = "Gestion des phases et jalons de chantiers BTP")
|
||||
public class PhaseChantierController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PhaseChantierController.class);
|
||||
|
||||
@Inject PhaseChantierService phaseChantierService;
|
||||
|
||||
/** Récupère toutes les phases */
|
||||
@GET
|
||||
public Response getAllPhases() {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findAll();
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère une phase par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getPhaseById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
PhaseChantier phase = phaseChantierService.findById(id);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les phases d'un chantier */
|
||||
@GET
|
||||
@Path("/chantier/{chantierId}")
|
||||
public Response getPhasesByChantier(@PathParam("chantierId") UUID chantierId) {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findByChantier(chantierId);
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases du chantier: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les phases par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getPhasesByStatut(@PathParam("statut") StatutPhaseChantier statut) {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findByStatut(statut);
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les phases en retard */
|
||||
@GET
|
||||
@Path("/en-retard")
|
||||
public Response getPhasesEnRetard() {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findPhasesEnRetard();
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases en retard", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les phases en cours */
|
||||
@GET
|
||||
@Path("/en-cours")
|
||||
public Response getPhasesEnCours() {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findPhasesEnCours();
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases en cours", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les phases critiques */
|
||||
@GET
|
||||
@Path("/critiques")
|
||||
public Response getPhasesCritiques() {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findPhasesCritiques();
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases critiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les phases nécessitant une attention */
|
||||
@GET
|
||||
@Path("/attention")
|
||||
public Response getPhasesNecessitantAttention() {
|
||||
try {
|
||||
List<PhaseChantier> phases = phaseChantierService.findPhasesNecessitantAttention();
|
||||
return Response.ok(phases).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des phases nécessitant attention", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des phases"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée une nouvelle phase */
|
||||
@POST
|
||||
public Response createPhase(@Valid PhaseChantier phase) {
|
||||
try {
|
||||
PhaseChantier nouvellephase = phaseChantierService.create(phase);
|
||||
return Response.status(Response.Status.CREATED).entity(nouvellephase).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création de la phase", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour une phase */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updatePhase(@PathParam("id") UUID id, @Valid PhaseChantier phaseData) {
|
||||
try {
|
||||
PhaseChantier phase = phaseChantierService.update(id, phaseData);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Démarre une phase */
|
||||
@POST
|
||||
@Path("/{id}/demarrer")
|
||||
public Response demarrerPhase(@PathParam("id") UUID id) {
|
||||
try {
|
||||
PhaseChantier phase = phaseChantierService.demarrerPhase(id);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du démarrage de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du démarrage de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Termine une phase */
|
||||
@POST
|
||||
@Path("/{id}/terminer")
|
||||
public Response terminerPhase(@PathParam("id") UUID id) {
|
||||
try {
|
||||
PhaseChantier phase = phaseChantierService.terminerPhase(id);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la terminaison de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la terminaison de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Suspend une phase */
|
||||
@POST
|
||||
@Path("/{id}/suspendre")
|
||||
public Response suspendrePhase(@PathParam("id") UUID id, Map<String, String> payload) {
|
||||
try {
|
||||
String motif = payload.get("motif");
|
||||
PhaseChantier phase = phaseChantierService.suspendrPhase(id, motif);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suspension de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suspension de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Reprend une phase suspendue */
|
||||
@POST
|
||||
@Path("/{id}/reprendre")
|
||||
public Response reprendrePhase(@PathParam("id") UUID id) {
|
||||
try {
|
||||
PhaseChantier phase = phaseChantierService.reprendrePhase(id);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la reprise de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la reprise de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour l'avancement d'une phase */
|
||||
@POST
|
||||
@Path("/{id}/avancement")
|
||||
public Response updateAvancement(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal pourcentage = new BigDecimal(payload.get("pourcentage").toString());
|
||||
PhaseChantier phase = phaseChantierService.updateAvancement(id, pourcentage);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Pourcentage invalide"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de l'avancement: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour de l'avancement"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Affecte une équipe à une phase */
|
||||
@POST
|
||||
@Path("/{id}/affecter-equipe")
|
||||
public Response affecterEquipe(@PathParam("id") UUID phaseId, Map<String, Object> payload) {
|
||||
try {
|
||||
UUID equipeId =
|
||||
payload.get("equipeId") != null
|
||||
? UUID.fromString(payload.get("equipeId").toString())
|
||||
: null;
|
||||
UUID chefEquipeId =
|
||||
payload.get("chefEquipeId") != null
|
||||
? UUID.fromString(payload.get("chefEquipeId").toString())
|
||||
: null;
|
||||
|
||||
PhaseChantier phase = phaseChantierService.affecterEquipe(phaseId, equipeId, chefEquipeId);
|
||||
return Response.ok(phase).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'affectation d'équipe: " + phaseId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'affectation d'équipe"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Planifie automatiquement les phases d'un chantier */
|
||||
@POST
|
||||
@Path("/chantier/{chantierId}/planifier")
|
||||
public Response planifierPhasesAutomatique(
|
||||
@PathParam("chantierId") UUID chantierId, Map<String, String> payload) {
|
||||
try {
|
||||
LocalDate dateDebut = LocalDate.parse(payload.get("dateDebut"));
|
||||
List<PhaseChantier> phases =
|
||||
phaseChantierService.planifierPhasesAutomatique(chantierId, dateDebut);
|
||||
return Response.ok(phases).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Date de début invalide"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la planification automatique: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la planification automatique"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime une phase */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deletePhase(@PathParam("id") UUID id) {
|
||||
try {
|
||||
phaseChantierService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression de la phase: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression de la phase"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des phases */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = phaseChantierService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
package dev.lions.btpxpress.presentation.controller;
|
||||
|
||||
import dev.lions.btpxpress.application.service.StockService;
|
||||
import dev.lions.btpxpress.domain.core.entity.CategorieStock;
|
||||
import dev.lions.btpxpress.domain.core.entity.StatutStock;
|
||||
import dev.lions.btpxpress.domain.core.entity.Stock;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Contrôleur REST pour la gestion des stocks et inventaires Permet de gérer les entrées, sorties,
|
||||
* réservations et suivi des stocks BTP
|
||||
*/
|
||||
@Path("/api/v1/stocks")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Stocks", description = "Gestion des stocks et inventaires BTP")
|
||||
public class StockController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StockController.class);
|
||||
|
||||
@Inject StockService stockService;
|
||||
|
||||
/** Récupère tous les stocks */
|
||||
@GET
|
||||
public Response getAllStocks() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findAll();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un stock par son ID */
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getStockById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
Stock stock = stockService.findById(id);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère un stock par sa référence */
|
||||
@GET
|
||||
@Path("/reference/{reference}")
|
||||
public Response getStockByReference(@PathParam("reference") String reference) {
|
||||
try {
|
||||
Stock stock = stockService.findByReference(reference);
|
||||
if (stock == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", "Stock non trouvé"))
|
||||
.build();
|
||||
}
|
||||
return Response.ok(stock).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du stock par référence: " + reference, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération du stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche des stocks par désignation */
|
||||
@GET
|
||||
@Path("/search/designation")
|
||||
public Response searchByDesignation(@QueryParam("designation") String designation) {
|
||||
try {
|
||||
if (designation == null || designation.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Désignation requise"))
|
||||
.build();
|
||||
}
|
||||
List<Stock> stocks = stockService.searchByDesignation(designation);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche par désignation: " + designation, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks par catégorie */
|
||||
@GET
|
||||
@Path("/categorie/{categorie}")
|
||||
public Response getStocksByCategorie(@PathParam("categorie") CategorieStock categorie) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findByCategorie(categorie);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks par catégorie: " + categorie, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks par statut */
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response getStocksByStatut(@PathParam("statut") StatutStock statut) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findByStatut(statut);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks par statut: " + statut, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks actifs */
|
||||
@GET
|
||||
@Path("/actifs")
|
||||
public Response getStocksActifs() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findActifs();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks actifs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks par fournisseur */
|
||||
@GET
|
||||
@Path("/fournisseur/{fournisseurId}")
|
||||
public Response getStocksByFournisseur(@PathParam("fournisseurId") UUID fournisseurId) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findByFournisseur(fournisseurId);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks du fournisseur: " + fournisseurId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks par chantier */
|
||||
@GET
|
||||
@Path("/chantier/{chantierId}")
|
||||
public Response getStocksByChantier(@PathParam("chantierId") UUID chantierId) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findByChantier(chantierId);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks du chantier: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks en rupture */
|
||||
@GET
|
||||
@Path("/rupture")
|
||||
public Response getStocksEnRupture() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksEnRupture();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks en rupture", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks sous quantité minimum */
|
||||
@GET
|
||||
@Path("/sous-minimum")
|
||||
public Response getStocksSousQuantiteMinimum() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksSousQuantiteMinimum();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks sous minimum", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks sous quantité de sécurité */
|
||||
@GET
|
||||
@Path("/sous-securite")
|
||||
public Response getStocksSousQuantiteSecurite() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksSousQuantiteSecurite();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks sous sécurité", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks à commander */
|
||||
@GET
|
||||
@Path("/a-commander")
|
||||
public Response getStocksACommander() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksACommander();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks à commander", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks périmés */
|
||||
@GET
|
||||
@Path("/perimes")
|
||||
public Response getStocksPerimes() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksPerimes();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks périmés", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks proches de la péremption */
|
||||
@GET
|
||||
@Path("/proches-peremption")
|
||||
public Response getStocksProchesPeremption(
|
||||
@QueryParam("nbJours") @DefaultValue("30") int nbJours) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksProchesPeremption(nbJours);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks proches péremption", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les stocks avec réservations */
|
||||
@GET
|
||||
@Path("/avec-reservations")
|
||||
public Response getStocksAvecReservations() {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findStocksAvecReservations();
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des stocks avec réservations", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Crée un nouveau stock */
|
||||
@POST
|
||||
public Response createStock(@Valid Stock stock) {
|
||||
try {
|
||||
Stock nouveauStock = stockService.create(stock);
|
||||
return Response.status(Response.Status.CREATED).entity(nouveauStock).build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du stock", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la création du stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Met à jour un stock */
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateStock(@PathParam("id") UUID id, @Valid Stock stockData) {
|
||||
try {
|
||||
Stock stock = stockService.update(id, stockData);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour du stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la mise à jour du stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Entrée de stock */
|
||||
@POST
|
||||
@Path("/{id}/entree")
|
||||
public Response entreeStock(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal quantite = new BigDecimal(payload.get("quantite").toString());
|
||||
String motif = payload.get("motif") != null ? payload.get("motif").toString() : null;
|
||||
String numeroDocument =
|
||||
payload.get("numeroDocument") != null ? payload.get("numeroDocument").toString() : null;
|
||||
|
||||
Stock stock = stockService.entreeStock(id, quantite, motif, numeroDocument);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Quantité ou données invalides"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'entrée de stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'entrée de stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sortie de stock */
|
||||
@POST
|
||||
@Path("/{id}/sortie")
|
||||
public Response sortieStock(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal quantite = new BigDecimal(payload.get("quantite").toString());
|
||||
String motif = payload.get("motif") != null ? payload.get("motif").toString() : null;
|
||||
String numeroDocument =
|
||||
payload.get("numeroDocument") != null ? payload.get("numeroDocument").toString() : null;
|
||||
|
||||
Stock stock = stockService.sortieStock(id, quantite, motif, numeroDocument);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Quantité insuffisante ou données invalides"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la sortie de stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la sortie de stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Réservation de stock */
|
||||
@POST
|
||||
@Path("/{id}/reserver")
|
||||
public Response reserverStock(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal quantite = new BigDecimal(payload.get("quantite").toString());
|
||||
String motif = payload.get("motif") != null ? payload.get("motif").toString() : null;
|
||||
|
||||
Stock stock = stockService.reserverStock(id, quantite, motif);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Quantité insuffisante ou données invalides"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la réservation de stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la réservation de stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Libération de réservation */
|
||||
@POST
|
||||
@Path("/{id}/liberer-reservation")
|
||||
public Response libererReservation(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal quantite = new BigDecimal(payload.get("quantite").toString());
|
||||
|
||||
Stock stock = stockService.libererReservation(id, quantite);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Quantité invalide"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la libération de réservation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la libération de réservation"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Inventaire d'un stock */
|
||||
@POST
|
||||
@Path("/{id}/inventaire")
|
||||
public Response inventaireStock(@PathParam("id") UUID id, Map<String, Object> payload) {
|
||||
try {
|
||||
BigDecimal quantiteReelle = new BigDecimal(payload.get("quantiteReelle").toString());
|
||||
String motif = payload.get("motif") != null ? payload.get("motif").toString() : "Inventaire";
|
||||
|
||||
Stock stock = stockService.inventaireStock(id, quantiteReelle, motif);
|
||||
return Response.ok(stock).build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Quantité invalide"))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'inventaire du stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de l'inventaire du stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Supprime un stock */
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteStock(@PathParam("id") UUID id) {
|
||||
try {
|
||||
stockService.delete(id);
|
||||
return Response.noContent().build();
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suppression du stock: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la suppression du stock"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Recherche de stocks par multiple critères */
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchStocks(@QueryParam("term") String searchTerm) {
|
||||
try {
|
||||
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Terme de recherche requis"))
|
||||
.build();
|
||||
}
|
||||
List<Stock> stocks = stockService.searchStocks(searchTerm);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche de stocks: " + searchTerm, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la recherche"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les statistiques des stocks */
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
Map<String, Object> stats = stockService.getStatistiques();
|
||||
return Response.ok(stats).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des statistiques"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Calcule la valeur totale du stock */
|
||||
@GET
|
||||
@Path("/valeur-totale")
|
||||
public Response getValeurTotaleStock() {
|
||||
try {
|
||||
BigDecimal valeurTotale = stockService.calculateValeurTotaleStock();
|
||||
return Response.ok(Map.of("valeurTotale", valeurTotale)).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du calcul de la valeur totale", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors du calcul de la valeur totale"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les top stocks par valeur */
|
||||
@GET
|
||||
@Path("/top-valeur")
|
||||
public Response getTopStocksByValeur(@QueryParam("limit") @DefaultValue("10") int limit) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findTopStocksByValeur(limit);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des top stocks par valeur", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les top stocks par quantité */
|
||||
@GET
|
||||
@Path("/top-quantite")
|
||||
public Response getTopStocksByQuantite(@QueryParam("limit") @DefaultValue("10") int limit) {
|
||||
try {
|
||||
List<Stock> stocks = stockService.findTopStocksByQuantite(limit);
|
||||
return Response.ok(stocks).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des top stocks par quantité", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", "Erreur lors de la récupération des stocks"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,519 @@
|
||||
package dev.lions.btpxpress.presentation.rest;
|
||||
|
||||
import dev.lions.btpxpress.application.service.ComparaisonFournisseurService;
|
||||
import dev.lions.btpxpress.domain.core.entity.*;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* API REST pour la comparaison des fournisseurs EXPOSITION: Endpoints pour l'aide à la décision et
|
||||
* l'optimisation des achats BTP
|
||||
*/
|
||||
@Path("/api/v1/comparaisons-fournisseurs")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class ComparaisonFournisseurResource {
|
||||
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(ComparaisonFournisseurResource.class);
|
||||
|
||||
@Inject ComparaisonFournisseurService comparaisonService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION ===
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
public Response findAll(
|
||||
@QueryParam("page") @DefaultValue("0") int page,
|
||||
@QueryParam("size") @DefaultValue("50") int size) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/ - page: {}, size: {}", page, size);
|
||||
|
||||
List<ComparaisonFournisseur> comparaisons;
|
||||
if (page > 0 || size < 1000) {
|
||||
comparaisons = comparaisonService.findAll(page, size);
|
||||
} else {
|
||||
comparaisons = comparaisonService.findAll();
|
||||
}
|
||||
|
||||
return Response.ok(comparaisons).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des comparaisons", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des comparaisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response findById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/{}", id);
|
||||
|
||||
ComparaisonFournisseur comparaison = comparaisonService.findByIdRequired(id);
|
||||
return Response.ok(comparaison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de la comparaison: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération de la comparaison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/materiel/{materielId}")
|
||||
public Response findByMateriel(@PathParam("materielId") UUID materielId) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/materiel/{}", materielId);
|
||||
|
||||
List<ComparaisonFournisseur> comparaisons = comparaisonService.findByMateriel(materielId);
|
||||
return Response.ok(comparaisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des comparaisons pour matériel: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des comparaisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/fournisseur/{fournisseurId}")
|
||||
public Response findByFournisseur(@PathParam("fournisseurId") UUID fournisseurId) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/fournisseur/{}", fournisseurId);
|
||||
|
||||
List<ComparaisonFournisseur> comparaisons =
|
||||
comparaisonService.findByFournisseur(fournisseurId);
|
||||
return Response.ok(comparaisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des comparaisons pour fournisseur: " + fournisseurId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des comparaisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/session/{sessionId}")
|
||||
public Response findBySession(@PathParam("sessionId") String sessionId) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/session/{}", sessionId);
|
||||
|
||||
List<ComparaisonFournisseur> comparaisons = comparaisonService.findBySession(sessionId);
|
||||
return Response.ok(comparaisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des comparaisons pour session: " + sessionId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des comparaisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response search(@QueryParam("terme") String terme) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/search?terme={}", terme);
|
||||
|
||||
List<ComparaisonFournisseur> resultats = comparaisonService.search(terme);
|
||||
return Response.ok(resultats).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche avec terme: " + terme, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS MÉTIER SPÉCIALISÉS ===
|
||||
|
||||
@GET
|
||||
@Path("/meilleures-offres/{materielId}")
|
||||
public Response findMeilleuresOffres(
|
||||
@PathParam("materielId") UUID materielId,
|
||||
@QueryParam("limite") @DefaultValue("5") int limite) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/meilleures-offres/{}", materielId);
|
||||
|
||||
List<ComparaisonFournisseur> meilleures =
|
||||
comparaisonService.findMeilleuresOffres(materielId, limite);
|
||||
return Response.ok(meilleures).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des meilleures offres: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des meilleures offres: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/recommandees")
|
||||
public Response findOffresRecommandees() {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/recommandees");
|
||||
|
||||
List<ComparaisonFournisseur> recommandees = comparaisonService.findOffresRecommandees();
|
||||
return Response.ok(recommandees).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des offres recommandées", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des offres recommandées: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/gamme-prix")
|
||||
public Response findByGammePrix(
|
||||
@QueryParam("prixMin") @NotNull BigDecimal prixMin,
|
||||
@QueryParam("prixMax") @NotNull BigDecimal prixMax) {
|
||||
try {
|
||||
logger.debug(
|
||||
"GET /api/comparaisons-fournisseurs/gamme-prix?prixMin={}&prixMax={}", prixMin, prixMax);
|
||||
|
||||
List<ComparaisonFournisseur> comparaisons =
|
||||
comparaisonService.findByGammePrix(prixMin, prixMax);
|
||||
return Response.ok(comparaisons).build();
|
||||
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche par gamme de prix", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche par gamme de prix: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/disponibles-delai")
|
||||
public Response findDisponiblesDansDelai(
|
||||
@QueryParam("maxJours") @DefaultValue("30") int maxJours) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/disponibles-delai?maxJours={}", maxJours);
|
||||
|
||||
List<ComparaisonFournisseur> disponibles =
|
||||
comparaisonService.findDisponiblesDansDelai(maxJours);
|
||||
return Response.ok(disponibles).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche par délai", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche par délai: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE CRÉATION ET GESTION ===
|
||||
|
||||
@POST
|
||||
@Path("/lancer-comparaison")
|
||||
public Response lancerComparaison(@Valid LancerComparaisonRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/comparaisons-fournisseurs/lancer-comparaison");
|
||||
|
||||
String sessionId =
|
||||
comparaisonService.lancerComparaison(
|
||||
request.materielId,
|
||||
request.quantiteDemandee,
|
||||
request.uniteDemandee,
|
||||
request.dateDebutSouhaitee,
|
||||
request.dateFinSouhaitee,
|
||||
request.lieuLivraison,
|
||||
request.evaluateur);
|
||||
|
||||
return Response.status(Response.Status.CREATED)
|
||||
.entity(Map.of("sessionId", sessionId))
|
||||
.build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du lancement de la comparaison", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du lancement de la comparaison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateComparaison(
|
||||
@PathParam("id") UUID id, @Valid UpdateComparaisonRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/comparaisons-fournisseurs/{}", id);
|
||||
|
||||
ComparaisonFournisseurService.ComparaisonUpdateRequest updateRequest =
|
||||
mapToServiceRequest(request);
|
||||
|
||||
ComparaisonFournisseur comparaison = comparaisonService.updateComparaison(id, updateRequest);
|
||||
return Response.ok(comparaison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de la comparaison: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la mise à jour de la comparaison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/calculer-scores")
|
||||
public Response calculerScores(@PathParam("id") UUID id, @Valid CalculerScoresRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/comparaisons-fournisseurs/{}/calculer-scores", id);
|
||||
|
||||
ComparaisonFournisseur comparaison = comparaisonService.findByIdRequired(id);
|
||||
comparaisonService.calculerScores(comparaison, request.poidsCriteres);
|
||||
|
||||
return Response.ok(comparaison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du calcul des scores: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du calcul des scores: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/session/{sessionId}/classer")
|
||||
public Response classerComparaisons(@PathParam("sessionId") String sessionId) {
|
||||
try {
|
||||
logger.info("PUT /api/comparaisons-fournisseurs/session/{}/classer", sessionId);
|
||||
|
||||
comparaisonService.classerComparaisons(sessionId);
|
||||
|
||||
List<ComparaisonFournisseur> comparaisons = comparaisonService.findBySession(sessionId);
|
||||
return Response.ok(
|
||||
Map.of("message", "Classement effectué avec succès", "comparaisons", comparaisons))
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du classement des comparaisons: " + sessionId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du classement des comparaisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS D'ANALYSE ET RAPPORTS ===
|
||||
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/statistiques");
|
||||
|
||||
Map<String, Object> statistiques = comparaisonService.getStatistiques();
|
||||
return Response.ok(statistiques).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération des statistiques: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/evolution-prix/{materielId}")
|
||||
public Response analyserEvolutionPrix(
|
||||
@PathParam("materielId") UUID materielId,
|
||||
@QueryParam("dateDebut") @NotNull LocalDate dateDebut,
|
||||
@QueryParam("dateFin") @NotNull LocalDate dateFin) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/evolution-prix/{}", materielId);
|
||||
|
||||
List<Object> evolution =
|
||||
comparaisonService.analyserEvolutionPrix(materielId, dateDebut, dateFin);
|
||||
return Response.ok(evolution).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'analyse d'évolution des prix: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'analyse d'évolution des prix: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/delais-fournisseurs")
|
||||
public Response analyserDelaisFournisseurs() {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/delais-fournisseurs");
|
||||
|
||||
List<Object> delais = comparaisonService.analyserDelaisFournisseurs();
|
||||
return Response.ok(delais).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'analyse des délais fournisseurs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'analyse des délais fournisseurs: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/rapport/{sessionId}")
|
||||
public Response genererRapportComparaison(@PathParam("sessionId") String sessionId) {
|
||||
try {
|
||||
logger.debug("GET /api/comparaisons-fournisseurs/rapport/{}", sessionId);
|
||||
|
||||
Map<String, Object> rapport = comparaisonService.genererRapportComparaison(sessionId);
|
||||
return Response.ok(rapport).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération du rapport: " + sessionId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération du rapport: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS UTILITAIRES ===
|
||||
|
||||
@GET
|
||||
@Path("/criteres-comparaison")
|
||||
public Response getCriteresComparaison() {
|
||||
try {
|
||||
CritereComparaison[] criteres = CritereComparaison.values();
|
||||
|
||||
List<Map<String, Object>> criteresInfo =
|
||||
Arrays.stream(criteres)
|
||||
.map(
|
||||
critere -> {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("code", critere.name());
|
||||
map.put("libelle", critere.getLibelle());
|
||||
map.put("description", critere.getDescription());
|
||||
map.put("poidsDefaut", critere.getPoidsDefaut());
|
||||
map.put("uniteMesure", critere.getUniteMesure());
|
||||
map.put("icone", critere.getIcone());
|
||||
map.put("couleur", critere.getCouleur());
|
||||
return map;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Response.ok(criteresInfo).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des critères", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des critères: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === MÉTHODES UTILITAIRES ===
|
||||
|
||||
private ComparaisonFournisseurService.ComparaisonUpdateRequest mapToServiceRequest(
|
||||
UpdateComparaisonRequest request) {
|
||||
ComparaisonFournisseurService.ComparaisonUpdateRequest serviceRequest =
|
||||
new ComparaisonFournisseurService.ComparaisonUpdateRequest();
|
||||
|
||||
serviceRequest.disponible = request.disponible;
|
||||
serviceRequest.quantiteDisponible = request.quantiteDisponible;
|
||||
serviceRequest.dateDisponibilite = request.dateDisponibilite;
|
||||
serviceRequest.delaiLivraisonJours = request.delaiLivraisonJours;
|
||||
serviceRequest.prixUnitaireHT = request.prixUnitaireHT;
|
||||
serviceRequest.fraisLivraison = request.fraisLivraison;
|
||||
serviceRequest.fraisInstallation = request.fraisInstallation;
|
||||
serviceRequest.fraisMaintenance = request.fraisMaintenance;
|
||||
serviceRequest.cautionDemandee = request.cautionDemandee;
|
||||
serviceRequest.remiseAppliquee = request.remiseAppliquee;
|
||||
serviceRequest.dureeValiditeOffre = request.dureeValiditeOffre;
|
||||
serviceRequest.delaiPaiement = request.delaiPaiement;
|
||||
serviceRequest.garantieMois = request.garantieMois;
|
||||
serviceRequest.maintenanceIncluse = request.maintenanceIncluse;
|
||||
serviceRequest.formationIncluse = request.formationIncluse;
|
||||
serviceRequest.noteQualite = request.noteQualite;
|
||||
serviceRequest.noteFiabilite = request.noteFiabilite;
|
||||
serviceRequest.distanceKm = request.distanceKm;
|
||||
serviceRequest.conditionsParticulieres = request.conditionsParticulieres;
|
||||
serviceRequest.avantages = request.avantages;
|
||||
serviceRequest.inconvenients = request.inconvenients;
|
||||
serviceRequest.commentairesEvaluateur = request.commentairesEvaluateur;
|
||||
serviceRequest.recommandations = request.recommandations;
|
||||
serviceRequest.poidsCriteres = request.poidsCriteres;
|
||||
|
||||
return serviceRequest;
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class LancerComparaisonRequest {
|
||||
@NotNull public UUID materielId;
|
||||
|
||||
@NotNull public BigDecimal quantiteDemandee;
|
||||
|
||||
public String uniteDemandee;
|
||||
public LocalDate dateDebutSouhaitee;
|
||||
public LocalDate dateFinSouhaitee;
|
||||
public String lieuLivraison;
|
||||
public String evaluateur;
|
||||
}
|
||||
|
||||
public static class UpdateComparaisonRequest {
|
||||
public Boolean disponible;
|
||||
public BigDecimal quantiteDisponible;
|
||||
public LocalDate dateDisponibilite;
|
||||
public Integer delaiLivraisonJours;
|
||||
public BigDecimal prixUnitaireHT;
|
||||
public BigDecimal fraisLivraison;
|
||||
public BigDecimal fraisInstallation;
|
||||
public BigDecimal fraisMaintenance;
|
||||
public BigDecimal cautionDemandee;
|
||||
public BigDecimal remiseAppliquee;
|
||||
public Integer dureeValiditeOffre;
|
||||
public Integer delaiPaiement;
|
||||
public Integer garantieMois;
|
||||
public Boolean maintenanceIncluse;
|
||||
public Boolean formationIncluse;
|
||||
public BigDecimal noteQualite;
|
||||
public BigDecimal noteFiabilite;
|
||||
public BigDecimal distanceKm;
|
||||
public String conditionsParticulieres;
|
||||
public String avantages;
|
||||
public String inconvenients;
|
||||
public String commentairesEvaluateur;
|
||||
public String recommandations;
|
||||
public Map<CritereComparaison, Integer> poidsCriteres;
|
||||
}
|
||||
|
||||
public static class CalculerScoresRequest {
|
||||
public Map<CritereComparaison, Integer> poidsCriteres;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,849 @@
|
||||
package dev.lions.btpxpress.presentation.rest;
|
||||
|
||||
import dev.lions.btpxpress.application.service.LivraisonMaterielService;
|
||||
import dev.lions.btpxpress.domain.core.entity.*;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* API REST pour la gestion des livraisons de matériel EXPOSITION: Endpoints pour la logistique et
|
||||
* le suivi des livraisons BTP
|
||||
*/
|
||||
@Path("/api/v1/livraisons-materiel")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class LivraisonMaterielResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LivraisonMaterielResource.class);
|
||||
|
||||
@Inject LivraisonMaterielService livraisonService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION ===
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
public Response findAll(
|
||||
@QueryParam("page") @DefaultValue("0") int page,
|
||||
@QueryParam("size") @DefaultValue("50") int size) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/ - page: {}, size: {}", page, size);
|
||||
|
||||
List<LivraisonMateriel> livraisons;
|
||||
if (page > 0 || size < 1000) {
|
||||
livraisons = livraisonService.findAll(page, size);
|
||||
} else {
|
||||
livraisons = livraisonService.findAll();
|
||||
}
|
||||
|
||||
return Response.ok(livraisons).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response findById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/{}", id);
|
||||
|
||||
LivraisonMateriel livraison = livraisonService.findByIdRequired(id);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de la livraison: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération de la livraison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/numero/{numero}")
|
||||
public Response findByNumero(@PathParam("numero") String numeroLivraison) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/numero/{}", numeroLivraison);
|
||||
|
||||
return livraisonService
|
||||
.findByNumero(numeroLivraison)
|
||||
.map(livraison -> Response.ok(livraison).build())
|
||||
.orElse(
|
||||
Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("Livraison non trouvée avec le numéro: " + numeroLivraison)
|
||||
.build());
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération de la livraison par numéro: " + numeroLivraison, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération de la livraison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/reservation/{reservationId}")
|
||||
public Response findByReservation(@PathParam("reservationId") UUID reservationId) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/reservation/{}", reservationId);
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findByReservation(reservationId);
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des livraisons pour réservation: " + reservationId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/chantier/{chantierId}")
|
||||
public Response findByChantier(@PathParam("chantierId") UUID chantierId) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/chantier/{}", chantierId);
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findByChantier(chantierId);
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons pour chantier: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response findByStatut(@PathParam("statut") String statutStr) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/statut/{}", statutStr);
|
||||
|
||||
StatutLivraison statut = StatutLivraison.fromString(statutStr);
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findByStatut(statut);
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons par statut: " + statutStr, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/transporteur/{transporteur}")
|
||||
public Response findByTransporteur(@PathParam("transporteur") String transporteur) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/transporteur/{}", transporteur);
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findByTransporteur(transporteur);
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des livraisons pour transporteur: " + transporteur, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response search(@QueryParam("terme") String terme) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/search?terme={}", terme);
|
||||
|
||||
List<LivraisonMateriel> resultats = livraisonService.search(terme);
|
||||
return Response.ok(resultats).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche avec terme: " + terme, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS MÉTIER SPÉCIALISÉS ===
|
||||
|
||||
@GET
|
||||
@Path("/du-jour")
|
||||
public Response findLivraisonsDuJour() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/du-jour");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findLivraisonsDuJour();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons du jour", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/en-cours")
|
||||
public Response findLivraisonsEnCours() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/en-cours");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findLivraisonsEnCours();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons en cours", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/en-retard")
|
||||
public Response findLivraisonsEnRetard() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/en-retard");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findLivraisonsEnRetard();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons en retard", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/avec-incidents")
|
||||
public Response findAvecIncidents() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/avec-incidents");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findAvecIncidents();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons avec incidents", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/prioritaires")
|
||||
public Response findLivraisonsPrioritaires() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/prioritaires");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findLivraisonsPrioritaires();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons prioritaires", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/tracking-actif")
|
||||
public Response findAvecTrackingActif() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/tracking-actif");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findAvecTrackingActif();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons avec tracking", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/necessitant-action")
|
||||
public Response findNecessitantAction() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/necessitant-action");
|
||||
|
||||
List<LivraisonMateriel> livraisons = livraisonService.findNecessitantAction();
|
||||
return Response.ok(livraisons).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des livraisons nécessitant action", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des livraisons: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE CRÉATION ET MODIFICATION ===
|
||||
|
||||
@POST
|
||||
@Path("/")
|
||||
public Response creerLivraison(@Valid CreerLivraisonRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/livraisons-materiel/ - création livraison");
|
||||
|
||||
LivraisonMateriel livraison =
|
||||
livraisonService.creerLivraison(
|
||||
request.reservationId,
|
||||
request.typeTransport,
|
||||
request.dateLivraisonPrevue,
|
||||
request.heureLivraisonPrevue,
|
||||
request.transporteur,
|
||||
request.planificateur);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création de la livraison", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la création de la livraison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateLivraison(@PathParam("id") UUID id, @Valid UpdateLivraisonRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}", id);
|
||||
|
||||
LivraisonMaterielService.LivraisonUpdateRequest updateRequest = mapToServiceRequest(request);
|
||||
LivraisonMateriel livraison = livraisonService.updateLivraison(id, updateRequest);
|
||||
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de la livraison: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la mise à jour de la livraison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE GESTION DU WORKFLOW ===
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/demarrer-preparation")
|
||||
public Response demarrerPreparation(@PathParam("id") UUID id, @Valid OperateurRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/demarrer-preparation", id);
|
||||
|
||||
LivraisonMateriel livraison = livraisonService.demarrerPreparation(id, request.operateur);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du démarrage de la préparation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du démarrage de la préparation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/marquer-prete")
|
||||
public Response marquerPrete(@PathParam("id") UUID id, @Valid MarquerPreteRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/marquer-prete", id);
|
||||
|
||||
LivraisonMateriel livraison =
|
||||
livraisonService.marquerPrete(id, request.operateur, request.observations);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du marquage prêt: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du marquage prêt: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/demarrer-transit")
|
||||
public Response demarrerTransit(@PathParam("id") UUID id, @Valid DemarrerTransitRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/demarrer-transit", id);
|
||||
|
||||
LivraisonMateriel livraison =
|
||||
livraisonService.demarrerTransit(id, request.chauffeur, request.heureDepart);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du démarrage du transit: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du démarrage du transit: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/signaler-arrivee")
|
||||
public Response signalerArrivee(@PathParam("id") UUID id, @Valid SignalerArriveeRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/signaler-arrivee", id);
|
||||
|
||||
LivraisonMateriel livraison =
|
||||
livraisonService.signalerArrivee(
|
||||
id, request.chauffeur, request.heureArrivee, request.latitude, request.longitude);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du signalement d'arrivée: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du signalement d'arrivée: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/commencer-dechargement")
|
||||
public Response commencerDechargement(@PathParam("id") UUID id, @Valid OperateurRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/commencer-dechargement", id);
|
||||
|
||||
LivraisonMateriel livraison = livraisonService.commencerDechargement(id, request.operateur);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du début de déchargement: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du début de déchargement: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/finaliser")
|
||||
public Response finaliserLivraison(@PathParam("id") UUID id, @Valid FinalisationRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/finaliser", id);
|
||||
|
||||
LivraisonMaterielService.FinalisationLivraisonRequest finalisationRequest =
|
||||
mapToFinalisationRequest(request);
|
||||
|
||||
LivraisonMateriel livraison = livraisonService.finaliserLivraison(id, finalisationRequest);
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la finalisation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la finalisation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/signaler-incident")
|
||||
public Response signalerIncident(
|
||||
@PathParam("id") UUID id, @Valid SignalerIncidentRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/signaler-incident", id);
|
||||
|
||||
LivraisonMaterielService.IncidentRequest incidentRequest = mapToIncidentRequest(request);
|
||||
LivraisonMateriel livraison = livraisonService.signalerIncident(id, incidentRequest);
|
||||
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du signalement d'incident: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du signalement d'incident: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/retarder")
|
||||
public Response retarderLivraison(
|
||||
@PathParam("id") UUID id, @Valid RetarderLivraisonRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/retarder", id);
|
||||
|
||||
LivraisonMateriel livraison =
|
||||
livraisonService.retarderLivraison(
|
||||
id,
|
||||
request.nouvelleDatePrevue,
|
||||
request.nouvelleHeurePrevue,
|
||||
request.motif,
|
||||
request.operateur);
|
||||
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du retard de livraison: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du retard de livraison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/annuler")
|
||||
public Response annulerLivraison(
|
||||
@PathParam("id") UUID id, @Valid AnnulerLivraisonRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/livraisons-materiel/{}/annuler", id);
|
||||
|
||||
LivraisonMateriel livraison =
|
||||
livraisonService.annulerLivraison(id, request.motifAnnulation, request.operateur);
|
||||
|
||||
return Response.ok(livraison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'annulation de livraison: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'annulation de livraison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE SUIVI ET TRACKING ===
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/position-gps")
|
||||
public Response mettreAJourPositionGPS(
|
||||
@PathParam("id") UUID id, @Valid PositionGPSRequest request) {
|
||||
try {
|
||||
livraisonService.mettreAJourPositionGPS(
|
||||
id, request.latitude, request.longitude, request.vitesseKmh);
|
||||
return Response.ok(Map.of("message", "Position mise à jour")).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour GPS: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la mise à jour GPS: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}/eta")
|
||||
public Response calculerETA(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/{}/eta", id);
|
||||
|
||||
Map<String, Object> eta = livraisonService.calculerETA(id);
|
||||
return Response.ok(eta).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du calcul ETA: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du calcul ETA: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS D'OPTIMISATION ===
|
||||
|
||||
@POST
|
||||
@Path("/optimiser-itineraires")
|
||||
public Response optimiserItineraires(@Valid OptimiserItinerairesRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/livraisons-materiel/optimiser-itineraires");
|
||||
|
||||
List<LivraisonMateriel> itineraireOptimise =
|
||||
livraisonService.optimiserItineraires(request.date, request.transporteur);
|
||||
|
||||
return Response.ok(
|
||||
Map.of(
|
||||
"itineraireOptimise",
|
||||
itineraireOptimise,
|
||||
"nombreLivraisons",
|
||||
itineraireOptimise.size()))
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'optimisation des itinéraires", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'optimisation des itinéraires: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS STATISTIQUES ===
|
||||
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/statistiques");
|
||||
|
||||
Map<String, Object> statistiques = livraisonService.getStatistiques();
|
||||
return Response.ok(statistiques).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération des statistiques: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/tableau-bord")
|
||||
public Response getTableauBordLogistique() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/tableau-bord");
|
||||
|
||||
Map<String, Object> tableauBord = livraisonService.getTableauBordLogistique();
|
||||
return Response.ok(tableauBord).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération du tableau de bord", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération du tableau de bord: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/performance-transporteurs")
|
||||
public Response analyserPerformanceTransporteurs() {
|
||||
try {
|
||||
logger.debug("GET /api/livraisons-materiel/performance-transporteurs");
|
||||
|
||||
List<Object> performance = livraisonService.analyserPerformanceTransporteurs();
|
||||
return Response.ok(performance).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'analyse des performances", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'analyse des performances: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === MÉTHODES UTILITAIRES ===
|
||||
|
||||
private LivraisonMaterielService.LivraisonUpdateRequest mapToServiceRequest(
|
||||
UpdateLivraisonRequest request) {
|
||||
LivraisonMaterielService.LivraisonUpdateRequest serviceRequest =
|
||||
new LivraisonMaterielService.LivraisonUpdateRequest();
|
||||
|
||||
serviceRequest.dateLivraisonPrevue = request.dateLivraisonPrevue;
|
||||
serviceRequest.heureLivraisonPrevue = request.heureLivraisonPrevue;
|
||||
serviceRequest.transporteur = request.transporteur;
|
||||
serviceRequest.chauffeur = request.chauffeur;
|
||||
serviceRequest.telephoneChauffeur = request.telephoneChauffeur;
|
||||
serviceRequest.immatriculation = request.immatriculation;
|
||||
serviceRequest.contactReception = request.contactReception;
|
||||
serviceRequest.telephoneContact = request.telephoneContact;
|
||||
serviceRequest.instructionsSpeciales = request.instructionsSpeciales;
|
||||
serviceRequest.accesChantier = request.accesChantier;
|
||||
serviceRequest.modifiePar = request.modifiePar;
|
||||
|
||||
return serviceRequest;
|
||||
}
|
||||
|
||||
private LivraisonMaterielService.FinalisationLivraisonRequest mapToFinalisationRequest(
|
||||
FinalisationRequest request) {
|
||||
LivraisonMaterielService.FinalisationLivraisonRequest finalisationRequest =
|
||||
new LivraisonMaterielService.FinalisationLivraisonRequest();
|
||||
|
||||
finalisationRequest.quantiteLivree = request.quantiteLivree;
|
||||
finalisationRequest.etatMateriel = request.etatMateriel;
|
||||
finalisationRequest.observations = request.observations;
|
||||
finalisationRequest.receptionnaire = request.receptionnaire;
|
||||
finalisationRequest.conforme = request.conforme;
|
||||
finalisationRequest.photoLivraison = request.photoLivraison;
|
||||
|
||||
return finalisationRequest;
|
||||
}
|
||||
|
||||
private LivraisonMaterielService.IncidentRequest mapToIncidentRequest(
|
||||
SignalerIncidentRequest request) {
|
||||
LivraisonMaterielService.IncidentRequest incidentRequest =
|
||||
new LivraisonMaterielService.IncidentRequest();
|
||||
|
||||
incidentRequest.typeIncident = request.typeIncident;
|
||||
incidentRequest.description = request.description;
|
||||
incidentRequest.impact = request.impact;
|
||||
incidentRequest.actionsCorrectives = request.actionsCorrectives;
|
||||
incidentRequest.declarant = request.declarant;
|
||||
|
||||
return incidentRequest;
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class CreerLivraisonRequest {
|
||||
@NotNull public UUID reservationId;
|
||||
|
||||
@NotNull public TypeTransport typeTransport;
|
||||
|
||||
@NotNull public LocalDate dateLivraisonPrevue;
|
||||
|
||||
public LocalTime heureLivraisonPrevue;
|
||||
public String transporteur;
|
||||
public String planificateur;
|
||||
}
|
||||
|
||||
public static class UpdateLivraisonRequest {
|
||||
public LocalDate dateLivraisonPrevue;
|
||||
public LocalTime heureLivraisonPrevue;
|
||||
public String transporteur;
|
||||
public String chauffeur;
|
||||
public String telephoneChauffeur;
|
||||
public String immatriculation;
|
||||
public String contactReception;
|
||||
public String telephoneContact;
|
||||
public String instructionsSpeciales;
|
||||
public String accesChantier;
|
||||
public String modifiePar;
|
||||
}
|
||||
|
||||
public static class OperateurRequest {
|
||||
@NotNull public String operateur;
|
||||
}
|
||||
|
||||
public static class MarquerPreteRequest {
|
||||
@NotNull public String operateur;
|
||||
|
||||
public String observations;
|
||||
}
|
||||
|
||||
public static class DemarrerTransitRequest {
|
||||
@NotNull public String chauffeur;
|
||||
|
||||
public LocalTime heureDepart;
|
||||
}
|
||||
|
||||
public static class SignalerArriveeRequest {
|
||||
@NotNull public String chauffeur;
|
||||
|
||||
public LocalTime heureArrivee;
|
||||
public BigDecimal latitude;
|
||||
public BigDecimal longitude;
|
||||
}
|
||||
|
||||
public static class FinalisationRequest {
|
||||
@NotNull public BigDecimal quantiteLivree;
|
||||
|
||||
public String etatMateriel;
|
||||
public String observations;
|
||||
|
||||
@NotNull public String receptionnaire;
|
||||
|
||||
public Boolean conforme;
|
||||
public String photoLivraison;
|
||||
}
|
||||
|
||||
public static class SignalerIncidentRequest {
|
||||
@NotNull public String typeIncident;
|
||||
|
||||
@NotNull public String description;
|
||||
|
||||
public String impact;
|
||||
public String actionsCorrectives;
|
||||
|
||||
@NotNull public String declarant;
|
||||
}
|
||||
|
||||
public static class RetarderLivraisonRequest {
|
||||
@NotNull public LocalDate nouvelleDatePrevue;
|
||||
|
||||
public LocalTime nouvelleHeurePrevue;
|
||||
|
||||
@NotNull public String motif;
|
||||
|
||||
@NotNull public String operateur;
|
||||
}
|
||||
|
||||
public static class AnnulerLivraisonRequest {
|
||||
@NotNull public String motifAnnulation;
|
||||
|
||||
@NotNull public String operateur;
|
||||
}
|
||||
|
||||
public static class PositionGPSRequest {
|
||||
@NotNull public BigDecimal latitude;
|
||||
|
||||
@NotNull public BigDecimal longitude;
|
||||
|
||||
public Integer vitesseKmh;
|
||||
}
|
||||
|
||||
public static class OptimiserItinerairesRequest {
|
||||
@NotNull public LocalDate date;
|
||||
|
||||
public String transporteur;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
package dev.lions.btpxpress.presentation.rest;
|
||||
|
||||
import dev.lions.btpxpress.application.service.MaterielFournisseurService;
|
||||
import dev.lions.btpxpress.domain.core.entity.*;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* API REST pour la gestion intégrée matériel-fournisseur EXPOSITION: Endpoints pour l'orchestration
|
||||
* matériel-fournisseur-catalogue
|
||||
*/
|
||||
@Path("/api/v1/materiel-fournisseur")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class MaterielFournisseurResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MaterielFournisseurResource.class);
|
||||
|
||||
@Inject MaterielFournisseurService materielFournisseurService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION INTÉGRÉE ===
|
||||
|
||||
@GET
|
||||
@Path("/materiels-avec-fournisseurs")
|
||||
public Response findMaterielsAvecFournisseurs() {
|
||||
try {
|
||||
logger.debug("GET /api/materiel-fournisseur/materiels-avec-fournisseurs");
|
||||
|
||||
List<Object> materiels = materielFournisseurService.findMaterielsAvecFournisseurs();
|
||||
return Response.ok(materiels).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des matériels avec fournisseurs", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des matériels: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/materiel/{materielId}/avec-offres")
|
||||
public Response findMaterielAvecOffres(@PathParam("materielId") UUID materielId) {
|
||||
try {
|
||||
logger.debug("GET /api/materiel-fournisseur/materiel/{}/avec-offres", materielId);
|
||||
|
||||
Object materielAvecOffres = materielFournisseurService.findMaterielAvecOffres(materielId);
|
||||
return Response.ok(materielAvecOffres).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du matériel avec offres: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération du matériel: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/fournisseurs-avec-materiels")
|
||||
public Response findFournisseursAvecMateriels() {
|
||||
try {
|
||||
logger.debug("GET /api/materiel-fournisseur/fournisseurs-avec-materiels");
|
||||
|
||||
List<Object> fournisseurs = materielFournisseurService.findFournisseursAvecMateriels();
|
||||
return Response.ok(fournisseurs).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des fournisseurs avec matériels", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des fournisseurs: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE CRÉATION INTÉGRÉE ===
|
||||
|
||||
@POST
|
||||
@Path("/materiel-avec-fournisseur")
|
||||
public Response createMaterielAvecFournisseur(
|
||||
@Valid CreateMaterielAvecFournisseurRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/materiel-fournisseur/materiel-avec-fournisseur");
|
||||
|
||||
Materiel materiel =
|
||||
materielFournisseurService.createMaterielAvecFournisseur(
|
||||
request.nom,
|
||||
request.marque,
|
||||
request.modele,
|
||||
request.numeroSerie,
|
||||
request.type,
|
||||
request.description,
|
||||
request.propriete,
|
||||
request.fournisseurId,
|
||||
request.valeurAchat,
|
||||
request.localisation);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(materiel).build();
|
||||
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du matériel avec fournisseur", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la création du matériel: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/ajouter-au-catalogue")
|
||||
public Response ajouterMaterielAuCatalogue(@Valid AjouterMaterielCatalogueRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/materiel-fournisseur/ajouter-au-catalogue");
|
||||
|
||||
CatalogueFournisseur entree =
|
||||
materielFournisseurService.ajouterMaterielAuCatalogue(
|
||||
request.materielId,
|
||||
request.fournisseurId,
|
||||
request.referenceFournisseur,
|
||||
request.prixUnitaire,
|
||||
request.unitePrix,
|
||||
request.delaiLivraisonJours);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(entree).build();
|
||||
|
||||
} catch (BadRequestException | NotFoundException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'ajout du matériel au catalogue", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'ajout au catalogue: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE RECHERCHE AVANCÉE ===
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response searchMaterielsAvecFournisseurs(
|
||||
@QueryParam("terme") String terme,
|
||||
@QueryParam("propriete") String proprieteStr,
|
||||
@QueryParam("prixMax") BigDecimal prixMax,
|
||||
@QueryParam("delaiMax") Integer delaiMax) {
|
||||
try {
|
||||
logger.debug(
|
||||
"GET /api/materiel-fournisseur/search?terme={}&propriete={}&prixMax={}&delaiMax={}",
|
||||
terme,
|
||||
proprieteStr,
|
||||
prixMax,
|
||||
delaiMax);
|
||||
|
||||
ProprieteMateriel propriete = null;
|
||||
if (proprieteStr != null && !proprieteStr.trim().isEmpty()) {
|
||||
try {
|
||||
propriete = ProprieteMateriel.valueOf(proprieteStr.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity("Propriété matériel invalide: " + proprieteStr)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> resultats =
|
||||
materielFournisseurService.searchMaterielsAvecFournisseurs(
|
||||
terme, propriete, prixMax, delaiMax);
|
||||
|
||||
return Response.ok(resultats).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche avancée", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/comparer-prix/{materielId}")
|
||||
public Response comparerPrixFournisseurs(@PathParam("materielId") UUID materielId) {
|
||||
try {
|
||||
logger.debug("GET /api/materiel-fournisseur/comparer-prix/{}", materielId);
|
||||
|
||||
Object comparaison = materielFournisseurService.comparerPrixFournisseurs(materielId);
|
||||
return Response.ok(comparaison).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la comparaison des prix pour: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la comparaison des prix: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE GESTION ===
|
||||
|
||||
@PUT
|
||||
@Path("/materiel/{materielId}/changer-fournisseur")
|
||||
public Response changerFournisseurMateriel(
|
||||
@PathParam("materielId") UUID materielId, @Valid ChangerFournisseurRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/materiel-fournisseur/materiel/{}/changer-fournisseur", materielId);
|
||||
|
||||
Materiel materiel =
|
||||
materielFournisseurService.changerFournisseurMateriel(
|
||||
materielId, request.nouveauFournisseurId, request.nouvellePropriete);
|
||||
|
||||
return Response.ok(materiel).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du changement de fournisseur: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du changement de fournisseur: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS STATISTIQUES ===
|
||||
|
||||
@GET
|
||||
@Path("/statistiques-propriete")
|
||||
public Response getStatistiquesMaterielsParPropriete() {
|
||||
try {
|
||||
logger.debug("GET /api/materiel-fournisseur/statistiques-propriete");
|
||||
|
||||
Object statistiques = materielFournisseurService.getStatistiquesMaterielsParPropriete();
|
||||
return Response.ok(statistiques).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération des statistiques par propriété", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération des statistiques: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/tableau-bord")
|
||||
public Response getTableauBordMaterielFournisseur() {
|
||||
try {
|
||||
logger.debug("GET /api/materiel-fournisseur/tableau-bord");
|
||||
|
||||
Object tableauBord = materielFournisseurService.getTableauBordMaterielFournisseur();
|
||||
return Response.ok(tableauBord).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération du tableau de bord", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération du tableau de bord: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class CreateMaterielAvecFournisseurRequest {
|
||||
@NotNull public String nom;
|
||||
|
||||
public String marque;
|
||||
public String modele;
|
||||
public String numeroSerie;
|
||||
|
||||
@NotNull public TypeMateriel type;
|
||||
|
||||
public String description;
|
||||
|
||||
@NotNull public ProprieteMateriel propriete;
|
||||
|
||||
public UUID fournisseurId;
|
||||
public BigDecimal valeurAchat;
|
||||
public String localisation;
|
||||
}
|
||||
|
||||
public static class AjouterMaterielCatalogueRequest {
|
||||
@NotNull public UUID materielId;
|
||||
|
||||
@NotNull public UUID fournisseurId;
|
||||
|
||||
@NotNull public String referenceFournisseur;
|
||||
|
||||
@NotNull public BigDecimal prixUnitaire;
|
||||
|
||||
@NotNull public UnitePrix unitePrix;
|
||||
|
||||
public Integer delaiLivraisonJours;
|
||||
}
|
||||
|
||||
public static class ChangerFournisseurRequest {
|
||||
public UUID nouveauFournisseurId;
|
||||
|
||||
@NotNull public ProprieteMateriel nouvellePropriete;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
package dev.lions.btpxpress.presentation.rest;
|
||||
|
||||
import dev.lions.btpxpress.application.service.PermissionService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Permission;
|
||||
import dev.lions.btpxpress.domain.core.entity.Permission.PermissionCategory;
|
||||
import dev.lions.btpxpress.domain.core.entity.UserRole;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* API REST pour la gestion des permissions EXPOSITION: Consultation des droits d'accès et
|
||||
* permissions par rôle
|
||||
*/
|
||||
@Path("/api/permissions")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class PermissionResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PermissionResource.class);
|
||||
|
||||
@Inject PermissionService permissionService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION ===
|
||||
|
||||
/** Récupère toutes les permissions disponibles */
|
||||
@GET
|
||||
@Path("/all")
|
||||
public Response getAllPermissions() {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/all");
|
||||
|
||||
List<Object> permissions =
|
||||
Arrays.stream(Permission.values())
|
||||
.map(
|
||||
p ->
|
||||
Map.of(
|
||||
"code", p.getCode(),
|
||||
"description", p.getDescription(),
|
||||
"category", p.getCategory().name(),
|
||||
"categoryDisplay", p.getCategory().getDisplayName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Response.ok(permissions).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des permissions", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des permissions: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les permissions par catégorie */
|
||||
@GET
|
||||
@Path("/categories")
|
||||
public Response getPermissionsByCategory() {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/categories");
|
||||
|
||||
Map<String, Object> result =
|
||||
Arrays.stream(PermissionCategory.values())
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
category -> category.name(),
|
||||
category ->
|
||||
Map.of(
|
||||
"displayName", category.getDisplayName(),
|
||||
"permissions",
|
||||
Permission.getByCategory(category).stream()
|
||||
.map(
|
||||
p ->
|
||||
Map.of(
|
||||
"code", p.getCode(),
|
||||
"description", p.getDescription()))
|
||||
.collect(Collectors.toList()))));
|
||||
|
||||
return Response.ok(result).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des permissions par catégorie", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des permissions: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les permissions d'un rôle spécifique */
|
||||
@GET
|
||||
@Path("/role/{role}")
|
||||
public Response getPermissionsByRole(@PathParam("role") String roleStr) {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/role/{}", roleStr);
|
||||
|
||||
UserRole role = UserRole.valueOf(roleStr.toUpperCase());
|
||||
Map<String, Object> summary = permissionService.getPermissionSummary(role);
|
||||
|
||||
return Response.ok(summary).build();
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity("Rôle invalide: " + roleStr)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des permissions pour le rôle: " + roleStr, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des permissions: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Vérifie si un rôle a une permission spécifique */
|
||||
@GET
|
||||
@Path("/check/{role}/{permission}")
|
||||
public Response checkPermission(
|
||||
@PathParam("role") String roleStr, @PathParam("permission") String permissionCode) {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/check/{}/{}", roleStr, permissionCode);
|
||||
|
||||
UserRole role = UserRole.valueOf(roleStr.toUpperCase());
|
||||
boolean hasPermission = permissionService.hasPermission(role, permissionCode);
|
||||
|
||||
return Response.ok(
|
||||
Map.of(
|
||||
"role", role.getDisplayName(),
|
||||
"permission", permissionCode,
|
||||
"hasPermission", hasPermission))
|
||||
.build();
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity("Rôle invalide: " + roleStr)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la vérification de permission", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la vérification de permission: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère tous les rôles avec leurs permissions */
|
||||
@GET
|
||||
@Path("/roles")
|
||||
public Response getAllRolesWithPermissions() {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/roles");
|
||||
|
||||
Map<String, Object> result =
|
||||
Arrays.stream(UserRole.values())
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
role -> role.name(),
|
||||
role ->
|
||||
Map.of(
|
||||
"displayName", role.getDisplayName(),
|
||||
"description", role.getDescription(),
|
||||
"hierarchyLevel", role.getHierarchyLevel(),
|
||||
"isManagementRole", role.isManagementRole(),
|
||||
"isFieldRole", role.isFieldRole(),
|
||||
"isAdministrativeRole", role.isAdministrativeRole(),
|
||||
"permissions",
|
||||
permissionService.getPermissions(role).stream()
|
||||
.map(Permission::getCode)
|
||||
.collect(Collectors.toList()),
|
||||
"permissionCount", permissionService.getPermissions(role).size())));
|
||||
|
||||
return Response.ok(result).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des rôles et permissions", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des rôles: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Compare les permissions entre deux rôles */
|
||||
@GET
|
||||
@Path("/compare/{role1}/{role2}")
|
||||
public Response compareRoles(
|
||||
@PathParam("role1") String role1Str, @PathParam("role2") String role2Str) {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/compare/{}/{}", role1Str, role2Str);
|
||||
|
||||
UserRole role1 = UserRole.valueOf(role1Str.toUpperCase());
|
||||
UserRole role2 = UserRole.valueOf(role2Str.toUpperCase());
|
||||
|
||||
Set<Permission> permissions1 = permissionService.getPermissions(role1);
|
||||
Set<Permission> permissions2 = permissionService.getPermissions(role2);
|
||||
Set<Permission> missing1to2 = permissionService.getMissingPermissions(role1, role2);
|
||||
Set<Permission> missing2to1 = permissionService.getMissingPermissions(role2, role1);
|
||||
|
||||
Set<Permission> common =
|
||||
permissions1.stream().filter(permissions2::contains).collect(Collectors.toSet());
|
||||
|
||||
return Response.ok(
|
||||
Map.of(
|
||||
"role1",
|
||||
Map.of(
|
||||
"name", role1.getDisplayName(),
|
||||
"permissionCount", permissions1.size(),
|
||||
"permissions",
|
||||
permissions1.stream()
|
||||
.map(Permission::getCode)
|
||||
.collect(Collectors.toList())),
|
||||
"role2",
|
||||
Map.of(
|
||||
"name", role2.getDisplayName(),
|
||||
"permissionCount", permissions2.size(),
|
||||
"permissions",
|
||||
permissions2.stream()
|
||||
.map(Permission::getCode)
|
||||
.collect(Collectors.toList())),
|
||||
"common",
|
||||
Map.of(
|
||||
"count", common.size(),
|
||||
"permissions",
|
||||
common.stream()
|
||||
.map(Permission::getCode)
|
||||
.collect(Collectors.toList())),
|
||||
"onlyInRole1",
|
||||
Map.of(
|
||||
"count", missing2to1.size(),
|
||||
"permissions",
|
||||
missing2to1.stream()
|
||||
.map(Permission::getCode)
|
||||
.collect(Collectors.toList())),
|
||||
"onlyInRole2",
|
||||
Map.of(
|
||||
"count", missing1to2.size(),
|
||||
"permissions",
|
||||
missing1to2.stream()
|
||||
.map(Permission::getCode)
|
||||
.collect(Collectors.toList()))))
|
||||
.build();
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity("Rôle invalide").build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la comparaison des rôles", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la comparaison: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Récupère les permissions spécifiques au gestionnaire de projet */
|
||||
@GET
|
||||
@Path("/gestionnaire")
|
||||
public Response getGestionnairePermissions() {
|
||||
try {
|
||||
logger.debug("GET /api/permissions/gestionnaire");
|
||||
|
||||
UserRole gestionnaireRole = UserRole.GESTIONNAIRE_PROJET;
|
||||
Map<String, Object> summary = permissionService.getPermissionSummary(gestionnaireRole);
|
||||
|
||||
// Ajout d'informations spécifiques au gestionnaire
|
||||
Map<PermissionCategory, List<Permission>> byCategory =
|
||||
permissionService.getPermissionsByCategory(gestionnaireRole);
|
||||
|
||||
return Response.ok(
|
||||
Map.of(
|
||||
"role", gestionnaireRole.getDisplayName(),
|
||||
"description", gestionnaireRole.getDescription(),
|
||||
"summary", summary,
|
||||
"specificities",
|
||||
Map.of(
|
||||
"clientManagement", "Gestion limitée aux clients assignés",
|
||||
"projectScope", "Chantiers et projets sous sa responsabilité uniquement",
|
||||
"budgetAccess", "Consultation et planification budgétaire",
|
||||
"materialReservation", "Réservation de matériel pour ses chantiers",
|
||||
"reportingLevel", "Rapports et statistiques de ses projets"),
|
||||
"categoriesDetails",
|
||||
byCategory.entrySet().stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
entry -> entry.getKey().getDisplayName(),
|
||||
entry ->
|
||||
entry.getValue().stream()
|
||||
.map(
|
||||
p ->
|
||||
Map.of(
|
||||
"code", p.getCode(),
|
||||
"description", p.getDescription()))
|
||||
.collect(Collectors.toList())))))
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des permissions gestionnaire", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des permissions: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Valide les permissions requises pour une fonctionnalité */
|
||||
@POST
|
||||
@Path("/validate")
|
||||
public Response validatePermissions(ValidationRequest request) {
|
||||
try {
|
||||
logger.debug("POST /api/permissions/validate");
|
||||
|
||||
UserRole role = UserRole.valueOf(request.role.toUpperCase());
|
||||
Set<Permission> requiredPermissions =
|
||||
request.requiredPermissions.stream()
|
||||
.map(Permission::fromCode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
boolean hasMinimum = permissionService.hasMinimumPermissions(role, requiredPermissions);
|
||||
|
||||
Map<String, Boolean> permissionChecks =
|
||||
request.requiredPermissions.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
code -> code, code -> permissionService.hasPermission(role, code)));
|
||||
|
||||
return Response.ok(
|
||||
Map.of(
|
||||
"role",
|
||||
role.getDisplayName(),
|
||||
"hasMinimumPermissions",
|
||||
hasMinimum,
|
||||
"permissionChecks",
|
||||
permissionChecks,
|
||||
"missingPermissions",
|
||||
request.requiredPermissions.stream()
|
||||
.filter(code -> !permissionService.hasPermission(role, code))
|
||||
.collect(Collectors.toList())))
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la validation des permissions", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la validation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class ValidationRequest {
|
||||
public String role;
|
||||
public List<String> requiredPermissions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,626 @@
|
||||
package dev.lions.btpxpress.presentation.rest;
|
||||
|
||||
import dev.lions.btpxpress.application.service.PlanningMaterielService;
|
||||
import dev.lions.btpxpress.domain.core.entity.*;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* API REST pour la gestion des plannings matériel EXPOSITION: Endpoints pour planification et
|
||||
* visualisation graphique
|
||||
*/
|
||||
@Path("/api/v1/plannings-materiel")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class PlanningMaterielResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PlanningMaterielResource.class);
|
||||
|
||||
@Inject PlanningMaterielService planningService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION ===
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
public Response findAll(
|
||||
@QueryParam("page") @DefaultValue("0") int page,
|
||||
@QueryParam("size") @DefaultValue("50") int size) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/ - page: {}, size: {}", page, size);
|
||||
|
||||
List<PlanningMateriel> plannings;
|
||||
if (page > 0 || size < 1000) {
|
||||
plannings = planningService.findAll(page, size);
|
||||
} else {
|
||||
plannings = planningService.findAll();
|
||||
}
|
||||
|
||||
return Response.ok(plannings).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response findById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/{}", id);
|
||||
|
||||
PlanningMateriel planning = planningService.findByIdRequired(id);
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/materiel/{materielId}")
|
||||
public Response findByMateriel(@PathParam("materielId") UUID materielId) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/materiel/{}", materielId);
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findByMateriel(materielId);
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings pour matériel: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/periode")
|
||||
public Response findByPeriode(
|
||||
@QueryParam("dateDebut") LocalDate dateDebut, @QueryParam("dateFin") LocalDate dateFin) {
|
||||
try {
|
||||
logger.debug(
|
||||
"GET /api/plannings-materiel/periode?dateDebut={}&dateFin={}", dateDebut, dateFin);
|
||||
|
||||
if (dateDebut == null || dateFin == null) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity("Les paramètres dateDebut et dateFin sont obligatoires")
|
||||
.build();
|
||||
}
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findByPeriode(dateDebut, dateFin);
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings par période", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response findByStatut(@PathParam("statut") String statutStr) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/statut/{}", statutStr);
|
||||
|
||||
StatutPlanning statut = StatutPlanning.fromString(statutStr);
|
||||
List<PlanningMateriel> plannings = planningService.findByStatut(statut);
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings par statut: " + statutStr, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/type/{type}")
|
||||
public Response findByType(@PathParam("type") String typeStr) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/type/{}", typeStr);
|
||||
|
||||
TypePlanning type = TypePlanning.fromString(typeStr);
|
||||
List<PlanningMateriel> plannings = planningService.findByType(type);
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings par type: " + typeStr, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response search(@QueryParam("terme") String terme) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/search?terme={}", terme);
|
||||
|
||||
List<PlanningMateriel> resultats = planningService.search(terme);
|
||||
return Response.ok(resultats).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche avec terme: " + terme, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS MÉTIER SPÉCIALISÉS ===
|
||||
|
||||
@GET
|
||||
@Path("/avec-conflits")
|
||||
public Response findAvecConflits() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/avec-conflits");
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findAvecConflits();
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings avec conflits", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/necessitant-attention")
|
||||
public Response findNecessitantAttention() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/necessitant-attention");
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findNecessitantAttention();
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings nécessitant attention", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/en-retard-validation")
|
||||
public Response findEnRetardValidation() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/en-retard-validation");
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findEnRetardValidation();
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings en retard", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/prioritaires")
|
||||
public Response findPrioritaires() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/prioritaires");
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findPrioritaires();
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings prioritaires", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/en-cours")
|
||||
public Response findEnCours() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/en-cours");
|
||||
|
||||
List<PlanningMateriel> plannings = planningService.findEnCours();
|
||||
return Response.ok(plannings).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des plannings en cours", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des plannings: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE CRÉATION ET MODIFICATION ===
|
||||
|
||||
@POST
|
||||
@Path("/")
|
||||
public Response createPlanning(@Valid CreatePlanningRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/plannings-materiel/ - création planning");
|
||||
|
||||
PlanningMateriel planning =
|
||||
planningService.createPlanning(
|
||||
request.materielId,
|
||||
request.nomPlanning,
|
||||
request.descriptionPlanning,
|
||||
request.dateDebut,
|
||||
request.dateFin,
|
||||
request.typePlanning,
|
||||
request.planificateur);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(planning).build();
|
||||
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création du planning", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la création du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updatePlanning(@PathParam("id") UUID id, @Valid UpdatePlanningRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}", id);
|
||||
|
||||
PlanningMateriel planning =
|
||||
planningService.updatePlanning(
|
||||
id,
|
||||
request.nomPlanning,
|
||||
request.descriptionPlanning,
|
||||
request.dateDebut,
|
||||
request.dateFin,
|
||||
request.modifiePar);
|
||||
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la mise à jour du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE GESTION DU WORKFLOW ===
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/valider")
|
||||
public Response validerPlanning(@PathParam("id") UUID id, @Valid ValiderPlanningRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}/valider", id);
|
||||
|
||||
PlanningMateriel planning =
|
||||
planningService.validerPlanning(id, request.valideur, request.commentaires);
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la validation du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la validation du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/mettre-en-revision")
|
||||
public Response mettreEnRevision(
|
||||
@PathParam("id") UUID id, @Valid RevisionPlanningRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}/mettre-en-revision", id);
|
||||
|
||||
PlanningMateriel planning = planningService.mettreEnRevision(id, request.motif);
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise en révision du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la mise en révision du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/archiver")
|
||||
public Response archiverPlanning(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}/archiver", id);
|
||||
|
||||
PlanningMateriel planning = planningService.archiverPlanning(id);
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'archivage du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'archivage du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/suspendre")
|
||||
public Response suspendrePlanning(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}/suspendre", id);
|
||||
|
||||
PlanningMateriel planning = planningService.suspendrePlanning(id);
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la suspension du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la suspension du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/reactiver")
|
||||
public Response reactiverPlanning(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}/reactiver", id);
|
||||
|
||||
PlanningMateriel planning = planningService.reactiverPlanning(id);
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la réactivation du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la réactivation du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE VÉRIFICATION ET ANALYSE ===
|
||||
|
||||
@GET
|
||||
@Path("/check-conflits")
|
||||
public Response checkConflits(
|
||||
@QueryParam("materielId") @NotNull UUID materielId,
|
||||
@QueryParam("dateDebut") @NotNull LocalDate dateDebut,
|
||||
@QueryParam("dateFin") @NotNull LocalDate dateFin,
|
||||
@QueryParam("excludeId") UUID excludeId) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/check-conflits");
|
||||
|
||||
List<PlanningMateriel> conflitsList =
|
||||
planningService.checkConflits(materielId, dateDebut, dateFin, excludeId);
|
||||
|
||||
return Response.ok(
|
||||
new Object() {
|
||||
public boolean disponible = conflitsList.isEmpty();
|
||||
public int nombreConflits = conflitsList.size();
|
||||
public List<PlanningMateriel> conflits = conflitsList;
|
||||
})
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la vérification des conflits", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la vérification des conflits: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/disponibilite/{materielId}")
|
||||
public Response analyserDisponibilite(
|
||||
@PathParam("materielId") UUID materielId,
|
||||
@QueryParam("dateDebut") @NotNull LocalDate dateDebut,
|
||||
@QueryParam("dateFin") @NotNull LocalDate dateFin) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/disponibilite/{}", materielId);
|
||||
|
||||
Map<String, Object> disponibilite =
|
||||
planningService.analyserDisponibilite(materielId, dateDebut, dateFin);
|
||||
return Response.ok(disponibilite).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'analyse de disponibilité: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'analyse de disponibilité: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS D'OPTIMISATION ===
|
||||
|
||||
@POST
|
||||
@Path("/optimiser")
|
||||
public Response optimiserPlannings() {
|
||||
try {
|
||||
logger.info("POST /api/plannings-materiel/optimiser");
|
||||
|
||||
List<PlanningMateriel> optimises = planningService.optimiserPlannings();
|
||||
return Response.ok(Map.of("nombreOptimises", optimises.size(), "plannings", optimises))
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'optimisation des plannings", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'optimisation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/optimiser")
|
||||
public Response optimiserPlanning(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.info("PUT /api/plannings-materiel/{}/optimiser", id);
|
||||
|
||||
PlanningMateriel planning = planningService.findByIdRequired(id);
|
||||
planningService.optimiserPlanning(planning);
|
||||
|
||||
return Response.ok(planning).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'optimisation du planning: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'optimisation du planning: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS STATISTIQUES ===
|
||||
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/statistiques");
|
||||
|
||||
Map<String, Object> statistiques = planningService.getStatistiques();
|
||||
return Response.ok(statistiques).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération des statistiques: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/tableau-bord")
|
||||
public Response getTableauBord() {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/tableau-bord");
|
||||
|
||||
Map<String, Object> tableauBord = planningService.getTableauBordPlannings();
|
||||
return Response.ok(tableauBord).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération du tableau de bord", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération du tableau de bord: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/taux-utilisation")
|
||||
public Response analyserTauxUtilisation(
|
||||
@QueryParam("dateDebut") @NotNull LocalDate dateDebut,
|
||||
@QueryParam("dateFin") @NotNull LocalDate dateFin) {
|
||||
try {
|
||||
logger.debug("GET /api/plannings-materiel/taux-utilisation");
|
||||
|
||||
List<Object> analyse = planningService.analyserTauxUtilisation(dateDebut, dateFin);
|
||||
return Response.ok(analyse).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'analyse des taux d'utilisation", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'analyse: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === MAINTENANCE AUTOMATIQUE ===
|
||||
|
||||
@POST
|
||||
@Path("/verifier-conflits")
|
||||
public Response verifierTousConflits() {
|
||||
try {
|
||||
logger.info("POST /api/plannings-materiel/verifier-conflits");
|
||||
|
||||
planningService.verifierTousConflits();
|
||||
return Response.ok(Map.of("message", "Vérification des conflits terminée")).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la vérification des conflits", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la vérification des conflits: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class CreatePlanningRequest {
|
||||
@NotNull public UUID materielId;
|
||||
|
||||
@NotNull public String nomPlanning;
|
||||
|
||||
public String descriptionPlanning;
|
||||
|
||||
@NotNull public LocalDate dateDebut;
|
||||
|
||||
@NotNull public LocalDate dateFin;
|
||||
|
||||
@NotNull public TypePlanning typePlanning;
|
||||
|
||||
public String planificateur;
|
||||
}
|
||||
|
||||
public static class UpdatePlanningRequest {
|
||||
public String nomPlanning;
|
||||
public String descriptionPlanning;
|
||||
public LocalDate dateDebut;
|
||||
public LocalDate dateFin;
|
||||
public String modifiePar;
|
||||
}
|
||||
|
||||
public static class ValiderPlanningRequest {
|
||||
@NotNull public String valideur;
|
||||
|
||||
public String commentaires;
|
||||
}
|
||||
|
||||
public static class RevisionPlanningRequest {
|
||||
@NotNull public String motif;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
package dev.lions.btpxpress.presentation.rest;
|
||||
|
||||
import dev.lions.btpxpress.application.service.ReservationMaterielService;
|
||||
import dev.lions.btpxpress.domain.core.entity.*;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* API REST pour la gestion des réservations matériel EXPOSITION: Endpoints pour l'affectation et
|
||||
* planification matériel/chantier
|
||||
*/
|
||||
@Path("/api/v1/reservations-materiel")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class ReservationMaterielResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ReservationMaterielResource.class);
|
||||
|
||||
@Inject ReservationMaterielService reservationService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION ===
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
public Response findAll(
|
||||
@QueryParam("page") @DefaultValue("0") int page,
|
||||
@QueryParam("size") @DefaultValue("50") int size) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/ - page: {}, size: {}", page, size);
|
||||
|
||||
List<ReservationMateriel> reservations;
|
||||
if (page > 0 || size < 1000) {
|
||||
reservations = reservationService.findAll(page, size);
|
||||
} else {
|
||||
reservations = reservationService.findAll();
|
||||
}
|
||||
|
||||
return Response.ok(reservations).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des réservations", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response findById(@PathParam("id") UUID id) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/{}", id);
|
||||
|
||||
ReservationMateriel reservation = reservationService.findByIdRequired(id);
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération de la réservation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/reference/{reference}")
|
||||
public Response findByReference(@PathParam("reference") String reference) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/reference/{}", reference);
|
||||
|
||||
return reservationService
|
||||
.findByReference(reference)
|
||||
.map(reservation -> Response.ok(reservation).build())
|
||||
.orElse(
|
||||
Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("Réservation non trouvée avec la référence: " + reference)
|
||||
.build());
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération de la réservation par référence: " + reference, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/materiel/{materielId}")
|
||||
public Response findByMateriel(@PathParam("materielId") UUID materielId) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/materiel/{}", materielId);
|
||||
|
||||
List<ReservationMateriel> reservations = reservationService.findByMateriel(materielId);
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des réservations pour matériel: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/chantier/{chantierId}")
|
||||
public Response findByChantier(@PathParam("chantierId") UUID chantierId) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/chantier/{}", chantierId);
|
||||
|
||||
List<ReservationMateriel> reservations = reservationService.findByChantier(chantierId);
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Erreur lors de la récupération des réservations pour chantier: " + chantierId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/statut/{statut}")
|
||||
public Response findByStatut(@PathParam("statut") String statutStr) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/statut/{}", statutStr);
|
||||
|
||||
StatutReservationMateriel statut = StatutReservationMateriel.fromString(statutStr);
|
||||
List<ReservationMateriel> reservations = reservationService.findByStatut(statut);
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des réservations par statut: " + statutStr, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/periode")
|
||||
public Response findByPeriode(
|
||||
@QueryParam("dateDebut") LocalDate dateDebut, @QueryParam("dateFin") LocalDate dateFin) {
|
||||
try {
|
||||
logger.debug(
|
||||
"GET /api/reservations-materiel/periode?dateDebut={}&dateFin={}", dateDebut, dateFin);
|
||||
|
||||
if (dateDebut == null || dateFin == null) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity("Les paramètres dateDebut et dateFin sont obligatoires")
|
||||
.build();
|
||||
}
|
||||
|
||||
List<ReservationMateriel> reservations = reservationService.findByPeriode(dateDebut, dateFin);
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des réservations par période", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS MÉTIER SPÉCIALISÉS ===
|
||||
|
||||
@GET
|
||||
@Path("/en-attente-validation")
|
||||
public Response findEnAttenteValidation() {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/en-attente-validation");
|
||||
|
||||
List<ReservationMateriel> reservations = reservationService.findEnAttenteValidation();
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des réservations en attente", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/en-retard")
|
||||
public Response findEnRetard() {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/en-retard");
|
||||
|
||||
List<ReservationMateriel> reservations = reservationService.findEnRetard();
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des réservations en retard", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/prioritaires")
|
||||
public Response findPrioritaires() {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/prioritaires");
|
||||
|
||||
List<ReservationMateriel> reservations = reservationService.findPrioritaires();
|
||||
return Response.ok(reservations).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la récupération des réservations prioritaires", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la récupération des réservations: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
public Response search(@QueryParam("terme") String terme) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/search?terme={}", terme);
|
||||
|
||||
List<ReservationMateriel> resultats = reservationService.search(terme);
|
||||
return Response.ok(resultats).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la recherche avec terme: " + terme, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la recherche: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE CRÉATION ET MODIFICATION ===
|
||||
|
||||
@POST
|
||||
@Path("/")
|
||||
public Response createReservation(@Valid CreateReservationRequest request) {
|
||||
try {
|
||||
logger.info("POST /api/reservations-materiel/ - création réservation");
|
||||
|
||||
ReservationMateriel reservation =
|
||||
reservationService.createReservation(
|
||||
request.materielId,
|
||||
request.chantierId,
|
||||
request.phaseId,
|
||||
request.dateDebut,
|
||||
request.dateFin,
|
||||
request.quantite,
|
||||
request.unite,
|
||||
request.demandeur,
|
||||
request.lieuLivraison);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(reservation).build();
|
||||
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la création de la réservation", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la création de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateReservation(
|
||||
@PathParam("id") UUID id, @Valid UpdateReservationRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/reservations-materiel/{}", id);
|
||||
|
||||
ReservationMateriel reservation =
|
||||
reservationService.updateReservation(
|
||||
id,
|
||||
request.dateDebut,
|
||||
request.dateFin,
|
||||
request.quantite,
|
||||
request.lieuLivraison,
|
||||
request.instructionsLivraison,
|
||||
request.priorite);
|
||||
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la mise à jour de la réservation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la mise à jour de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE GESTION DU WORKFLOW ===
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/valider")
|
||||
public Response validerReservation(
|
||||
@PathParam("id") UUID id, @Valid ValiderReservationRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/reservations-materiel/{}/valider", id);
|
||||
|
||||
ReservationMateriel reservation = reservationService.validerReservation(id, request.valideur);
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la validation de la réservation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la validation de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/refuser")
|
||||
public Response refuserReservation(
|
||||
@PathParam("id") UUID id, @Valid RefuserReservationRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/reservations-materiel/{}/refuser", id);
|
||||
|
||||
ReservationMateriel reservation =
|
||||
reservationService.refuserReservation(id, request.valideur, request.motifRefus);
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du refus de la réservation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du refus de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/livrer")
|
||||
public Response livrerMateriel(@PathParam("id") UUID id, @Valid LivrerMaterielRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/reservations-materiel/{}/livrer", id);
|
||||
|
||||
ReservationMateriel reservation =
|
||||
reservationService.livrerMateriel(
|
||||
id, request.dateLivraison, request.observations, request.etatMateriel);
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la livraison du matériel: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la livraison du matériel: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/retourner")
|
||||
public Response retournerMateriel(
|
||||
@PathParam("id") UUID id, @Valid RetournerMaterielRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/reservations-materiel/{}/retourner", id);
|
||||
|
||||
ReservationMateriel reservation =
|
||||
reservationService.retournerMateriel(
|
||||
id, request.dateRetour, request.observations, request.etatMateriel, request.prixReel);
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors du retour du matériel: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors du retour du matériel: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/annuler")
|
||||
public Response annulerReservation(
|
||||
@PathParam("id") UUID id, @Valid AnnulerReservationRequest request) {
|
||||
try {
|
||||
logger.info("PUT /api/reservations-materiel/{}/annuler", id);
|
||||
|
||||
ReservationMateriel reservation =
|
||||
reservationService.annulerReservation(id, request.motifAnnulation);
|
||||
return Response.ok(reservation).build();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'annulation de la réservation: " + id, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'annulation de la réservation: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE VÉRIFICATION ===
|
||||
|
||||
@GET
|
||||
@Path("/check-conflits")
|
||||
public Response checkConflits(
|
||||
@QueryParam("materielId") @NotNull UUID materielId,
|
||||
@QueryParam("dateDebut") @NotNull LocalDate dateDebut,
|
||||
@QueryParam("dateFin") @NotNull LocalDate dateFin,
|
||||
@QueryParam("excludeId") UUID excludeId) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/check-conflits");
|
||||
|
||||
List<ReservationMateriel> conflitsList =
|
||||
reservationService.checkConflits(materielId, dateDebut, dateFin, excludeId);
|
||||
|
||||
return Response.ok(
|
||||
new Object() {
|
||||
public boolean disponible = conflitsList.isEmpty();
|
||||
public int nombreConflits = conflitsList.size();
|
||||
public List<ReservationMateriel> conflits = conflitsList;
|
||||
})
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la vérification des conflits", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la vérification des conflits: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/disponibilite/{materielId}")
|
||||
public Response getDisponibiliteMateriel(
|
||||
@PathParam("materielId") UUID materielId,
|
||||
@QueryParam("dateDebut") @NotNull LocalDate dateDebut,
|
||||
@QueryParam("dateFin") @NotNull LocalDate dateFin) {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/disponibilite/{}", materielId);
|
||||
|
||||
Map<String, Object> disponibilite =
|
||||
reservationService.getDisponibiliteMateriel(materielId, dateDebut, dateFin);
|
||||
return Response.ok(disponibilite).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de l'analyse de disponibilité: " + materielId, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de l'analyse de disponibilité: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === ENDPOINTS STATISTIQUES ===
|
||||
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
public Response getStatistiques() {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/statistiques");
|
||||
|
||||
Object statistiques = reservationService.getStatistiques();
|
||||
return Response.ok(statistiques).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération des statistiques", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération des statistiques: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/tableau-bord")
|
||||
public Response getTableauBord() {
|
||||
try {
|
||||
logger.debug("GET /api/reservations-materiel/tableau-bord");
|
||||
|
||||
Object tableauBord = reservationService.getTableauBordReservations();
|
||||
return Response.ok(tableauBord).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Erreur lors de la génération du tableau de bord", e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("Erreur lors de la génération du tableau de bord: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class CreateReservationRequest {
|
||||
@NotNull public UUID materielId;
|
||||
|
||||
@NotNull public UUID chantierId;
|
||||
|
||||
public UUID phaseId;
|
||||
|
||||
@NotNull public LocalDate dateDebut;
|
||||
|
||||
@NotNull public LocalDate dateFin;
|
||||
|
||||
@NotNull public BigDecimal quantite;
|
||||
|
||||
public String unite;
|
||||
public String demandeur;
|
||||
public String lieuLivraison;
|
||||
}
|
||||
|
||||
public static class UpdateReservationRequest {
|
||||
public LocalDate dateDebut;
|
||||
public LocalDate dateFin;
|
||||
public BigDecimal quantite;
|
||||
public String lieuLivraison;
|
||||
public String instructionsLivraison;
|
||||
public PrioriteReservation priorite;
|
||||
}
|
||||
|
||||
public static class ValiderReservationRequest {
|
||||
@NotNull public String valideur;
|
||||
}
|
||||
|
||||
public static class RefuserReservationRequest {
|
||||
@NotNull public String valideur;
|
||||
|
||||
@NotNull public String motifRefus;
|
||||
}
|
||||
|
||||
public static class LivrerMaterielRequest {
|
||||
public LocalDate dateLivraison;
|
||||
public String observations;
|
||||
public String etatMateriel;
|
||||
}
|
||||
|
||||
public static class RetournerMaterielRequest {
|
||||
public LocalDate dateRetour;
|
||||
public String observations;
|
||||
public String etatMateriel;
|
||||
public BigDecimal prixReel;
|
||||
}
|
||||
|
||||
public static class AnnulerReservationRequest {
|
||||
@NotNull public String motifAnnulation;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user