diff --git a/e2e/input_template/EquipementPhysique_hors_serveur.csv b/e2e/input_template/EquipementPhysique_hors_serveur.csv index 65d3d63ad87cb2c8d5f688e1ce2a8214e2d5de00..918baf79bc1849420c76cd23e5c73c6151ec0435 100644 --- a/e2e/input_template/EquipementPhysique_hors_serveur.csv +++ b/e2e/input_template/EquipementPhysique_hors_serveur.csv @@ -6,10 +6,10 @@ physical-eq-004;HUB USB;10;;2023-04-01;2023-06-16;0.5;0.5;2;Consumable;Consumed; physical-eq-005;P2720DC;2;;2022-11-04;2023-06-16;-4.5;-1;2;Monitor;In stock;France;;;;MY ENTERPRISE;;365;;BYOD;12.1;moyenne physical-eq-006;PIXEL 6;1;;2022-10-18;2022-12-18;0.1;0.2;0.2;Communication Device;Missing;France;;;;MY ENTERPRISE;;365;;;test;haute physical-eq-007;UP2516D;1;;2022-07-31;2023-06-16;4.5;;;Monitor;Retired;France;;;;MY ENTERPRISE;;365;;;0.9;basse -physical-eq-008;UP2516D;2;;2022-03-10;2023-06-16;4.5;1;2;Monitor;In stock;France;;;;MY ENTERPRISE;;365;;COPE;0.6; +physical-eq-008;UP2516D;2;;2022-03-10;2023-06-16;4.5;1;2;Wrong / Type;In stock;France;;;;MY ENTERPRISE;;365;;COPE;0.6; physical-eq-009;Unknown;3;;2021-08-09;2023-06-16;4.5;1;2;IP Router;In use;France;;;;MY ENTERPRISE;;365;;COPE;0; physical-eq-010;Unknown;3;;2021-08-09;2023-06-16;4.5;1;2;IP Router;In use;France;;;;MY ENTERPRISE;;365;;;; -physical-eq-011;HP 8440p;1;;2021-08-05;2023-06-16;4.5;1;2;Personal Computer;Missing;France;;;;MY ENTERPRISE;;365;;;; +physical-eq-011;HP 8440p;1;;2021-08-05;2023-06-16;4.5;1;2;Wrong \type;Missing;France;;;;MY ENTERPRISE;;365;;;; physical-eq-012;HP 8440p;1;;2023-04-27;2023-06-16;4.5;1;2;Personal Computer;Retired;France;;;;MY ENTERPRISE;;365;;;; physical-eq-013;HP 8470w;2;;2025-08-23;2023-06-16;4.5;1;2;Personal Computer;Retired;France;;;;MY ENTERPRISE;;365;;;; physical-eq-014;OPPO A72;1;;2023-08-07;2023-06-16;4.5;1;2;Communication Device;Retired;France;;;;MY ENTERPRISE;;365;;;; diff --git a/e2e/input_template/OperationNonIT.csv b/e2e/input_template/OperationNonIT.csv index 9c9c6c5cb62533703dd1053e31a89e6eedc50e1f..66ad0e21b9b44d0b5d94deb99cfd8b92cc7484ea 100644 --- a/e2e/input_template/OperationNonIT.csv +++ b/e2e/input_template/OperationNonIT.csv @@ -8,7 +8,7 @@ batiment-dsi-Rennes;1200.0;Batiment 1;;France;EntiteTest;sourceTest5;;descriptio batiment-dsi-Cesson;1060.0;Batiment 2;;France;EntiteTest;sourceTest6;;description;;Basse batiment-dc-stMalo;836.0;Batiment DC;25.0;France;EntiteTest;sourceTest7;fakeName;description;; batiment-dc-Cesson;590.0;Batiment DC;;France;EntiteTest;sourceTest8;G1;description;; -maintenance-1;30.0;Maintenance 1;;France;EntiteTest;sourceTest9;;description;; +maintenance-1;30.0;Wrong/type;;France;EntiteTest;sourceTest9;;description;; deplacement-velo;1230.0;Deplacement Velo;;France;EntiteTest;sourceTest10;;description;; deplacement-trotinette;60.0;Deplacement Trotinette;;France;EntiteTest;sourceTest11;;description;; deplacement-voiture-electrique;156.0;Deplacement Voiture Electrique;;France;EntiteTest;sourceTest12;;description;; 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 e213130d37706c222710d104c1d204f48a77c577..cdb09811ef29d757887f67ef4b1435b06f757a4f 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 @@ -206,13 +206,17 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { records.forEach(csvRecord -> { + String nomEquipementPhysique = CSVHelper.safeString(csvRecord, LABEL_NOM_EQUIPEMENT_PHYSIQUE, "equipement"); String typeEquipement = csvRecord.get("type"); + String checkNomTypeItem = errorManagementService.checkNomTypeItem(typeEquipement, "L'équipement physique", nomEquipementPhysique); var refTypeEquipementOpt = typesEquipement.stream() .filter(refType -> refType.getType().equals(typeEquipement)) .findFirst(); if (!Arrays.stream(EQUIPEMENT_PHYSIQUE_HEADER).allMatch(csvRecord::isMapped)) { rapportImport.getErreurs().add(errorMessages.get(LIGNE_INCONSISTENTE).formatted(csvEquipementPhysique.getOriginalFilename(), csvRecord.getRecordNumber() + 1)); + } else if (checkNomTypeItem != null) { + rapportImport.getErreurs().add(checkNomTypeItem); } else if (refTypeEquipementOpt.isEmpty()) { // CA 1.1 rapportImport.getErreurs().add(errorMessages.get("TYPE_ITEM_INCONNU").formatted(csvRecord.get("type"), CSVHelper.safeString(csvRecord, LABEL_NOM_EQUIPEMENT_PHYSIQUE, "equipement"))); @@ -227,7 +231,6 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { Double dureeUsageAval = dureeUsageAvalStr == null ? 0 : NumberUtils.toDouble(dureeUsageAvalStr); var tauxUtilisationStr = CSVHelper.safeString(csvRecord, "tauxUtilisation"); Double tauxUtilisation = NumberUtils.isCreatable(tauxUtilisationStr) ? NumberUtils.toDouble(tauxUtilisationStr) : null; - String nomEquipementPhysique = CSVHelper.safeString(csvRecord, LABEL_NOM_EQUIPEMENT_PHYSIQUE, "equipement"); String qualite = CSVHelper.safeString(csvRecord, "qualite"); if (qualite != null) qualite = qualite.toUpperCase(); @@ -244,7 +247,7 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { .dateLot(dateLot) .nomOrganisation(nomOrganisation) .modele(CSVHelper.safeString(csvRecord, "modele", "refEquipement")) - .type(csvRecord.get("type")) + .type(typeEquipement) .quantite(CSVHelper.safeDouble(csvRecord, "quantite")) .nomEquipementPhysique(nomEquipementPhysique) .statut(CSVHelper.safeString(csvRecord, "statut")) @@ -466,18 +469,20 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { .build().parse(reader); records.forEach(csvRecord -> { + String nomItem = CSVHelper.safeString(csvRecord, LABEL_nom_item_non_it); String typeItem = csvRecord.get("type"); + String checkNomTypeItem = errorManagementService.checkNomTypeItem(typeItem, "L'opération non IT", nomItem); var refTypeItemOpt = typesItem.stream() .filter(refType -> refType.getType().equals(typeItem)) .findFirst(); - String nomItem = CSVHelper.safeString(csvRecord, LABEL_nom_item_non_it); String error = checkCSVRecord(csvRecord, OPERATION_NON_IT_HEADER, OPERATION_NON_IT_NOT_BLANK_FIELDS); if (error != null) { rapportImport.getErreurs().add(error); + } else if (checkNomTypeItem != null) { + rapportImport.getErreurs().add(checkNomTypeItem); } else if (refTypeItemOpt.isEmpty()) { rapportImport.getErreurs().add(errorMessages.get("TYPE_ITEM_INCONNU").formatted(csvRecord.get("type"), nomItem)); } else { - String qualite = CSVHelper.safeString(csvRecord, "qualite"); if (qualite != null) qualite = qualite.toUpperCase(); diff --git a/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementService.java b/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementService.java index fca94b4cfe98243b323644f983dbd2817671eb9f..f0faabc32f03e6e6460dc04da04e83c38fd38c0b 100644 --- a/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementService.java +++ b/services/api-expositiondonneesentrees/src/main/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementService.java @@ -45,6 +45,24 @@ public class ErrorManagementService { return messageProperties.getMessages().get("QUALITE_INVALIDE").formatted(type, nom, qualite); } + /** + * Vérifie si la syntaxe du nom fourni comme typeItem (dans l'inventaire d'un équipement physique ou d'une opération non IT) est correcte + * C'est à dire que le type ne contient pas les caractères '/' ou '\'. + * si ce n'est pas le cas, on lance une erreur + * + * @param type la qualité en majuscule + * @param nomItem le nom d'item : équipement ou opération non IT + * @param nom le nom de l'équipement + * @return l'avertissement associé ou null + */ + public String checkNomTypeItem(String type, String nomItem, String nom) { + if (type == null) return null; + if (!type.contains("/") && !type.contains("\\")) { + return null; + } + return messageProperties.getMessages().get("TYPE_ITEM_INVALIDE").formatted(nomItem, nom, type); + } + /** * Vérifie si la localisation du datacenter existe dans la table ref_MixElec.pays * @@ -127,12 +145,12 @@ public class ErrorManagementService { erreurs.add(messageProperties.getMessages().get("EQUIPEMENT_DUREE_USAGE_INCOHERENTE").formatted("aval", equipementPhysique.getNomEquipementPhysique())); } //CA 5.1 - //L'ajout d'un équipement dont le mode d'utilisation est autre que COPE, BYOD ou null + // L'ajout d'un équipement dont le mode d'utilisation est autre que COPE, BYOD ou null if (equipementPhysique.getModeUtilisation() != null && !modeUtilisationList.contains(equipementPhysique.getModeUtilisation())) { avertissements.add(messageProperties.getMessages().get("EQUIPEMENT_MODE_UTILISATION_INCONNU").formatted(equipementPhysique.getModeUtilisation())); } //CA 6.1 - //L'ajout d'un équipement dont le taux d'utilisation n'est pas compris entre 0 et 1 + // L'ajout d'un équipement dont le taux d'utilisation n'est pas compris entre 0 et 1 Double taux = equipementPhysique.getTauxUtilisation(); if (taux != null && (taux < 0 || taux > 1)) { avertissements.add(messageProperties.getMessages().get("EQUIPEMENT_TAUX_UTILISATION_INVALIDE").formatted(taux)); @@ -168,5 +186,4 @@ public class ErrorManagementService { } return Pair.of(erreurs, avertissements.stream().toList()); } - } diff --git a/services/api-expositiondonneesentrees/src/main/resources/application.yaml b/services/api-expositiondonneesentrees/src/main/resources/application.yaml index b4fd32d40de92570ee37616e607a794b57c8a185..ea08d244375722274fda3c213d7d1196e14a703d 100644 --- a/services/api-expositiondonneesentrees/src/main/resources/application.yaml +++ b/services/api-expositiondonneesentrees/src/main/resources/application.yaml @@ -96,5 +96,6 @@ messages: APPLICATION_AVEC_EQUIPEMENT_PHYSIQUE_INCONNU: "L'application %s n'est supporté par aucun équipement physique" APPLICATION_AVEC_EQUIPEMENT_VIRTUEL_INCONNU: "L'application %s n'est supporté par aucun équipement virtuel" QUALITE_INVALIDE: "%s '%s' possède une valeur de qualité invalide renseignée. La valeur '%s' est ignorée car elle n'est pas l'une de ces valeurs: BASSE, MOYENNE, HAUTE" + TYPE_ITEM_INVALIDE: "%s '%s' possède un type dont la valeur : '%s' est invalide. La valeur ne doit pas contenir les caractères '/' et '\\'." constraints: mode-utilisation: "BYOD,COPE" diff --git a/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementServiceTest.java b/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementServiceTest.java index 9e8f44e23ed1c29f8f44cdd662e4a726499f96d1..7f3d0c3fed86e0c14109f9e299091d19d1ca4bfd 100644 --- a/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementServiceTest.java +++ b/services/api-expositiondonneesentrees/src/test/java/org/mte/numecoeval/expositiondonneesentrees/infrastructure/service/ErrorManagementServiceTest.java @@ -262,4 +262,11 @@ public class ErrorManagementServiceTest { ); } + @Test + void importEqPhysique_with_NomTypeInvalide() { + Assertions.assertEquals( + "L'équipement physique 'eq1' possède un type dont la valeur : 'Monitor/' est invalide. La valeur ne doit pas contenir les caractères '/' et '\\'.", + errorManagementService.checkNomTypeItem("Monitor/", "L'équipement physique", "eq1") + ); + } }