diff --git a/e2e/input_template/EquipementPhysique_hors_serveur.csv b/e2e/input_template/EquipementPhysique_hors_serveur.csv index 09c3d4a9d0bce246d6e05f761f6980c5f90d7b6e..f8963fae13cdaafa4a4d2a48944b3d071820a321 100644 --- a/e2e/input_template/EquipementPhysique_hors_serveur.csv +++ b/e2e/input_template/EquipementPhysique_hors_serveur.csv @@ -5,9 +5,9 @@ physical-eq-003;P2719;4;;2021-03-30;2023-06-16;Monitor;In use;France;;;;MY ENTER physical-eq-004;HUB USB;10;;2023-04-01;2023-06-16;Consumable;Consumed;France;;;;MY ENTERPRISE;;365;;BYOD;0.1 physical-eq-005;P2720DC;2;;2022-11-04;2023-06-16;Monitor;In stock;France;;;;MY ENTERPRISE;;365;;BYOD;12.1 physical-eq-006;PIXEL 6;1;;2022-10-18;2023-06-16;Communication Device;Missing;France;;;;MY ENTERPRISE;;365;;;test -physical-eq-007;UP2516D;1;;2022-07-31;2023-06-16;Monitor;Retired;France;;;;MY ENTERPRISE;;365;;; -physical-eq-008;UP2516D;2;;2022-03-10;2023-06-16;Monitor;In stock;France;;;;MY ENTERPRISE;;365;;; -physical-eq-009;Unknown;3;;2021-08-09;2023-06-16;IP Router;In use;France;;;;MY ENTERPRISE;;365;;; +physical-eq-007;UP2516D;1;;2022-07-31;2023-06-16;Monitor;Retired;France;;;;MY ENTERPRISE;;365;;;0.9 +physical-eq-008;UP2516D;2;;2022-03-10;2023-06-16;Monitor;In stock;France;;;;MY ENTERPRISE;;365;;COPE;0.6 +physical-eq-009;Unknown;3;;2021-08-09;2023-06-16;IP Router;In use;France;;;;MY ENTERPRISE;;365;;COPE;0 physical-eq-010;Unknown;3;;2021-08-09;2023-06-16;IP Router;In use;France;;;;MY ENTERPRISE;;365;;; physical-eq-011;HP 8440p;1;;2021-08-05;2023-06-16;Personal Computer;Missing;France;;;;MY ENTERPRISE;;365;;; physical-eq-012;HP 8440p;1;;2023-04-27;2023-06-16;Personal Computer;Retired;France;;;;MY ENTERPRISE;;365;;; diff --git a/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/domain/ports/input/impl/ImportDonneesEntreePortImpl.java b/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/domain/ports/input/impl/ImportDonneesEntreePortImpl.java index 59a633323932aa11e8fe8e10fb80d820854254da..2b1557429d22610d08bbe2389ff8ebec0ddb5a4c 100644 --- a/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/domain/ports/input/impl/ImportDonneesEntreePortImpl.java +++ b/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/domain/ports/input/impl/ImportDonneesEntreePortImpl.java @@ -14,6 +14,7 @@ import org.mte.numecoeval.expositiondonneesentrees.infrastructure.service.ErrorM import org.mte.numecoeval.expositiondonneesentrees.referentiels.generated.api.model.TypeEquipementDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.multipart.MultipartFile; import java.io.FileNotFoundException; @@ -52,6 +53,9 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { final Map<String, String> errorMessages; + @Value("#{'${constraints.mode-utilisation}'.split(',')}") + private List<String> modeUtilisationList; + @Override public ResultatImport importCsv(String nomOrganisation, String nomLot, String dateLot, MultipartFile csvDataCenter, @@ -202,8 +206,14 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { var goTelechargeStr = CSVHelper.safeString(csvRecord, "goTelecharge"); Float goTelecharge = goTelechargeStr == null ? null : NumberUtils.toFloat(goTelechargeStr); var tauxUtilisationStr = CSVHelper.safeString(csvRecord, "tauxUtilisation"); - Double tauxUtilisation = tauxUtilisationStr == null ? null : NumberUtils.toDouble(tauxUtilisationStr); - + Double tauxUtilisation = NumberUtils.isCreatable(tauxUtilisationStr) ? NumberUtils.toDouble(tauxUtilisationStr) : null; + if (tauxUtilisation != null && (tauxUtilisation < 0 || tauxUtilisation > 1)) { + tauxUtilisation = null; + } + var modeUtilisation = CSVHelper.safeString(csvRecord, "modeUtilisation"); + if (!modeUtilisationList.contains(modeUtilisation)) { + modeUtilisation = null; + } EquipementPhysique equipementToAdd = EquipementPhysique.builder() .statutTraitement(STATUT_TRAITEMENT_EN_ATTENTE) @@ -222,7 +232,7 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { .nbCoeur(CSVHelper.safeString(csvRecord, "nbCoeur")) .nomCourtDatacenter(CSVHelper.safeString(csvRecord, "nomCourtDatacenter", "refDatacenter")) .goTelecharge(goTelecharge) - .modeUtilisation(CSVHelper.safeString(csvRecord, "modeUtilisation")) + .modeUtilisation(modeUtilisation) .tauxUtilisation(tauxUtilisation) .nbJourUtiliseAn(CSVHelper.safeDouble(csvRecord, "nbJourUtiliseAn")) .consoElecAnnuelle(CSVHelper.safeDouble(csvRecord, "consoElecAnnuelle")) diff --git a/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/config/ApplicationPortConfig.java b/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/config/ApplicationPortConfig.java index ecc79a180445b56b58d736660969c1c9bae6c806..7a62c6b92eb85a818dda843aadf2fcb05f9e3fb7 100644 --- a/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/config/ApplicationPortConfig.java +++ b/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/config/ApplicationPortConfig.java @@ -9,6 +9,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import java.util.List; + @Configuration @AllArgsConstructor @ComponentScan(basePackages = "org.mte.numecoeval.expositiondonneesentrees.infrastructure.adapters") @@ -18,9 +20,10 @@ public class ApplicationPortConfig { private ErrorManagementService errorManagementService; private MessageProperties messageProperties; + private List<String> modeUtilisationList; @Bean public ImportDonneesEntreePort importDonneesEntreePort() { - return new ImportDonneesEntreePortImpl(referentielServicePort, errorManagementService, messageProperties.getMessages()); + return new ImportDonneesEntreePortImpl(referentielServicePort, errorManagementService, messageProperties.getMessages(), modeUtilisationList); } } diff --git a/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/domain/port/input/ImportDonneesEntreePortImplTest.java b/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/domain/port/input/ImportDonneesEntreePortImplTest.java index 0bdb213e5c574fc002de9fc6f57da89459227be6..a92ad7fc80a14c33aa6e99fc16bb9a3482731263 100644 --- a/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/domain/port/input/ImportDonneesEntreePortImplTest.java +++ b/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/domain/port/input/ImportDonneesEntreePortImplTest.java @@ -31,11 +31,12 @@ class ImportDonneesEntreePortImplTest { ImportDonneesEntreePortImpl importDonneesEntreePort; ErrorManagementService errorManagementService; + private List<String> modeUtilisationList; @BeforeEach public void init() { MockitoAnnotations.openMocks(this); - importDonneesEntreePort = new ImportDonneesEntreePortImpl(referentielServicePort, errorManagementService, errorMessages); + importDonneesEntreePort = new ImportDonneesEntreePortImpl(referentielServicePort, errorManagementService, errorMessages, modeUtilisationList); } @Test diff --git a/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/data/demande/DemandeCalculImpactEquipementPhysique.java b/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/data/demande/DemandeCalculImpactEquipementPhysique.java index 4ea04c79e8018f9f68fce6742585101b26bf00bf..4e4247f964a5d4ced269f7defbaa65ab402926e3 100644 --- a/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/data/demande/DemandeCalculImpactEquipementPhysique.java +++ b/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/data/demande/DemandeCalculImpactEquipementPhysique.java @@ -46,6 +46,12 @@ public class DemandeCalculImpactEquipementPhysique { .findFirst(); } + public List<ReferentielHypothese> getHypothesesStartingWith(String startString) { + return hypotheses == null ? List.of() : hypotheses.stream() + .filter(hypothese -> hypothese.getCode().startsWith(startString)) + .toList(); + } + public Optional<ReferentielImpactEquipement> getImpactEquipement(String refEquipement) { if (refEquipement == null || impactEquipements == null) { return Optional.empty(); diff --git a/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/port/input/service/impl/CalculImpactEquipementPhysiqueServiceImpl.java b/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/port/input/service/impl/CalculImpactEquipementPhysiqueServiceImpl.java index a35d29cddf2b1173eca02136f512883077ebbf53..3dcdfe0a167e67091853e653241ba500a778fd71 100644 --- a/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/port/input/service/impl/CalculImpactEquipementPhysiqueServiceImpl.java +++ b/services/calculs/src/main/java/org/mte/numecoeval/calculs/domain/port/input/service/impl/CalculImpactEquipementPhysiqueServiceImpl.java @@ -19,6 +19,7 @@ import org.mte.numecoeval.calculs.domain.traceur.TraceCalculImpactEquipementPhys import org.mte.numecoeval.calculs.domain.traceur.TraceUtils; import java.util.Optional; +import java.util.stream.Collectors; @Slf4j @AllArgsConstructor @@ -257,17 +258,24 @@ public class CalculImpactEquipementPhysiqueServiceImpl implements CalculImpactEq /** - * compute the tauxUtilisationEquipementPhysique - * if the tauxUtilisation has been completed, we directly use this value - * else we retrieve the value of modeUtilisation and get the corresponding default value in ref_hypotheses + * Récupère le taux d'utilisation d'un équipement physique + * si le tauxUtilisation existe, on utilise la valeur, entre 0 et 1 + * si le modeUtilisation existe, on récupère la valeur dans les hypotheses + * sinon, on retourne 1 (=100% d'utilisation) * * @param demandeCalcul la demande de calcul * @return le taux d'utilsiation pour l'equipement physique + * @throws CalculImpactException si taux utilisation existe mais n'est pas entre 0 et 1 ou si le mode d'utilisation n'est pas connu */ - private Double getTauxUtilisationEqPhysique(DemandeCalculImpactEquipementPhysique demandeCalcul) { + private Double getTauxUtilisationEqPhysique(DemandeCalculImpactEquipementPhysique demandeCalcul) throws CalculImpactException { + var tauxUtilisation = demandeCalcul.getEquipementPhysique().getTauxUtilisation(); - if (tauxUtilisation != null && tauxUtilisation > 0.0 && tauxUtilisation <= 1.0) { + if (tauxUtilisation != null && (tauxUtilisation < 0 || tauxUtilisation > 1)) { + throw new CalculImpactException(TypeErreurCalcul.ERREUR_FONCTIONNELLE.getCode(), "Le taux d'utilisation doit être entre 0 et 1"); + } + + if (tauxUtilisation != null) { return tauxUtilisation; } @@ -275,10 +283,21 @@ public class CalculImpactEquipementPhysiqueServiceImpl implements CalculImpactEq return 1.0; } - var tauxUtilisationEqPhysique = demandeCalcul.getHypotheseFromCode("taux_utilisation_" + demandeCalcul.getEquipementPhysique().getModeUtilisation()); + final var tauxUtilisationStr = "taux_utilisation_"; + var tauxUtilisationEqPhysique = demandeCalcul.getHypotheseFromCode(tauxUtilisationStr + demandeCalcul.getEquipementPhysique().getModeUtilisation()); if (tauxUtilisationEqPhysique.isPresent()) { return tauxUtilisationEqPhysique.get().getValeur(); + } else { + var valeursTauxUtilisation = demandeCalcul.getHypothesesStartingWith(tauxUtilisationStr).stream() + .map(hypothese -> hypothese.getCode().replace(tauxUtilisationStr, "")) + .sorted() + .collect(Collectors.joining(", ")); + + throw new CalculImpactException( + TypeErreurCalcul.ERREUR_FONCTIONNELLE.getCode(), + valeursTauxUtilisation.isEmpty() ? + "Il n'y a pas d'hypotheses pour le taux d'utilisation" : + "Le mode d'utilisation doit avoir les valeurs " + valeursTauxUtilisation); } - return 1.0; } } diff --git a/services/calculs/src/test/java/org/mte/numecoeval/calculs/domain/service/CalculImpactEquipementPhysiqueServiceTest.java b/services/calculs/src/test/java/org/mte/numecoeval/calculs/domain/service/CalculImpactEquipementPhysiqueServiceTest.java index ffa130a08601b3757bb8c23d9baf34c0c4dd84ad..7d644ac5b0626e4878ecd18ad61315ace5d535de 100644 --- a/services/calculs/src/test/java/org/mte/numecoeval/calculs/domain/service/CalculImpactEquipementPhysiqueServiceTest.java +++ b/services/calculs/src/test/java/org/mte/numecoeval/calculs/domain/service/CalculImpactEquipementPhysiqueServiceTest.java @@ -2050,7 +2050,6 @@ class CalculImpactEquipementPhysiqueServiceTest { .quantite(1.0) .nbJourUtiliseAn(216.0) .consoElecAnnuelle(0.09) - .modeUtilisation("") .build(); ReferentielHypothese referentielHypothese = ReferentielHypothese.builder() .valeur(0.57) @@ -2122,11 +2121,10 @@ class CalculImpactEquipementPhysiqueServiceTest { ); //Then assertContentIndicateur(demandeCalcul, actual); - assertEquals("OK", actual.getStatutIndicateur()); - assertNotNull(actual.getImpactUnitaire()); - double actualImpactUnitaireLimited = BigDecimal.valueOf(actual.getImpactUnitaire()).setScale(4, RoundingMode.DOWN).doubleValue(); - assertEquals(0.0073, actualImpactUnitaireLimited); - assertEquals(referentielImpactEquipement.getConsoElecMoyenne(), actual.getConsoElecMoyenne()); + assertEquals("ERREUR", actual.getStatutIndicateur()); + assertEquals(""" + {"erreur":"ErrCalcFonc : Le mode d'utilisation doit avoir les valeurs BYOD"} + """.trim(), actual.getTrace()); } @Test @@ -2163,11 +2161,10 @@ class CalculImpactEquipementPhysiqueServiceTest { ); //Then assertContentIndicateur(demandeCalcul, actual); - assertEquals("OK", actual.getStatutIndicateur()); - assertNotNull(actual.getImpactUnitaire()); - double actualImpactUnitaireLimited = BigDecimal.valueOf(actual.getImpactUnitaire()).setScale(4, RoundingMode.DOWN).doubleValue(); - assertEquals(0.0073, actualImpactUnitaireLimited); - assertEquals(referentielImpactEquipement.getConsoElecMoyenne(), actual.getConsoElecMoyenne()); + assertEquals("ERREUR", actual.getStatutIndicateur()); + assertEquals(""" + {"erreur":"ErrCalcFonc : Il n'y a pas d'hypotheses pour le taux d'utilisation"} + """.trim(), actual.getTrace()); } @Test