407 lines
15 KiB
Java
407 lines
15 KiB
Java
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();
|
|
}
|
|
}
|
|
}
|