Initial commit
This commit is contained in:
@@ -0,0 +1,436 @@
|
||||
package dev.lions.btpxpress.adapter.http;
|
||||
|
||||
import dev.lions.btpxpress.application.service.DisponibiliteService;
|
||||
import dev.lions.btpxpress.domain.core.entity.Disponibilite;
|
||||
import dev.lions.btpxpress.domain.core.entity.TypeDisponibilite;
|
||||
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.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Content;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
|
||||
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Resource REST pour la gestion des disponibilités - Architecture 2025 RH: API complète de gestion
|
||||
* des disponibilités employés
|
||||
*/
|
||||
@Path("/api/v1/disponibilites")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Disponibilités", description = "Gestion des disponibilités et absences des employés")
|
||||
public class DisponibiliteResource {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DisponibiliteResource.class);
|
||||
|
||||
@Inject DisponibiliteService disponibiliteService;
|
||||
|
||||
// === ENDPOINTS DE CONSULTATION ===
|
||||
|
||||
@GET
|
||||
@Operation(
|
||||
summary = "Lister toutes les disponibilités",
|
||||
description =
|
||||
"Récupère la liste paginée de toutes les disponibilités avec filtres optionnels")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Liste des disponibilités récupérée avec succès",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
public Response getAllDisponibilites(
|
||||
@Parameter(description = "Numéro de page (0-indexé)", example = "0")
|
||||
@QueryParam("page")
|
||||
@DefaultValue("0")
|
||||
int page,
|
||||
@Parameter(description = "Taille de page", example = "20")
|
||||
@QueryParam("size")
|
||||
@DefaultValue("20")
|
||||
int size,
|
||||
@Parameter(description = "Filtrer par employé (UUID)") @QueryParam("employeId")
|
||||
UUID employeId,
|
||||
@Parameter(description = "Filtrer par type de disponibilité") @QueryParam("type") String type,
|
||||
@Parameter(description = "Filtrer par statut d'approbation") @QueryParam("approuvee")
|
||||
Boolean approuvee) {
|
||||
|
||||
logger.debug("Récupération des disponibilités - page: {}, taille: {}", page, size);
|
||||
|
||||
List<Disponibilite> disponibilites;
|
||||
|
||||
if (employeId != null) {
|
||||
disponibilites = disponibiliteService.findByEmployeId(employeId);
|
||||
} else if (type != null) {
|
||||
TypeDisponibilite typeEnum = TypeDisponibilite.valueOf(type.toUpperCase());
|
||||
disponibilites = disponibiliteService.findByType(typeEnum);
|
||||
} else if (approuvee != null && !approuvee) {
|
||||
disponibilites = disponibiliteService.findEnAttente();
|
||||
} else if (approuvee != null && approuvee) {
|
||||
disponibilites = disponibiliteService.findApprouvees();
|
||||
} else {
|
||||
disponibilites = disponibiliteService.findAll(page, size);
|
||||
}
|
||||
|
||||
return Response.ok(disponibilites).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Récupérer une disponibilité par ID",
|
||||
description = "Récupère les détails d'une disponibilité spécifique")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilité trouvée",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
@APIResponse(responseCode = "404", description = "Disponibilité non trouvée")
|
||||
public Response getDisponibiliteById(
|
||||
@Parameter(description = "Identifiant unique de la disponibilité", required = true)
|
||||
@PathParam("id")
|
||||
UUID id) {
|
||||
|
||||
logger.debug("Récupération de la disponibilité avec l'ID: {}", id);
|
||||
|
||||
return disponibiliteService
|
||||
.findById(id)
|
||||
.map(disponibilite -> Response.ok(disponibilite).build())
|
||||
.orElse(Response.status(Response.Status.NOT_FOUND).build());
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/actuelles")
|
||||
@Operation(
|
||||
summary = "Lister les disponibilités actuelles",
|
||||
description = "Récupère toutes les disponibilités actuellement actives")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilités actuelles récupérées",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
public Response getDisponibilitesActuelles() {
|
||||
logger.debug("Récupération des disponibilités actuelles");
|
||||
List<Disponibilite> disponibilites = disponibiliteService.findActuelles();
|
||||
return Response.ok(disponibilites).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/futures")
|
||||
@Operation(
|
||||
summary = "Lister les disponibilités futures",
|
||||
description = "Récupère toutes les disponibilités programmées pour le futur")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilités futures récupérées",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
public Response getDisponibilitesFutures() {
|
||||
logger.debug("Récupération des disponibilités futures");
|
||||
List<Disponibilite> disponibilites = disponibiliteService.findFutures();
|
||||
return Response.ok(disponibilites).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/en-attente")
|
||||
@Operation(
|
||||
summary = "Lister les demandes en attente",
|
||||
description = "Récupère toutes les demandes de disponibilité en attente d'approbation")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Demandes en attente récupérées",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
public Response getDemandesEnAttente() {
|
||||
logger.debug("Récupération des demandes en attente");
|
||||
List<Disponibilite> disponibilites = disponibiliteService.findEnAttente();
|
||||
return Response.ok(disponibilites).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/periode")
|
||||
@Operation(
|
||||
summary = "Lister les disponibilités pour une période",
|
||||
description = "Récupère toutes les disponibilités dans une période donnée")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilités de la période récupérées",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
public Response getDisponibilitesPourPeriode(
|
||||
@Parameter(description = "Date de début (yyyy-mm-dd)", required = true)
|
||||
@QueryParam("dateDebut")
|
||||
@NotNull
|
||||
LocalDate dateDebut,
|
||||
@Parameter(description = "Date de fin (yyyy-mm-dd)", required = true)
|
||||
@QueryParam("dateFin")
|
||||
@NotNull
|
||||
LocalDate dateFin) {
|
||||
|
||||
logger.debug("Récupération des disponibilités pour la période {} - {}", dateDebut, dateFin);
|
||||
List<Disponibilite> disponibilites = disponibiliteService.findPourPeriode(dateDebut, dateFin);
|
||||
return Response.ok(disponibilites).build();
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE GESTION CRUD ===
|
||||
|
||||
@POST
|
||||
@Operation(
|
||||
summary = "Créer une nouvelle disponibilité",
|
||||
description = "Créé une nouvelle demande de disponibilité pour un employé")
|
||||
@APIResponse(
|
||||
responseCode = "201",
|
||||
description = "Disponibilité créée avec succès",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
@APIResponse(responseCode = "400", description = "Données invalides ou conflit détecté")
|
||||
public Response createDisponibilite(@Valid @NotNull CreateDisponibiliteRequest request) {
|
||||
|
||||
logger.info("Création d'une nouvelle disponibilité pour l'employé: {}", request.employeId);
|
||||
|
||||
Disponibilite disponibilite =
|
||||
disponibiliteService.createDisponibilite(
|
||||
request.employeId, request.dateDebut, request.dateFin, request.type, request.motif);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(disponibilite).build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Mettre à jour une disponibilité",
|
||||
description = "Met à jour les informations d'une disponibilité existante")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilité mise à jour avec succès",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
@APIResponse(responseCode = "404", description = "Disponibilité non trouvée")
|
||||
@APIResponse(responseCode = "400", description = "Données invalides")
|
||||
public Response updateDisponibilite(
|
||||
@Parameter(description = "Identifiant de la disponibilité", required = true) @PathParam("id")
|
||||
UUID id,
|
||||
@Valid @NotNull UpdateDisponibiliteRequest request) {
|
||||
|
||||
logger.info("Mise à jour de la disponibilité: {}", id);
|
||||
|
||||
Disponibilite disponibilite =
|
||||
disponibiliteService.updateDisponibilite(
|
||||
id, request.dateDebut, request.dateFin, request.motif);
|
||||
|
||||
return Response.ok(disponibilite).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{id}/approuver")
|
||||
@Operation(
|
||||
summary = "Approuver une demande de disponibilité",
|
||||
description = "Approuve une demande de disponibilité en attente")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilité approuvée avec succès",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
@APIResponse(responseCode = "404", description = "Disponibilité non trouvée")
|
||||
@APIResponse(responseCode = "400", description = "Disponibilité déjà approuvée")
|
||||
public Response approuverDisponibilite(
|
||||
@Parameter(description = "Identifiant de la disponibilité", required = true) @PathParam("id")
|
||||
UUID id) {
|
||||
|
||||
logger.info("Approbation de la disponibilité: {}", id);
|
||||
|
||||
Disponibilite disponibilite = disponibiliteService.approuverDisponibilite(id);
|
||||
return Response.ok(disponibilite).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{id}/rejeter")
|
||||
@Operation(
|
||||
summary = "Rejeter une demande de disponibilité",
|
||||
description = "Rejette une demande de disponibilité avec une raison")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Disponibilité rejetée avec succès",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
@APIResponse(responseCode = "404", description = "Disponibilité non trouvée")
|
||||
@APIResponse(responseCode = "400", description = "Impossible de rejeter")
|
||||
public Response rejeterDisponibilite(
|
||||
@Parameter(description = "Identifiant de la disponibilité", required = true) @PathParam("id")
|
||||
UUID id,
|
||||
@Valid @NotNull RejetDisponibiliteRequest request) {
|
||||
|
||||
logger.info("Rejet de la disponibilité: {}", id);
|
||||
|
||||
Disponibilite disponibilite =
|
||||
disponibiliteService.rejeterDisponibilite(id, request.raisonRejet);
|
||||
return Response.ok(disponibilite).build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
@Operation(
|
||||
summary = "Supprimer une disponibilité",
|
||||
description = "Supprime définitivement une disponibilité")
|
||||
@APIResponse(responseCode = "204", description = "Disponibilité supprimée avec succès")
|
||||
@APIResponse(responseCode = "404", description = "Disponibilité non trouvée")
|
||||
@APIResponse(responseCode = "400", description = "Impossible de supprimer")
|
||||
public Response deleteDisponibilite(
|
||||
@Parameter(description = "Identifiant de la disponibilité", required = true) @PathParam("id")
|
||||
UUID id) {
|
||||
|
||||
logger.info("Suppression de la disponibilité: {}", id);
|
||||
|
||||
disponibiliteService.deleteDisponibilite(id);
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
// === ENDPOINTS DE VALIDATION ===
|
||||
|
||||
@GET
|
||||
@Path("/employe/{employeId}/disponible")
|
||||
@Operation(
|
||||
summary = "Vérifier la disponibilité d'un employé",
|
||||
description = "Vérifie si un employé est disponible pour une période donnée")
|
||||
@APIResponse(responseCode = "200", description = "Statut de disponibilité retourné")
|
||||
public Response checkEmployeDisponibilite(
|
||||
@Parameter(description = "Identifiant de l'employé", required = true) @PathParam("employeId")
|
||||
UUID employeId,
|
||||
@Parameter(description = "Date/heure de début", required = true)
|
||||
@QueryParam("dateDebut")
|
||||
@NotNull
|
||||
LocalDateTime dateDebut,
|
||||
@Parameter(description = "Date/heure de fin", required = true) @QueryParam("dateFin") @NotNull
|
||||
LocalDateTime dateFin) {
|
||||
|
||||
logger.debug("Vérification de disponibilité pour l'employé {}", employeId);
|
||||
|
||||
boolean estDisponible = disponibiliteService.isEmployeDisponible(employeId, dateDebut, dateFin);
|
||||
|
||||
return Response.ok(
|
||||
new Object() {
|
||||
public final boolean disponible = estDisponible;
|
||||
public final String message =
|
||||
estDisponible
|
||||
? "Employé disponible pour cette période"
|
||||
: "Employé indisponible pour cette période";
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/employe/{employeId}/conflits")
|
||||
@Operation(
|
||||
summary = "Rechercher les conflits de disponibilité",
|
||||
description = "Trouve les conflits de disponibilité pour un employé et une période")
|
||||
@APIResponse(
|
||||
responseCode = "200",
|
||||
description = "Conflits trouvés",
|
||||
content = @Content(schema = @Schema(implementation = Disponibilite.class)))
|
||||
public Response getConflits(
|
||||
@Parameter(description = "Identifiant de l'employé", required = true) @PathParam("employeId")
|
||||
UUID employeId,
|
||||
@Parameter(description = "Date/heure de début", required = true)
|
||||
@QueryParam("dateDebut")
|
||||
@NotNull
|
||||
LocalDateTime dateDebut,
|
||||
@Parameter(description = "Date/heure de fin", required = true) @QueryParam("dateFin") @NotNull
|
||||
LocalDateTime dateFin,
|
||||
@Parameter(description = "ID à exclure de la recherche") @QueryParam("excludeId")
|
||||
UUID excludeId) {
|
||||
|
||||
logger.debug("Recherche de conflits pour l'employé {}", employeId);
|
||||
|
||||
List<Disponibilite> conflits =
|
||||
disponibiliteService.getConflicts(employeId, dateDebut, dateFin, excludeId);
|
||||
|
||||
return Response.ok(conflits).build();
|
||||
}
|
||||
|
||||
// === ENDPOINTS STATISTIQUES ===
|
||||
|
||||
@GET
|
||||
@Path("/statistiques")
|
||||
@Operation(
|
||||
summary = "Obtenir les statistiques des disponibilités",
|
||||
description = "Récupère les statistiques globales des disponibilités")
|
||||
@APIResponse(responseCode = "200", description = "Statistiques récupérées avec succès")
|
||||
public Response getStatistiques() {
|
||||
logger.debug("Récupération des statistiques des disponibilités");
|
||||
Object statistiques = disponibiliteService.getStatistics();
|
||||
return Response.ok(statistiques).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/statistiques/par-type")
|
||||
@Operation(
|
||||
summary = "Statistiques par type de disponibilité",
|
||||
description = "Récupère les statistiques détaillées par type")
|
||||
@APIResponse(responseCode = "200", description = "Statistiques par type récupérées")
|
||||
public Response getStatistiquesParType() {
|
||||
logger.debug("Récupération des statistiques par type");
|
||||
List<Object[]> stats = disponibiliteService.getStatsByType();
|
||||
return Response.ok(stats).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/statistiques/par-employe")
|
||||
@Operation(
|
||||
summary = "Statistiques par employé",
|
||||
description = "Récupère les statistiques de disponibilité par employé")
|
||||
@APIResponse(responseCode = "200", description = "Statistiques par employé récupérées")
|
||||
public Response getStatistiquesParEmploye() {
|
||||
logger.debug("Récupération des statistiques par employé");
|
||||
List<Object[]> stats = disponibiliteService.getStatsByEmployee();
|
||||
return Response.ok(stats).build();
|
||||
}
|
||||
|
||||
// === CLASSES DE REQUÊTE ===
|
||||
|
||||
public static class CreateDisponibiliteRequest {
|
||||
@Schema(description = "Identifiant unique de l'employé", required = true)
|
||||
public UUID employeId;
|
||||
|
||||
@Schema(
|
||||
description = "Date et heure de début de la disponibilité",
|
||||
required = true,
|
||||
example = "2024-03-15T08:00:00")
|
||||
public LocalDateTime dateDebut;
|
||||
|
||||
@Schema(
|
||||
description = "Date et heure de fin de la disponibilité",
|
||||
required = true,
|
||||
example = "2024-03-20T18:00:00")
|
||||
public LocalDateTime dateFin;
|
||||
|
||||
@Schema(
|
||||
description = "Type de disponibilité",
|
||||
required = true,
|
||||
enumeration = {
|
||||
"CONGE_PAYE",
|
||||
"CONGE_SANS_SOLDE",
|
||||
"ARRET_MALADIE",
|
||||
"FORMATION",
|
||||
"ABSENCE",
|
||||
"HORAIRE_REDUIT"
|
||||
})
|
||||
public String type;
|
||||
|
||||
@Schema(description = "Motif ou raison de la disponibilité", example = "Congés annuels")
|
||||
public String motif;
|
||||
}
|
||||
|
||||
public static class UpdateDisponibiliteRequest {
|
||||
@Schema(description = "Nouvelle date de début")
|
||||
public LocalDateTime dateDebut;
|
||||
|
||||
@Schema(description = "Nouvelle date de fin")
|
||||
public LocalDateTime dateFin;
|
||||
|
||||
@Schema(description = "Nouveau motif")
|
||||
public String motif;
|
||||
}
|
||||
|
||||
public static class RejetDisponibiliteRequest {
|
||||
@Schema(description = "Raison du rejet de la demande", required = true)
|
||||
public String raisonRejet;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user