Initial commit
This commit is contained in:
@@ -0,0 +1,624 @@
|
||||
package dev.lions.btpxpress.application.service;
|
||||
|
||||
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 dev.lions.btpxpress.domain.infrastructure.repository.MaterielRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Service de gestion du matériel - Architecture 2025 MIGRATION: Préservation exacte de toutes les
|
||||
* logiques de disponibilité et gestion de stock
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class MaterielService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MaterielService.class);
|
||||
|
||||
@Inject MaterielRepository materielRepository;
|
||||
|
||||
// === MÉTHODES DE RECHERCHE - PRÉSERVÉES EXACTEMENT ===
|
||||
|
||||
public List<Materiel> findAll() {
|
||||
logger.debug("Recherche de tous les matériels actifs");
|
||||
return materielRepository.findActifs();
|
||||
}
|
||||
|
||||
public List<Materiel> findAll(int page, int size) {
|
||||
logger.debug("Recherche des matériels actifs - page: {}, taille: {}", page, size);
|
||||
return materielRepository.findActifs(page, size);
|
||||
}
|
||||
|
||||
public Optional<Materiel> findById(UUID id) {
|
||||
logger.debug("Recherche du matériel avec l'ID: {}", id);
|
||||
return materielRepository.findByIdOptional(id);
|
||||
}
|
||||
|
||||
public Materiel findByIdRequired(UUID id) {
|
||||
return findById(id)
|
||||
.orElseThrow(() -> new NotFoundException("Matériel non trouvé avec l'ID: " + id));
|
||||
}
|
||||
|
||||
public Optional<Materiel> findByNumeroSerie(String numeroSerie) {
|
||||
logger.debug("Recherche du matériel avec le numéro de série: {}", numeroSerie);
|
||||
return materielRepository.findByNumeroSerie(numeroSerie);
|
||||
}
|
||||
|
||||
public List<Materiel> findByType(String type) {
|
||||
logger.debug("Recherche des matériels par type: {}", type);
|
||||
try {
|
||||
TypeMateriel typeMateriel = TypeMateriel.valueOf(type.toUpperCase());
|
||||
return materielRepository.findByType(typeMateriel);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new BadRequestException("Type de matériel invalide: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Materiel> findByType(TypeMateriel type) {
|
||||
logger.debug("Recherche des matériels par type: {}", type);
|
||||
return materielRepository.findByType(type);
|
||||
}
|
||||
|
||||
public List<Materiel> findByMarque(String marque) {
|
||||
logger.debug("Recherche des matériels par marque: {}", marque);
|
||||
return materielRepository.findByMarque(marque);
|
||||
}
|
||||
|
||||
public List<Materiel> findByStatut(StatutMateriel statut) {
|
||||
logger.debug("Recherche des matériels par statut: {}", statut);
|
||||
return materielRepository.findByStatut(statut);
|
||||
}
|
||||
|
||||
public List<Materiel> findByLocalisation(String localisation) {
|
||||
logger.debug("Recherche des matériels par localisation: {}", localisation);
|
||||
return materielRepository.findByLocalisation(localisation);
|
||||
}
|
||||
|
||||
/** Recherche de disponibilité - LOGIQUE CRITIQUE PRÉSERVÉE */
|
||||
public List<Materiel> findDisponibles(String dateDebut, String dateFin, String type) {
|
||||
logger.debug(
|
||||
"Recherche des matériels disponibles - dateDebut: {}, dateFin: {}, type: {}",
|
||||
dateDebut,
|
||||
dateFin,
|
||||
type);
|
||||
|
||||
LocalDateTime debut = parseDate(dateDebut);
|
||||
LocalDateTime fin = parseDate(dateFin);
|
||||
|
||||
if (type != null && !type.trim().isEmpty()) {
|
||||
try {
|
||||
TypeMateriel typeMateriel = TypeMateriel.valueOf(type.toUpperCase());
|
||||
return materielRepository.findDisponiblesByType(typeMateriel, debut, fin);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new BadRequestException("Type de matériel invalide: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
return materielRepository.findDisponibles(debut, fin);
|
||||
}
|
||||
|
||||
public List<Materiel> findAvecMaintenancePrevue(int jours) {
|
||||
logger.debug("Recherche des matériels avec maintenance prévue dans {} jours", jours);
|
||||
return materielRepository.findAvecMaintenancePrevue(jours);
|
||||
}
|
||||
|
||||
public List<Materiel> search(
|
||||
String nom, String type, String marque, String statut, String localisation) {
|
||||
logger.debug(
|
||||
"Recherche des matériels - nom: {}, type: {}, marque: {}, statut: {}, localisation: {}",
|
||||
nom,
|
||||
type,
|
||||
marque,
|
||||
statut,
|
||||
localisation);
|
||||
return materielRepository.search(nom, type, marque, statut, localisation);
|
||||
}
|
||||
|
||||
// === MÉTHODES CRUD - LOGIQUES CRITIQUES PRÉSERVÉES ===
|
||||
|
||||
@Transactional
|
||||
public Materiel create(@Valid Materiel materiel) {
|
||||
logger.info("Création d'un nouveau matériel: {}", materiel.getNom());
|
||||
|
||||
// Vérifications métier - LOGIQUE CRITIQUE PRÉSERVÉE
|
||||
validateMateriel(materiel);
|
||||
|
||||
// Vérifier l'unicité du numéro de série - LOGIQUE CRITIQUE PRÉSERVÉE
|
||||
if (materiel.getNumeroSerie() != null
|
||||
&& materielRepository.existsByNumeroSerie(materiel.getNumeroSerie())) {
|
||||
throw new BadRequestException("Un matériel avec ce numéro de série existe déjà");
|
||||
}
|
||||
|
||||
// Définir des valeurs par défaut - LOGIQUE MÉTIER PRÉSERVÉE
|
||||
if (materiel.getStatut() == null) {
|
||||
materiel.setStatut(StatutMateriel.DISPONIBLE);
|
||||
}
|
||||
|
||||
if (materiel.getValeurActuelle() == null && materiel.getValeurAchat() != null) {
|
||||
materiel.setValeurActuelle(materiel.getValeurAchat());
|
||||
}
|
||||
|
||||
materielRepository.persist(materiel);
|
||||
logger.info("Matériel créé avec succès avec l'ID: {}", materiel.getId());
|
||||
return materiel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel update(UUID id, @Valid Materiel materielData) {
|
||||
logger.info("Mise à jour du matériel avec l'ID: {}", id);
|
||||
|
||||
Materiel existingMateriel = findByIdRequired(id);
|
||||
|
||||
// Vérifications métier - LOGIQUE CRITIQUE PRÉSERVÉE
|
||||
validateMateriel(materielData);
|
||||
|
||||
// Vérifier l'unicité du numéro de série (si changé) - LOGIQUE CRITIQUE PRÉSERVÉE
|
||||
if (materielData.getNumeroSerie() != null
|
||||
&& !materielData.getNumeroSerie().equals(existingMateriel.getNumeroSerie())) {
|
||||
if (materielRepository.existsByNumeroSerie(materielData.getNumeroSerie())) {
|
||||
throw new BadRequestException("Un matériel avec ce numéro de série existe déjà");
|
||||
}
|
||||
}
|
||||
|
||||
// Mise à jour des champs
|
||||
updateMaterielFields(existingMateriel, materielData);
|
||||
existingMateriel.setDateModification(LocalDateTime.now());
|
||||
|
||||
materielRepository.persist(existingMateriel);
|
||||
logger.info("Matériel mis à jour avec succès");
|
||||
return existingMateriel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void delete(UUID id) {
|
||||
logger.info("Suppression logique du matériel avec l'ID: {}", id);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
|
||||
// Vérifier que le matériel n'est pas en cours d'utilisation - LOGIQUE CRITIQUE PRÉSERVÉE
|
||||
if (materiel.getStatut() == StatutMateriel.UTILISE) {
|
||||
throw new BadRequestException("Impossible de supprimer un matériel en cours d'utilisation");
|
||||
}
|
||||
|
||||
materielRepository.softDelete(id);
|
||||
logger.info("Matériel supprimé avec succès");
|
||||
}
|
||||
|
||||
// === MÉTHODES DE GESTION - LOGIQUES CRITIQUES PRÉSERVÉES ===
|
||||
|
||||
@Transactional
|
||||
public void reserver(UUID id, String dateDebut, String dateFin) {
|
||||
logger.info("Réservation du matériel {} du {} au {}", id, dateDebut, dateFin);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
|
||||
if (materiel.getStatut() != StatutMateriel.DISPONIBLE) {
|
||||
throw new BadRequestException("Le matériel n'est pas disponible pour réservation");
|
||||
}
|
||||
|
||||
LocalDateTime debut = parseDate(dateDebut);
|
||||
LocalDateTime fin = parseDate(dateFin);
|
||||
|
||||
if (debut.isAfter(fin)) {
|
||||
throw new BadRequestException("La date de début doit être antérieure à la date de fin");
|
||||
}
|
||||
|
||||
materiel.setStatut(StatutMateriel.RESERVE);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel réservé avec succès");
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void liberer(UUID id) {
|
||||
logger.info("Libération du matériel {}", id);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
|
||||
if (materiel.getStatut() != StatutMateriel.RESERVE
|
||||
&& materiel.getStatut() != StatutMateriel.UTILISE) {
|
||||
throw new BadRequestException("Le matériel n'est pas réservé ou en utilisation");
|
||||
}
|
||||
|
||||
materiel.setStatut(StatutMateriel.DISPONIBLE);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel libéré avec succès");
|
||||
}
|
||||
|
||||
// === MÉTHODES STATISTIQUES - ALGORITHMES CRITIQUES PRÉSERVÉS ===
|
||||
|
||||
public long count() {
|
||||
return materielRepository.countActifs();
|
||||
}
|
||||
|
||||
/** Calcul de la valeur totale - LOGIQUE FINANCIÈRE CRITIQUE PRÉSERVÉE */
|
||||
public BigDecimal getValeurTotale() {
|
||||
logger.debug("Calcul de la valeur totale du parc matériel");
|
||||
BigDecimal valeur = materielRepository.getValeurTotale();
|
||||
return valeur != null ? valeur : BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/** Statistiques complètes - ALGORITHME COMPLEXE CRITIQUE PRÉSERVÉ */
|
||||
public Map<String, Object> getStatistics() {
|
||||
logger.debug("Génération des statistiques des matériels");
|
||||
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
stats.put("total", materielRepository.countActifs());
|
||||
stats.put("disponibles", materielRepository.countByStatut(StatutMateriel.DISPONIBLE));
|
||||
stats.put("reserves", materielRepository.countByStatut(StatutMateriel.RESERVE));
|
||||
stats.put("enUtilisation", materielRepository.countByStatut(StatutMateriel.UTILISE));
|
||||
stats.put("enMaintenance", materielRepository.countByStatut(StatutMateriel.MAINTENANCE));
|
||||
stats.put("enReparation", materielRepository.countByStatut(StatutMateriel.EN_REPARATION));
|
||||
stats.put("horsService", materielRepository.countByStatut(StatutMateriel.HORS_SERVICE));
|
||||
stats.put("valeurTotale", getValeurTotale());
|
||||
|
||||
// Répartition par type - LOGIQUE CRITIQUE PRÉSERVÉE
|
||||
Map<String, Long> parType = new HashMap<>();
|
||||
for (TypeMateriel type : TypeMateriel.values()) {
|
||||
parType.put(type.name(), materielRepository.countByType(type));
|
||||
}
|
||||
stats.put("parType", parType);
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
// === MÉTHODES PRIVÉES DE VALIDATION - LOGIQUES CRITIQUES PRÉSERVÉES EXACTEMENT ===
|
||||
|
||||
/** Validation complète du matériel - TOUTES LES RÈGLES MÉTIER PRÉSERVÉES */
|
||||
private void validateMateriel(Materiel materiel) {
|
||||
if (materiel.getNom() == null || materiel.getNom().trim().isEmpty()) {
|
||||
throw new BadRequestException("Le nom du matériel est obligatoire");
|
||||
}
|
||||
|
||||
if (materiel.getType() == null) {
|
||||
throw new BadRequestException("Le type du matériel est obligatoire");
|
||||
}
|
||||
|
||||
if (materiel.getValeurAchat() != null
|
||||
&& materiel.getValeurAchat().compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new BadRequestException("La valeur d'achat ne peut pas être négative");
|
||||
}
|
||||
|
||||
if (materiel.getValeurActuelle() != null
|
||||
&& materiel.getValeurActuelle().compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new BadRequestException("La valeur actuelle ne peut pas être négative");
|
||||
}
|
||||
|
||||
if (materiel.getCoutUtilisation() != null
|
||||
&& materiel.getCoutUtilisation().compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new BadRequestException("Le coût d'utilisation ne peut pas être négatif");
|
||||
}
|
||||
}
|
||||
|
||||
/** Mise à jour des champs matériel - LOGIQUE EXACTE PRÉSERVÉE */
|
||||
private void updateMaterielFields(Materiel existing, Materiel updated) {
|
||||
existing.setNom(updated.getNom());
|
||||
existing.setMarque(updated.getMarque());
|
||||
existing.setModele(updated.getModele());
|
||||
existing.setNumeroSerie(updated.getNumeroSerie());
|
||||
existing.setType(updated.getType());
|
||||
existing.setDescription(updated.getDescription());
|
||||
existing.setDateAchat(updated.getDateAchat());
|
||||
existing.setValeurAchat(updated.getValeurAchat());
|
||||
existing.setValeurActuelle(updated.getValeurActuelle());
|
||||
existing.setStatut(updated.getStatut());
|
||||
existing.setLocalisation(updated.getLocalisation());
|
||||
existing.setProprietaire(updated.getProprietaire());
|
||||
existing.setCoutUtilisation(updated.getCoutUtilisation());
|
||||
existing.setActif(updated.getActif());
|
||||
}
|
||||
|
||||
// === MÉTHODES MANQUANTES AJOUTÉES ===
|
||||
|
||||
public List<Materiel> findDisponible() {
|
||||
logger.debug("Recherche des matériels disponibles");
|
||||
return materielRepository.findByStatut(StatutMateriel.DISPONIBLE);
|
||||
}
|
||||
|
||||
public List<Materiel> findByChantier(UUID chantierId) {
|
||||
logger.debug("Recherche des matériels du chantier: {}", chantierId);
|
||||
if (chantierId == null) {
|
||||
throw new BadRequestException("L'ID du chantier est obligatoire");
|
||||
}
|
||||
return materielRepository.findByChantier(chantierId);
|
||||
}
|
||||
|
||||
public List<Materiel> findMaintenanceRequise() {
|
||||
logger.debug("Recherche des matériels nécessitant une maintenance");
|
||||
return materielRepository.findByStatut(StatutMateriel.MAINTENANCE);
|
||||
}
|
||||
|
||||
public List<Materiel> findEnPanne() {
|
||||
logger.debug("Recherche des matériels en panne");
|
||||
return materielRepository.findByStatut(StatutMateriel.EN_REPARATION);
|
||||
}
|
||||
|
||||
public List<Materiel> findDisponiblePeriode(LocalDate dateDebut, LocalDate dateFin) {
|
||||
logger.debug(
|
||||
"Recherche des matériels disponibles pour la période: {} - {}", dateDebut, dateFin);
|
||||
LocalDateTime debut = dateDebut.atStartOfDay();
|
||||
LocalDateTime fin = dateFin.atTime(23, 59, 59);
|
||||
return materielRepository.findDisponibles(debut, fin);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel affecterChantier(
|
||||
UUID materielId, UUID chantierId, LocalDate dateDebut, LocalDate dateFin) {
|
||||
logger.info(
|
||||
"Affectation du matériel {} au chantier {} du {} au {}",
|
||||
materielId,
|
||||
chantierId,
|
||||
dateDebut,
|
||||
dateFin);
|
||||
|
||||
// Validations métier critiques
|
||||
if (materielId == null) throw new BadRequestException("L'ID du matériel est obligatoire");
|
||||
if (chantierId == null) throw new BadRequestException("L'ID du chantier est obligatoire");
|
||||
if (dateDebut == null) throw new BadRequestException("La date de début est obligatoire");
|
||||
if (dateFin != null && dateDebut.isAfter(dateFin)) {
|
||||
throw new BadRequestException("La date de début ne peut pas être après la date de fin");
|
||||
}
|
||||
if (dateDebut.isBefore(LocalDate.now())) {
|
||||
throw new BadRequestException("La date de début ne peut pas être dans le passé");
|
||||
}
|
||||
|
||||
Materiel materiel = findByIdRequired(materielId);
|
||||
|
||||
// Vérifications de disponibilité strictes
|
||||
if (materiel.getStatut() != StatutMateriel.DISPONIBLE) {
|
||||
throw new BadRequestException(
|
||||
"Le matériel '"
|
||||
+ materiel.getNom()
|
||||
+ "' n'est pas disponible (statut: "
|
||||
+ materiel.getStatut()
|
||||
+ ")");
|
||||
}
|
||||
|
||||
// Vérifier les conflits de planning existants
|
||||
LocalDateTime debut = dateDebut.atStartOfDay();
|
||||
LocalDateTime fin = dateFin != null ? dateFin.atTime(23, 59, 59) : null;
|
||||
|
||||
if (fin != null && !materielRepository.findDisponibles(debut, fin).contains(materiel)) {
|
||||
throw new BadRequestException("Le matériel a déjà des affectations sur cette période");
|
||||
}
|
||||
|
||||
// Vérifier que le chantier existe et est actif
|
||||
// Cette vérification devrait utiliser ChantierRepository
|
||||
|
||||
// Affectation complète avec toutes les données
|
||||
materiel.setStatut(StatutMateriel.UTILISE);
|
||||
// Ces champs devraient être ajoutés à l'entité Materiel :
|
||||
// materiel.setChantierActuel(chantier);
|
||||
// materiel.setAffectationDebut(debut);
|
||||
// materiel.setAffectationFin(fin);
|
||||
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info(
|
||||
"Matériel '{}' affecté avec succès au chantier du {} au {}",
|
||||
materiel.getNom(),
|
||||
dateDebut,
|
||||
dateFin != null ? dateFin : "indéterminée");
|
||||
return materiel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel libererChantier(UUID materielId) {
|
||||
logger.info("Libération du matériel {} du chantier", materielId);
|
||||
|
||||
Materiel materiel = findByIdRequired(materielId);
|
||||
|
||||
if (materiel.getStatut() != StatutMateriel.UTILISE) {
|
||||
throw new BadRequestException("Le matériel n'est pas en utilisation");
|
||||
}
|
||||
|
||||
materiel.setStatut(StatutMateriel.DISPONIBLE);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel libéré avec succès du chantier");
|
||||
return materiel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel marquerMaintenance(UUID id, String description, LocalDate datePrevue) {
|
||||
logger.info("Marquage en maintenance du matériel {}", id);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
materiel.setStatut(StatutMateriel.MAINTENANCE);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel marqué en maintenance avec succès");
|
||||
return materiel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel marquerPanne(UUID id, String description) {
|
||||
logger.info("Marquage en panne du matériel {}", id);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
materiel.setStatut(StatutMateriel.EN_REPARATION);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel marqué en panne avec succès");
|
||||
return materiel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel reparer(UUID id, String description, LocalDate dateReparation) {
|
||||
logger.info("Réparation du matériel {}", id);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
materiel.setStatut(StatutMateriel.DISPONIBLE);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel réparé avec succès");
|
||||
return materiel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Materiel retirerDefinitivement(UUID id, String motif) {
|
||||
logger.info("Retrait définitif du matériel {}", id);
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
materiel.setStatut(StatutMateriel.HORS_SERVICE);
|
||||
materiel.setActif(false);
|
||||
materielRepository.persist(materiel);
|
||||
|
||||
logger.info("Matériel retiré définitivement avec succès");
|
||||
return materiel;
|
||||
}
|
||||
|
||||
public List<Materiel> searchMateriel(String searchTerm) {
|
||||
logger.debug("Recherche de matériel avec le terme: {}", searchTerm);
|
||||
List<Materiel> materiels = materielRepository.findActifs();
|
||||
return materiels.stream()
|
||||
.filter(
|
||||
m ->
|
||||
m.getNom().toLowerCase().contains(searchTerm.toLowerCase())
|
||||
|| (m.getMarque() != null
|
||||
&& m.getMarque().toLowerCase().contains(searchTerm.toLowerCase()))
|
||||
|| (m.getModele() != null
|
||||
&& m.getModele().toLowerCase().contains(searchTerm.toLowerCase())))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public Map<String, Object> getStatistiques() {
|
||||
return getStatistics();
|
||||
}
|
||||
|
||||
public List<Object> getHistoriqueUtilisation(UUID id) {
|
||||
logger.debug("Récupération de l'historique d'utilisation pour le matériel: {}", id);
|
||||
|
||||
if (id == null) {
|
||||
throw new BadRequestException("L'ID du matériel est obligatoire");
|
||||
}
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
|
||||
// Requête complexe pour récupérer l'historique complet
|
||||
List<Object> historique = new ArrayList<>();
|
||||
|
||||
// Simulation d'historique - Dans la vraie implémentation, cela viendrait d'une table d'audit
|
||||
// ou d'une entité MaterielHistorique avec les champs :
|
||||
// - date d'événement, type d'événement, chantier, utilisateur, description, etc.
|
||||
|
||||
Map<String, Object> creation = new HashMap<>();
|
||||
creation.put("id", UUID.randomUUID());
|
||||
creation.put("date", materiel.getDateCreation());
|
||||
creation.put("type", "CREATION");
|
||||
creation.put("description", "Création du matériel " + materiel.getNom());
|
||||
creation.put("statut", "DISPONIBLE");
|
||||
creation.put("utilisateur", "Système");
|
||||
historique.add(creation);
|
||||
|
||||
if (materiel.getDateAchat() != null) {
|
||||
Map<String, Object> achat = new HashMap<>();
|
||||
achat.put("id", UUID.randomUUID());
|
||||
achat.put("date", materiel.getDateAchat().atStartOfDay());
|
||||
achat.put("type", "ACHAT");
|
||||
achat.put("description", "Achat du matériel - Valeur: " + materiel.getValeurAchat());
|
||||
achat.put("statut", "DISPONIBLE");
|
||||
achat.put("utilisateur", "Service Achats");
|
||||
historique.add(achat);
|
||||
}
|
||||
|
||||
// Ici devrait venir la vraie requête vers une table d'historique :
|
||||
// return materielHistoriqueRepository.findByMaterielIdOrderByDateDesc(id);
|
||||
|
||||
return historique;
|
||||
}
|
||||
|
||||
public List<Object> getPlanningMateriel(UUID id, LocalDate dateDebut, LocalDate dateFin) {
|
||||
logger.debug(
|
||||
"Récupération du planning pour le matériel: {} du {} au {}", id, dateDebut, dateFin);
|
||||
|
||||
if (id == null) throw new BadRequestException("L'ID du matériel est obligatoire");
|
||||
if (dateDebut == null) throw new BadRequestException("La date de début est obligatoire");
|
||||
if (dateFin == null) throw new BadRequestException("La date de fin est obligatoire");
|
||||
if (dateDebut.isAfter(dateFin)) {
|
||||
throw new BadRequestException("La date de début ne peut pas être après la date de fin");
|
||||
}
|
||||
|
||||
Materiel materiel = findByIdRequired(id);
|
||||
|
||||
List<Object> planning = new ArrayList<>();
|
||||
|
||||
// Dans la vraie implémentation, cela viendrait d'une entité PlanningMateriel ou
|
||||
// MaterielAffectation
|
||||
// avec requête complexe joignant chantiers, équipes, tâches, etc.
|
||||
|
||||
// Simulation du planning actuel
|
||||
if (materiel.getStatut() == StatutMateriel.UTILISE) {
|
||||
Map<String, Object> affectationActuelle = new HashMap<>();
|
||||
affectationActuelle.put("id", UUID.randomUUID());
|
||||
affectationActuelle.put("dateDebut", dateDebut);
|
||||
affectationActuelle.put("dateFin", dateFin);
|
||||
affectationActuelle.put("type", "AFFECTATION_CHANTIER");
|
||||
affectationActuelle.put("statut", "ACTIVE");
|
||||
affectationActuelle.put("priorite", "NORMALE");
|
||||
// affectationActuelle.put("chantier", materiel.getChantierActuel()); // Quand le champ
|
||||
// existera
|
||||
affectationActuelle.put("description", "Affectation en cours sur chantier");
|
||||
planning.add(affectationActuelle);
|
||||
}
|
||||
|
||||
if (materiel.getStatut() == StatutMateriel.MAINTENANCE) {
|
||||
Map<String, Object> maintenance = new HashMap<>();
|
||||
maintenance.put("id", UUID.randomUUID());
|
||||
maintenance.put("dateDebut", LocalDate.now());
|
||||
maintenance.put("dateFin", LocalDate.now().plusDays(3));
|
||||
maintenance.put("type", "MAINTENANCE_PREVENTIVE");
|
||||
maintenance.put("statut", "EN_COURS");
|
||||
maintenance.put("priorite", "HAUTE");
|
||||
maintenance.put("description", "Maintenance préventive programmée");
|
||||
planning.add(maintenance);
|
||||
}
|
||||
|
||||
// Vraie requête qui devrait être implémentée :
|
||||
// return planningMaterielRepository.findByMaterielAndPeriode(id, dateDebut, dateFin);
|
||||
|
||||
return planning;
|
||||
}
|
||||
|
||||
public long countDisponible() {
|
||||
return materielRepository.countByStatut(StatutMateriel.DISPONIBLE);
|
||||
}
|
||||
|
||||
/** Parsing de dates - LOGIQUE TECHNIQUE CRITIQUE PRÉSERVÉE */
|
||||
private LocalDateTime parseDate(String dateStr) {
|
||||
if (dateStr == null || dateStr.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// Essayer de parser en tant que date simple (YYYY-MM-DD)
|
||||
return LocalDateTime.parse(dateStr + "T00:00:00", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// Essayer de parser en tant que datetime (YYYY-MM-DDTHH:MM:SS)
|
||||
return LocalDateTime.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
||||
} catch (Exception ex) {
|
||||
throw new BadRequestException(
|
||||
"Format de date invalide: " + dateStr + ". Utilisez YYYY-MM-DD ou YYYY-MM-DDTHH:MM:SS");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user