Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • creation_mode_onlyapi
  • deployment_with_superset
  • develop
  • main
  • 1.2.2
  • 1.3.0
  • 2.0.0
  • 2.0.1
  • 2.1.0
9 results

Target

Select target project
  • pub/numeco/m4g/numecoeval
1 result
Select Git revision
  • creation_mode_onlyapi
  • deployment_with_superset
  • develop
  • main
  • 1.2.2
  • 1.3.0
  • 2.0.0
  • 2.0.1
  • 2.1.0
9 results
Show changes
Commits on Source (9)
Showing
with 159 additions and 86 deletions
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
Tous les changements de ce projet seront documentés dans ce document. Tous les changements de ce projet seront documentés dans ce document.
## [Non livré] ## [Non livré]
## [2.0.0] - 2024-06-14
Adaptations pour être conforme avec le référentiel méthodologique d'évaluation environnementale des Systèmes d'Information [(RCP SI)](https://librairie.ademe.fr/consommer-autrement/6649-referentiel-methodologique-d-evaluation-environnementale-des-systemes-d-information-si.html):
- Pouvoir charger et lancer un calcul sur les opérations non IT -> [Issue3](https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/issues/3) - Pouvoir charger et lancer un calcul sur les opérations non IT -> [Issue3](https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/issues/3)
- Intégrer la durée d'usage amont et aval des équipements physiques & ajout d'un paramètre pour choisir la méthode de calcul de la durée d'usage d'un équipement physique -> [Issue5](https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/issues/5) - Intégrer la durée d'usage amont et aval des équipements physiques & ajout d'un paramètre pour choisir la méthode de calcul de la durée d'usage d'un équipement physique -> [Issue5](https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/issues/5)
- Pouvoir inclure dans l'évaluation d'impact des informations sur la qualité des données -> [Issue4](https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/issues/4) - Pouvoir inclure dans l'évaluation d'impact des informations sur la qualité des données -> [Issue4](https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/issues/4)
......
...@@ -424,46 +424,58 @@ Elle est exprimée en années et autorise les décimales. ...@@ -424,46 +424,58 @@ Elle est exprimée en années et autorise les décimales.
[pseudocode] [pseudocode]
---- ----
Règle RG_DureeVieItem(equipementPhysique,dureeVieItem,methodeDureeUsage) { Règle RG_DureeVieItem(equipementPhysique) {
SI methodeDureeUsage=="REEL" SI methodeDureeUsage=="REEL"
ALORS ALORS
'dans le cas où il est possible de calculer l'age réel de l'item, ce dernier fait foi 'dans le cas où il est possible de calculer l'age réel de l'item, ce dernier fait foi
SI equipementPhysique.DateAchat est correcte et renseignée ET equipementPhysique.DateRetrait est correcte et renseignée SI equipementPhysique.DateAchat est correcte et renseignée ET equipementPhysique.DateRetrait est correcte et renseignée
ALORS ALORS
SI (equipementPhysique.DateRetrait - equipementPhysique.DateAchat) < 1 SI ((equipementPhysique.DateRetrait - equipementPhysique.DateAchat) / 365 + equipementPhysique.dureeUsageAmont + equipementPhysique.dureeUsageAval < 1)
ALORS RENVOYER (1 + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) ' si la durée de vie totale de l'équipement est inférieure à 1 an, on la fixe à 1 an car :
' comme impact = facteurCaracterisation/dureeDeVie, si la dureeDeVie est inférieure à 1, on prendrait + de 100% de l'impact de l'équipement pour sa première année ce qui n'est pas logique
ALORS RENVOYER 1
SINON RENVOYER (((equipementPhysique.DateRetrait - equipementPhysique.DateAchat) / 365) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) SINON RENVOYER (((equipementPhysique.DateRetrait - equipementPhysique.DateAchat) / 365) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
'dans le cas où seul la date d'achat est disponible, la règle du "Pseudo-amortissement" prévaut (impact de 100% sur l'année d'achat, 50% l'année 2, 33% l'année 3, etc... ) 'dans le cas où seul la date d'achat est disponible, la règle du "Pseudo-amortissement" prévaut (impact de 100% sur l'année d'achat, 50% l'année 2, 33% l'année 3, etc... )
SINON SI equipementPhysique.DateAchat est correcte et equipementPhysique.DateRetrait non reseignée SINON SI equipementPhysique.DateAchat est correcte et equipementPhysique.DateRetrait non reseignée
ALORS RENVOYER (((equipementPhysique.DateAchat - date du jour) / 365) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) SI ((equipementPhysique.DateRetrait - date du jour) / 365 + equipementPhysique.dureeUsageAmont + equipementPhysique.dureeUsageAval < 1)
ALORS RENVOYER 1
SINON RENVOYER (((equipementPhysique.DateAchat - date du jour) / 365) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
'dans les autres cas, une durée de vie moyenne de l'équipement est déduite 'dans les autres cas, une durée de vie moyenne de l'équipement est déduite
SINON SINON
RENVOYER (RG_DureeVieEqP_Defaut(equipementPhysique)+ equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) SI (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
ALORS RENVOYER 1
SINON RENVOYER (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
FIN SI FIN SI
'par défaut, la méthode de calcul de la durée de vie est la méthode "FIXE"
SINON SINON
'dans le cas où nous connaissons la durée d'usage interne par défaut, cette dernière fait foi 'dans le cas où nous connaissons la durée d'usage interne par défaut, cette dernière fait foi
SI equipementPhysique.DureeUsageInterne est renseignée et supérieure à 0 SI equipementPhysique.DureeUsageInterne est renseignée et supérieure à 0
ALORS ALORS
SI (equipementPhysique.DureeUsageInterne<1) SI (equipementPhysique.DureeUsageInterne + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
ALORS RENVOYER (1 + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) ALORS RENVOYER 1
SINON RENVOYER (equipementPhysique.DureeUsageInterne + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) SINON RENVOYER (equipementPhysique.DureeUsageInterne + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
SINON SINON
RENVOYER (RG_DureeVieEqP_Defaut(equipementPhysique)+ equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval) SI (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
ALORS RENVOYER 1
SINON RENVOYER (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
FIN SI FIN SI
FIN SI FIN SI
} }
Règle RG_DureeVieItem(operationNonIT,dureeVieItem) { Règle RG_DureeVieItem(operationNonIT) {
'dans le cas où il est possible de calculer l'age réel de l'item, ce dernier fait foi 'dans le cas où il est possible de calculer l'age réel de l'item, ce dernier fait foi
SI operationNonIT.dureeDeVie est correcte et renseignée SI operationNonIT.dureeDeVie est correcte et renseignée
ALORS ALORS
RENVOYER operationNonIT.dureeDeVie SI operationNonIT.dureeDeVie < 1
ALORS RENVOYER 1
SINON RENVOYER operationNonIT.dureeDeVie
'dans les autres cas, une durée de vie moyenne de l'équipement est déduite 'dans les autres cas, une durée de vie moyenne de l'équipement est déduite
SINON SINON
RENVOYER RG_DureeVieItem_Defaut(operationNonIT) SI RG_DureeVieItem_Defaut(operationNonIT) < 1
ALORS RENVOYER 1
SINON RENVOYER RG_DureeVieItem_Defaut(operationNonIT)
FIN SI FIN SI
} }
---- ----
...@@ -675,7 +687,7 @@ refEquipementRetenu = RG_correspondanceRefEquipement(nomOrganisation, equipement ...@@ -675,7 +687,7 @@ refEquipementRetenu = RG_correspondanceRefEquipement(nomOrganisation, equipement
'récupération de l'impact pour le critère et l'étape ACV en cours, de la référence de l'équipement retenue 'récupération de l'impact pour le critère et l'étape ACV en cours, de la référence de l'équipement retenue
x Ref_FacteurCaracterisation(refEquipementretenu, EtapeACV, Critere).valeur x Ref_FacteurCaracterisation(refEquipementretenu, EtapeACV, Critere).valeur
/ RG_DureeVieEqP / RG_DureeVieItem_Defaut(equipementPhysique)
'conso electrique retenue est null 'conso electrique retenue est null
ind_ImpactEquipementPhysique.consoElecMoyenne = null ind_ImpactEquipementPhysique.consoElecMoyenne = null
...@@ -854,7 +866,7 @@ Règle calculIndicateurImpactOperationNonIT(critere, etape, nomOrganisation, OpN ...@@ -854,7 +866,7 @@ Règle calculIndicateurImpactOperationNonIT(critere, etape, nomOrganisation, OpN
/ ref_Hypothese.valeur(CAPACITE_LIGNE_FIXE_LOCALISATION) / ref_Hypothese.valeur(CAPACITE_LIGNE_FIXE_LOCALISATION)
SINON SI OpNIT.categorie = "BATIMENT" SINON SI OpNIT.categorie = "BATIMENT"
/ dureeDeVie / RG_DureeVieItem_Defaut(operationNonIT)
FIN SI FIN SI
SINON SI OpNIT.categorie = "DEPLACEMENT_ELECTRIQUE" OU "DEPLACEMENT_ESSENCE" OU DEPLACEMENT_HYBRIDE SINON SI OpNIT.categorie = "DEPLACEMENT_ELECTRIQUE" OU "DEPLACEMENT_ESSENCE" OU DEPLACEMENT_HYBRIDE
......
...@@ -69,7 +69,7 @@ class ConsoElecAnMoyenne { ...@@ -69,7 +69,7 @@ class ConsoElecAnMoyenne {
} }
class DureeDeVie { class DureeDeVie {
Double valeur Double valeurRetenue
private String methodeDureeUsage private String methodeDureeUsage
private Double dureeUsageInterne private Double dureeUsageInterne
private Double dureeUsageAmont private Double dureeUsageAmont
......
...@@ -6,10 +6,10 @@ physical-eq-004;HUB USB;10;;2023-04-01;2023-06-16;0.5;0.5;2;Consumable;Consumed; ...@@ -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-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-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-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-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-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-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-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;;;; physical-eq-014;OPPO A72;1;;2023-08-07;2023-06-16;4.5;1;2;Communication Device;Retired;France;;;;MY ENTERPRISE;;365;;;;
......
...@@ -8,7 +8,7 @@ batiment-dsi-Rennes;1200.0;Batiment 1;;France;EntiteTest;sourceTest5;;descriptio ...@@ -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-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-stMalo;836.0;Batiment DC;25.0;France;EntiteTest;sourceTest7;fakeName;description;;
batiment-dc-Cesson;590.0;Batiment DC;;France;EntiteTest;sourceTest8;G1;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-velo;1230.0;Deplacement Velo;;France;EntiteTest;sourceTest10;;description;;
deplacement-trotinette;60.0;Deplacement Trotinette;;France;EntiteTest;sourceTest11;;description;; deplacement-trotinette;60.0;Deplacement Trotinette;;France;EntiteTest;sourceTest11;;description;;
deplacement-voiture-electrique;156.0;Deplacement Voiture Electrique;;France;EntiteTest;sourceTest12;;description;; deplacement-voiture-electrique;156.0;Deplacement Voiture Electrique;;France;EntiteTest;sourceTest12;;description;;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/../../e2e/e2e.iml" filepath="$PROJECT_DIR$/../../e2e/e2e.iml" />
</modules> </modules>
</component> </component>
</project> </project>
\ No newline at end of file
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<option name="configurationPath" value="" /> <option name="configurationPath" value="" />
<option name="exclusions"> <option name="exclusions">
<set> <set>
<option value=".*\.adoc" />
<option value=".*\.yaml" /> <option value=".*\.yaml" />
<option value=".*\.yml" /> <option value=".*\.yml" />
</set> </set>
......
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
<parent> <parent>
<groupId>org.mte.numecoeval</groupId> <groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>api-event-calculs</artifactId> <artifactId>api-event-calculs</artifactId>
<name>api-event-calculs</name> <name>api-event-calculs</name>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<description>api-event-calculs</description> <description>api-event-calculs</description>
<repositories> <repositories>
......
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
<parent> <parent>
<groupId>org.mte.numecoeval</groupId> <groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>api-event-donneesEntrees</artifactId> <artifactId>api-event-donneesEntrees</artifactId>
<name>api-event-donneesEntrees</name> <name>api-event-donneesEntrees</name>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<description>api-event-donneesEntrees</description> <description>api-event-donneesEntrees</description>
<repositories> <repositories>
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
<parent> <parent>
<groupId>org.mte.numecoeval</groupId> <groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>api-expositiondonneesentrees</artifactId> <artifactId>api-expositiondonneesentrees</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<name>api-expositiondonneesentrees</name> <name>api-expositiondonneesentrees</name>
<description>API Exposition des données d'entrées - Exposition par API pour injecter des données d'entrées <description>API Exposition des données d'entrées - Exposition par API pour injecter des données d'entrées
</description> </description>
......
...@@ -206,13 +206,17 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { ...@@ -206,13 +206,17 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort {
records.forEach(csvRecord -> records.forEach(csvRecord ->
{ {
String nomEquipementPhysique = CSVHelper.safeString(csvRecord, LABEL_NOM_EQUIPEMENT_PHYSIQUE, "equipement");
String typeEquipement = csvRecord.get("type"); String typeEquipement = csvRecord.get("type");
String checkNomTypeItem = errorManagementService.checkNomTypeItem(typeEquipement, "L'équipement physique", nomEquipementPhysique);
var refTypeEquipementOpt = typesEquipement.stream() var refTypeEquipementOpt = typesEquipement.stream()
.filter(refType -> refType.getType().equals(typeEquipement)) .filter(refType -> refType.getType().equals(typeEquipement))
.findFirst(); .findFirst();
if (!Arrays.stream(EQUIPEMENT_PHYSIQUE_HEADER).allMatch(csvRecord::isMapped)) { if (!Arrays.stream(EQUIPEMENT_PHYSIQUE_HEADER).allMatch(csvRecord::isMapped)) {
rapportImport.getErreurs().add(errorMessages.get(LIGNE_INCONSISTENTE).formatted(csvEquipementPhysique.getOriginalFilename(), csvRecord.getRecordNumber() + 1)); 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()) { } else if (refTypeEquipementOpt.isEmpty()) {
// CA 1.1 // CA 1.1
rapportImport.getErreurs().add(errorMessages.get("TYPE_ITEM_INCONNU").formatted(csvRecord.get("type"), CSVHelper.safeString(csvRecord, LABEL_NOM_EQUIPEMENT_PHYSIQUE, "equipement"))); 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 { ...@@ -227,7 +231,6 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort {
Double dureeUsageAval = dureeUsageAvalStr == null ? 0 : NumberUtils.toDouble(dureeUsageAvalStr); Double dureeUsageAval = dureeUsageAvalStr == null ? 0 : NumberUtils.toDouble(dureeUsageAvalStr);
var tauxUtilisationStr = CSVHelper.safeString(csvRecord, "tauxUtilisation"); var tauxUtilisationStr = CSVHelper.safeString(csvRecord, "tauxUtilisation");
Double tauxUtilisation = NumberUtils.isCreatable(tauxUtilisationStr) ? NumberUtils.toDouble(tauxUtilisationStr) : null; 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"); String qualite = CSVHelper.safeString(csvRecord, "qualite");
if (qualite != null) qualite = qualite.toUpperCase(); if (qualite != null) qualite = qualite.toUpperCase();
...@@ -244,7 +247,7 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { ...@@ -244,7 +247,7 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort {
.dateLot(dateLot) .dateLot(dateLot)
.nomOrganisation(nomOrganisation) .nomOrganisation(nomOrganisation)
.modele(CSVHelper.safeString(csvRecord, "modele", "refEquipement")) .modele(CSVHelper.safeString(csvRecord, "modele", "refEquipement"))
.type(csvRecord.get("type")) .type(typeEquipement)
.quantite(CSVHelper.safeDouble(csvRecord, "quantite")) .quantite(CSVHelper.safeDouble(csvRecord, "quantite"))
.nomEquipementPhysique(nomEquipementPhysique) .nomEquipementPhysique(nomEquipementPhysique)
.statut(CSVHelper.safeString(csvRecord, "statut")) .statut(CSVHelper.safeString(csvRecord, "statut"))
...@@ -466,18 +469,20 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort { ...@@ -466,18 +469,20 @@ public class ImportDonneesEntreePortImpl implements ImportDonneesEntreePort {
.build().parse(reader); .build().parse(reader);
records.forEach(csvRecord -> records.forEach(csvRecord ->
{ {
String nomItem = CSVHelper.safeString(csvRecord, LABEL_nom_item_non_it);
String typeItem = csvRecord.get("type"); String typeItem = csvRecord.get("type");
String checkNomTypeItem = errorManagementService.checkNomTypeItem(typeItem, "L'opération non IT", nomItem);
var refTypeItemOpt = typesItem.stream() var refTypeItemOpt = typesItem.stream()
.filter(refType -> refType.getType().equals(typeItem)) .filter(refType -> refType.getType().equals(typeItem))
.findFirst(); .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); String error = checkCSVRecord(csvRecord, OPERATION_NON_IT_HEADER, OPERATION_NON_IT_NOT_BLANK_FIELDS);
if (error != null) { if (error != null) {
rapportImport.getErreurs().add(error); rapportImport.getErreurs().add(error);
} else if (checkNomTypeItem != null) {
rapportImport.getErreurs().add(checkNomTypeItem);
} else if (refTypeItemOpt.isEmpty()) { } else if (refTypeItemOpt.isEmpty()) {
rapportImport.getErreurs().add(errorMessages.get("TYPE_ITEM_INCONNU").formatted(csvRecord.get("type"), nomItem)); rapportImport.getErreurs().add(errorMessages.get("TYPE_ITEM_INCONNU").formatted(csvRecord.get("type"), nomItem));
} else { } else {
String qualite = CSVHelper.safeString(csvRecord, "qualite"); String qualite = CSVHelper.safeString(csvRecord, "qualite");
if (qualite != null) qualite = qualite.toUpperCase(); if (qualite != null) qualite = qualite.toUpperCase();
......
...@@ -45,6 +45,24 @@ public class ErrorManagementService { ...@@ -45,6 +45,24 @@ public class ErrorManagementService {
return messageProperties.getMessages().get("QUALITE_INVALIDE").formatted(type, nom, qualite); 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 * Vérifie si la localisation du datacenter existe dans la table ref_MixElec.pays
* *
...@@ -127,12 +145,12 @@ public class ErrorManagementService { ...@@ -127,12 +145,12 @@ public class ErrorManagementService {
erreurs.add(messageProperties.getMessages().get("EQUIPEMENT_DUREE_USAGE_INCOHERENTE").formatted("aval", equipementPhysique.getNomEquipementPhysique())); erreurs.add(messageProperties.getMessages().get("EQUIPEMENT_DUREE_USAGE_INCOHERENTE").formatted("aval", equipementPhysique.getNomEquipementPhysique()));
} }
//CA 5.1 //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())) { if (equipementPhysique.getModeUtilisation() != null && !modeUtilisationList.contains(equipementPhysique.getModeUtilisation())) {
avertissements.add(messageProperties.getMessages().get("EQUIPEMENT_MODE_UTILISATION_INCONNU").formatted(equipementPhysique.getModeUtilisation())); avertissements.add(messageProperties.getMessages().get("EQUIPEMENT_MODE_UTILISATION_INCONNU").formatted(equipementPhysique.getModeUtilisation()));
} }
//CA 6.1 //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(); Double taux = equipementPhysique.getTauxUtilisation();
if (taux != null && (taux < 0 || taux > 1)) { if (taux != null && (taux < 0 || taux > 1)) {
avertissements.add(messageProperties.getMessages().get("EQUIPEMENT_TAUX_UTILISATION_INVALIDE").formatted(taux)); avertissements.add(messageProperties.getMessages().get("EQUIPEMENT_TAUX_UTILISATION_INVALIDE").formatted(taux));
...@@ -168,5 +186,4 @@ public class ErrorManagementService { ...@@ -168,5 +186,4 @@ public class ErrorManagementService {
} }
return Pair.of(erreurs, avertissements.stream().toList()); return Pair.of(erreurs, avertissements.stream().toList());
} }
} }
...@@ -96,5 +96,6 @@ messages: ...@@ -96,5 +96,6 @@ messages:
APPLICATION_AVEC_EQUIPEMENT_PHYSIQUE_INCONNU: "L'application %s n'est supporté par aucun équipement physique" 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" 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" 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: constraints:
mode-utilisation: "BYOD,COPE" mode-utilisation: "BYOD,COPE"
...@@ -262,4 +262,11 @@ public class ErrorManagementServiceTest { ...@@ -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")
);
}
} }
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
<parent> <parent>
<groupId>org.mte.numecoeval</groupId> <groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>api-referentiel</artifactId> <artifactId>api-referentiel</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<name>api-referentiel</name> <name>api-referentiel</name>
<description>API Referentiel - Lecture, chargement et exposition par API</description> <description>API Referentiel - Lecture, chargement et exposition par API</description>
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
<parent> <parent>
<groupId>org.mte.numecoeval</groupId> <groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>calculs</artifactId> <artifactId>calculs</artifactId>
<version>1.3.1-SNAPSHOT</version> <version>2.1.0-SNAPSHOT</version>
<name>calculs</name> <name>calculs</name>
<description>Module contenant l'intégralité des règles de calculs et du code métier lié aux calculs d'impact <description>Module contenant l'intégralité des règles de calculs et du code métier lié aux calculs d'impact
d'équipement d'équipement
......
...@@ -72,7 +72,9 @@ public class DemandeCalculImpactOperationNonIT { ...@@ -72,7 +72,9 @@ public class DemandeCalculImpactOperationNonIT {
return facteurCaracterisations.stream() return facteurCaracterisations.stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(fc -> Constants.ELECTRICITY_MIX_CATEGORY.equals(fc.getCategorie()) && .filter(fc -> Constants.ELECTRICITY_MIX_CATEGORY.equals(fc.getCategorie()) &&
localisation.equals(fc.getLocalisation())) localisation.equals(fc.getLocalisation()) &&
critere.getNomCritere().equals(fc.getCritere())
)
.findFirst(); .findFirst();
} }
......
...@@ -2,9 +2,13 @@ package org.mte.numecoeval.calculs.domain.port.input.service; ...@@ -2,9 +2,13 @@ package org.mte.numecoeval.calculs.domain.port.input.service;
import org.mte.numecoeval.calculs.domain.data.demande.DemandeCalculImpactOperationNonIT; import org.mte.numecoeval.calculs.domain.data.demande.DemandeCalculImpactOperationNonIT;
import org.mte.numecoeval.calculs.domain.data.indicateurs.ImpactOperationNonIT; import org.mte.numecoeval.calculs.domain.data.indicateurs.ImpactOperationNonIT;
import org.mte.numecoeval.calculs.domain.data.trace.DureeDeVie;
import org.mte.numecoeval.calculs.domain.exception.CalculImpactException;
public interface CalculImpactOperationNonITService { public interface CalculImpactOperationNonITService {
ImpactOperationNonIT calculerImpactOperationNonIT(DemandeCalculImpactOperationNonIT demandeCalcul); ImpactOperationNonIT calculerImpactOperationNonIT(DemandeCalculImpactOperationNonIT demandeCalcul);
DureeDeVie getDureeVie(DemandeCalculImpactOperationNonIT demandeCalcul) throws CalculImpactException;
} }
...@@ -119,7 +119,7 @@ public class CalculImpactOperationNonITServiceImpl implements CalculImpactOperat ...@@ -119,7 +119,7 @@ public class CalculImpactOperationNonITServiceImpl implements CalculImpactOperat
} }
MetadataCalcul metadataCalcul = getFormule(demandeCalcul); MetadataCalcul metadataCalcul = getFormule(demandeCalcul);
DureeDeVie dureeDeVie = getDureeVie(demandeCalcul); DureeDeVie dureeDeVie = getDureeVie(demandeCalcul);
Double dureeDeVieValeur = (dureeDeVie.getValeurRetenue() == null) ? dureeDeVie.getDureeDeVieParDefaut().getValeur() : dureeDeVie.getValeurRetenue(); Double dureeDeVieValeur = dureeDeVie.getValeurRetenue();
Double valeurImpactUnitaire = metadataCalcul.valeurImpactUnitaire() / dureeDeVieValeur; Double valeurImpactUnitaire = metadataCalcul.valeurImpactUnitaire() / dureeDeVieValeur;
TraceCalculImpactOperationNonIT traceCalculImpactOperationNonIT = metadataCalcul.traceCalculImpactOperationNonIT(); TraceCalculImpactOperationNonIT traceCalculImpactOperationNonIT = metadataCalcul.traceCalculImpactOperationNonIT();
String traceFormuleBase = traceCalculImpactOperationNonIT.getFormule(); String traceFormuleBase = traceCalculImpactOperationNonIT.getFormule();
...@@ -320,33 +320,53 @@ public class CalculImpactOperationNonITServiceImpl implements CalculImpactOperat ...@@ -320,33 +320,53 @@ public class CalculImpactOperationNonITServiceImpl implements CalculImpactOperat
* *
* @param demandeCalcul la demande de calcul * @param demandeCalcul la demande de calcul
* @return dureeDeVie * @return dureeDeVie
* @throws CalculImpactException * @throws CalculImpactException sinon
*/ */
public DureeDeVie getDureeVie(DemandeCalculImpactOperationNonIT demandeCalcul) throws CalculImpactException { public DureeDeVie getDureeVie(DemandeCalculImpactOperationNonIT demandeCalcul) throws CalculImpactException {
var refHypotheseOpt = demandeCalcul.getHypotheseFromCode("dureeVieBatimentParDefaut");
var dureeDeVie = DureeDeVie.builder().build(); var dureeDeVie = DureeDeVie.builder().build();
if (demandeCalcul.getOperationNonIT().getDureeDeVie() != null) { Double dureeInventaire = demandeCalcul.getOperationNonIT().getDureeDeVie();
dureeDeVie.setValeurRetenue(demandeCalcul.getOperationNonIT().getDureeDeVie()); if (dureeInventaire != null) {
dureeDeVie.setValeurRetenue(dureeInventaire < 1 ? 1.0 : dureeInventaire);
return dureeDeVie;
}
} else if (demandeCalcul.getTypeItem() != null && demandeCalcul.getTypeItem().getDureeVieDefaut() != null) { // dureeInventaire est null
dureeDeVie.setDureeDeVieParDefaut(DureeDeVieParDefaut.builder() // recuperation duree de vie via typeItem
.valeurTypeItemDureeVieDefaut(demandeCalcul.getTypeItem().getDureeVieDefaut()) if (demandeCalcul.getTypeItem() != null) {
.valeur(demandeCalcul.getTypeItem().getDureeVieDefaut()) var dureeVieDefaut = demandeCalcul.getTypeItem().getDureeVieDefaut();
.sourceTypeItemDureeVieDefaut(demandeCalcul.getTypeItem().getSource())
.build()); if (dureeVieDefaut != null) {
Double duree = dureeVieDefaut < 1 ? 1 : dureeVieDefaut;
dureeDeVie.setDureeDeVieParDefaut(DureeDeVieParDefaut.builder()
.valeurTypeItemDureeVieDefaut(duree)
.valeur(duree)
.sourceTypeItemDureeVieDefaut(demandeCalcul.getTypeItem().getSource())
.build());
dureeDeVie.setValeurRetenue(duree);
return dureeDeVie;
}
}
// dureeInventaire est null
// typeItem est null
// recuperation duree de vie via hypothese 'dureeVieBatimentParDefaut'
var hypothese = demandeCalcul.getHypotheseFromCode("dureeVieBatimentParDefaut")
.orElseThrow(() -> new CalculImpactException(TypeErreurCalcul.ERREUR_FONCTIONNELLE.getCode(), "La durée de vie par défaut de l'item n'a pas pu être déterminée"));
} else if (refHypotheseOpt.isPresent() && refHypotheseOpt.get().getValeur() != null) { if (hypothese.getValeur() != null) {
ReferentielHypothese hypothese = refHypotheseOpt.get(); Double duree = hypothese.getValeur() < 1 ? 1 : hypothese.getValeur();
dureeDeVie.setDureeDeVieParDefaut(DureeDeVieParDefaut.builder() dureeDeVie.setDureeDeVieParDefaut(DureeDeVieParDefaut.builder()
.valeurReferentielHypothese(hypothese.getValeur()) .valeurReferentielHypothese(duree)
.sourceReferentielHypothese(hypothese.getSource()) .sourceReferentielHypothese(hypothese.getSource())
.valeur(hypothese.getValeur()) .valeur(duree)
.build()); .build());
} else {
throw new CalculImpactException(TypeErreurCalcul.ERREUR_FONCTIONNELLE.getCode(), "La durée de vie par défaut de l'item n'a pas pu être déterminée");
dureeDeVie.setValeurRetenue(duree);
} }
return dureeDeVie; return dureeDeVie;
} }
} }
...@@ -44,6 +44,7 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe ...@@ -44,6 +44,7 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe
} else { } else {
result.setDureeUsageAmont(0.0); result.setDureeUsageAmont(0.0);
} }
Double dureeUsageAval = demandeCalcul.getEquipementPhysique().getDureeUsageAval(); Double dureeUsageAval = demandeCalcul.getEquipementPhysique().getDureeUsageAval();
if (dureeUsageAval != null) { if (dureeUsageAval != null) {
if (dureeUsageAval < 0) { if (dureeUsageAval < 0) {
...@@ -62,36 +63,34 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe ...@@ -62,36 +63,34 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe
result.setMethodeDureeUsage("REEL"); result.setMethodeDureeUsage("REEL");
var dateAchat = demandeCalcul.getEquipementPhysique().getDateAchat(); var dateAchat = demandeCalcul.getEquipementPhysique().getDateAchat();
var dateRetrait = demandeCalcul.getEquipementPhysique().getDateRetrait(); var dateRetrait = demandeCalcul.getEquipementPhysique().getDateRetrait();
if (dateAchat != null && dateRetrait != null) {
if (dateAchat.isBefore(dateRetrait)) { if (dateAchat != null) {
Double valeur; // Si la date d'achat est présente et non la date de retrait, la date du jour devient la date de retrait pour le calcul
if ((double) ChronoUnit.MONTHS.between(dateAchat, dateRetrait) / 12 + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) { var dateRetraitReelle = dateRetrait == null ? LocalDate.now() : dateRetrait;
result.setValeurRetenue(1.0); if (!dateAchat.isBefore(dateRetraitReelle)) {
} else {
valeur = ChronoUnit.DAYS.between(dateAchat, dateRetrait) / 365d;
result.setValeurRetenue(result.getValeurRetenue() + valeur);
}
result.setDateAchat(dateAchat.format(DateTimeFormatter.ISO_DATE));
result.setDateRetrait(dateRetrait.format(DateTimeFormatter.ISO_DATE));
} else {
throw new CalculImpactException(TypeErreurCalcul.ERREUR_FONCTIONNELLE.getCode(), "La durée de vie de l'équipement n'a pas pu être déterminée"); throw new CalculImpactException(TypeErreurCalcul.ERREUR_FONCTIONNELLE.getCode(), "La durée de vie de l'équipement n'a pas pu être déterminée");
} }
}
// Taiga#864 - Si la date d'achat est présente et non la date de retrait, on prend la date du jour devient la date de retrait pour le calcul var dureeAnneeUtilisation = ChronoUnit.DAYS.between(dateAchat, dateRetraitReelle) / 365d;
else if (dateAchat != null) {
result.setValeurRetenue(result.getValeurRetenue() + if (dureeAnneeUtilisation + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
ChronoUnit.DAYS.between(dateAchat, LocalDate.now()) / 365d
);
result.setDateAchat(dateAchat.format(DateTimeFormatter.ISO_DATE));
result.setDateRetrait(LocalDate.now().format(DateTimeFormatter.ISO_DATE));
} else {
var dureeDeVieParDefaut = calculerDureeVieDefaut(demandeCalcul);
result.setDureeDeVieParDefaut(dureeDeVieParDefaut);
if (dureeDeVieParDefaut.getValeur() + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
result.setValeurRetenue(1.0); result.setValeurRetenue(1.0);
} else {
result.setValeurRetenue(result.getValeurRetenue() + dureeAnneeUtilisation);
} }
result.setValeurRetenue(result.getValeurRetenue() + dureeDeVieParDefaut.getValeur());
result.setDateAchat(dateAchat.format(DateTimeFormatter.ISO_DATE));
result.setDateRetrait(dateRetraitReelle.format(DateTimeFormatter.ISO_DATE));
return result;
} }
// dateAchat et dateRetrait sont null
var dureeDeVieParDefaut = calculerDureeVieDefaut(demandeCalcul);
result.setDureeDeVieParDefaut(dureeDeVieParDefaut);
if (dureeDeVieParDefaut.getValeur() + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
result.setValeurRetenue(1.0);
}
result.setValeurRetenue(result.getValeurRetenue() + dureeDeVieParDefaut.getValeur());
return result; return result;
} }
...@@ -109,14 +108,16 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe ...@@ -109,14 +108,16 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe
} else { } else {
result.setValeurRetenue(result.getValeurRetenue() + dureeUsageInterne); result.setValeurRetenue(result.getValeurRetenue() + dureeUsageInterne);
} }
return result;
}
// dureeUsageInterne est null
var dureeDeVieParDefaut = calculerDureeVieDefaut(demandeCalcul);
result.setDureeDeVieParDefaut(dureeDeVieParDefaut);
if (dureeDeVieParDefaut.getValeur() + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
result.setValeurRetenue(1.0);
} else { } else {
var dureeDeVieParDefaut = calculerDureeVieDefaut(demandeCalcul); result.setValeurRetenue(result.getValeurRetenue() + dureeDeVieParDefaut.getValeur());
result.setDureeDeVieParDefaut(dureeDeVieParDefaut);
if (dureeDeVieParDefaut.getValeur() + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
result.setValeurRetenue(1.0);
} else {
result.setValeurRetenue(result.getValeurRetenue() + dureeDeVieParDefaut.getValeur());
}
} }
return result; return result;
} }
......