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

Target

Select target project
  • pub/numeco/m4g/numecoeval
1 result
Show changes
Commits on Source (9)
Showing
with 159 additions and 86 deletions
......@@ -3,6 +3,10 @@
Tous les changements de ce projet seront documentés dans ce document.
## [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)
- 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)
......
......@@ -424,46 +424,58 @@ Elle est exprimée en années et autorise les décimales.
[pseudocode]
----
Règle RG_DureeVieItem(equipementPhysique,dureeVieItem,methodeDureeUsage) {
Règle RG_DureeVieItem(equipementPhysique) {
SI methodeDureeUsage=="REEL"
ALORS
'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
ALORS
SI (equipementPhysique.DateRetrait - equipementPhysique.DateAchat) < 1
ALORS RENVOYER (1 + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
SI ((equipementPhysique.DateRetrait - equipementPhysique.DateAchat) / 365 + equipementPhysique.dureeUsageAmont + equipementPhysique.dureeUsageAval < 1)
' 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)
'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
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
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
'par défaut, la méthode de calcul de la durée de vie est la méthode "FIXE"
SINON
'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
ALORS
SI (equipementPhysique.DureeUsageInterne<1)
ALORS RENVOYER (1 + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
SI (equipementPhysique.DureeUsageInterne + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
ALORS RENVOYER 1
SINON RENVOYER (equipementPhysique.DureeUsageInterne + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
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
}
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
SI operationNonIT.dureeDeVie est correcte et renseignée
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
SINON
RENVOYER RG_DureeVieItem_Defaut(operationNonIT)
SI RG_DureeVieItem_Defaut(operationNonIT) < 1
ALORS RENVOYER 1
SINON RENVOYER RG_DureeVieItem_Defaut(operationNonIT)
FIN SI
}
----
......@@ -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
x Ref_FacteurCaracterisation(refEquipementretenu, EtapeACV, Critere).valeur
/ RG_DureeVieEqP
/ RG_DureeVieItem_Defaut(equipementPhysique)
'conso electrique retenue est null
ind_ImpactEquipementPhysique.consoElecMoyenne = null
......@@ -854,7 +866,7 @@ Règle calculIndicateurImpactOperationNonIT(critere, etape, nomOrganisation, OpN
/ ref_Hypothese.valeur(CAPACITE_LIGNE_FIXE_LOCALISATION)
SINON SI OpNIT.categorie = "BATIMENT"
/ dureeDeVie
/ RG_DureeVieItem_Defaut(operationNonIT)
FIN SI
SINON SI OpNIT.categorie = "DEPLACEMENT_ELECTRIQUE" OU "DEPLACEMENT_ESSENCE" OU DEPLACEMENT_HYBRIDE
......
......@@ -69,7 +69,7 @@ class ConsoElecAnMoyenne {
}
class DureeDeVie {
Double valeur
Double valeurRetenue
private String methodeDureeUsage
private Double dureeUsageInterne
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;
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;;;;
......
......@@ -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;;
......
......@@ -2,7 +2,6 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/../../e2e/e2e.iml" filepath="$PROJECT_DIR$/../../e2e/e2e.iml" />
</modules>
</component>
</project>
\ No newline at end of file
......@@ -11,6 +11,7 @@
<option name="configurationPath" value="" />
<option name="exclusions">
<set>
<option value=".*\.adoc" />
<option value=".*\.yaml" />
<option value=".*\.yml" />
</set>
......
......@@ -5,12 +5,12 @@
<parent>
<groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>api-event-calculs</artifactId>
<name>api-event-calculs</name>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<description>api-event-calculs</description>
<repositories>
......
......@@ -5,12 +5,12 @@
<parent>
<groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>api-event-donneesEntrees</artifactId>
<name>api-event-donneesEntrees</name>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<description>api-event-donneesEntrees</description>
<repositories>
......
......@@ -5,11 +5,11 @@
<parent>
<groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>api-expositiondonneesentrees</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<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>
......
......@@ -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();
......
......@@ -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());
}
}
......@@ -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"
......@@ -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 @@
<parent>
<groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>api-referentiel</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<name>api-referentiel</name>
<description>API Referentiel - Lecture, chargement et exposition par API</description>
......
......@@ -5,11 +5,11 @@
<parent>
<groupId>org.mte.numecoeval</groupId>
<artifactId>core</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>calculs</artifactId>
<version>1.3.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<name>calculs</name>
<description>Module contenant l'intégralité des règles de calculs et du code métier lié aux calculs d'impact
d'équipement
......
......@@ -72,7 +72,9 @@ public class DemandeCalculImpactOperationNonIT {
return facteurCaracterisations.stream()
.filter(Objects::nonNull)
.filter(fc -> Constants.ELECTRICITY_MIX_CATEGORY.equals(fc.getCategorie()) &&
localisation.equals(fc.getLocalisation()))
localisation.equals(fc.getLocalisation()) &&
critere.getNomCritere().equals(fc.getCritere())
)
.findFirst();
}
......
......@@ -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.indicateurs.ImpactOperationNonIT;
import org.mte.numecoeval.calculs.domain.data.trace.DureeDeVie;
import org.mte.numecoeval.calculs.domain.exception.CalculImpactException;
public interface CalculImpactOperationNonITService {
ImpactOperationNonIT calculerImpactOperationNonIT(DemandeCalculImpactOperationNonIT demandeCalcul);
DureeDeVie getDureeVie(DemandeCalculImpactOperationNonIT demandeCalcul) throws CalculImpactException;
}
......@@ -119,7 +119,7 @@ public class CalculImpactOperationNonITServiceImpl implements CalculImpactOperat
}
MetadataCalcul metadataCalcul = getFormule(demandeCalcul);
DureeDeVie dureeDeVie = getDureeVie(demandeCalcul);
Double dureeDeVieValeur = (dureeDeVie.getValeurRetenue() == null) ? dureeDeVie.getDureeDeVieParDefaut().getValeur() : dureeDeVie.getValeurRetenue();
Double dureeDeVieValeur = dureeDeVie.getValeurRetenue();
Double valeurImpactUnitaire = metadataCalcul.valeurImpactUnitaire() / dureeDeVieValeur;
TraceCalculImpactOperationNonIT traceCalculImpactOperationNonIT = metadataCalcul.traceCalculImpactOperationNonIT();
String traceFormuleBase = traceCalculImpactOperationNonIT.getFormule();
......@@ -320,33 +320,53 @@ public class CalculImpactOperationNonITServiceImpl implements CalculImpactOperat
*
* @param demandeCalcul la demande de calcul
* @return dureeDeVie
* @throws CalculImpactException
* @throws CalculImpactException sinon
*/
public DureeDeVie getDureeVie(DemandeCalculImpactOperationNonIT demandeCalcul) throws CalculImpactException {
var refHypotheseOpt = demandeCalcul.getHypotheseFromCode("dureeVieBatimentParDefaut");
var dureeDeVie = DureeDeVie.builder().build();
if (demandeCalcul.getOperationNonIT().getDureeDeVie() != null) {
dureeDeVie.setValeurRetenue(demandeCalcul.getOperationNonIT().getDureeDeVie());
Double dureeInventaire = demandeCalcul.getOperationNonIT().getDureeDeVie();
if (dureeInventaire != null) {
dureeDeVie.setValeurRetenue(dureeInventaire < 1 ? 1.0 : dureeInventaire);
return dureeDeVie;
}
} else if (demandeCalcul.getTypeItem() != null && demandeCalcul.getTypeItem().getDureeVieDefaut() != null) {
dureeDeVie.setDureeDeVieParDefaut(DureeDeVieParDefaut.builder()
.valeurTypeItemDureeVieDefaut(demandeCalcul.getTypeItem().getDureeVieDefaut())
.valeur(demandeCalcul.getTypeItem().getDureeVieDefaut())
.sourceTypeItemDureeVieDefaut(demandeCalcul.getTypeItem().getSource())
.build());
// dureeInventaire est null
// recuperation duree de vie via typeItem
if (demandeCalcul.getTypeItem() != null) {
var dureeVieDefaut = demandeCalcul.getTypeItem().getDureeVieDefaut();
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) {
ReferentielHypothese hypothese = refHypotheseOpt.get();
if (hypothese.getValeur() != null) {
Double duree = hypothese.getValeur() < 1 ? 1 : hypothese.getValeur();
dureeDeVie.setDureeDeVieParDefaut(DureeDeVieParDefaut.builder()
.valeurReferentielHypothese(hypothese.getValeur())
.valeurReferentielHypothese(duree)
.sourceReferentielHypothese(hypothese.getSource())
.valeur(hypothese.getValeur())
.valeur(duree)
.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;
}
}
......@@ -44,6 +44,7 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe
} else {
result.setDureeUsageAmont(0.0);
}
Double dureeUsageAval = demandeCalcul.getEquipementPhysique().getDureeUsageAval();
if (dureeUsageAval != null) {
if (dureeUsageAval < 0) {
......@@ -62,36 +63,34 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe
result.setMethodeDureeUsage("REEL");
var dateAchat = demandeCalcul.getEquipementPhysique().getDateAchat();
var dateRetrait = demandeCalcul.getEquipementPhysique().getDateRetrait();
if (dateAchat != null && dateRetrait != null) {
if (dateAchat.isBefore(dateRetrait)) {
Double valeur;
if ((double) ChronoUnit.MONTHS.between(dateAchat, dateRetrait) / 12 + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
result.setValeurRetenue(1.0);
} 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 {
if (dateAchat != null) {
// 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
var dateRetraitReelle = dateRetrait == null ? LocalDate.now() : dateRetrait;
if (!dateAchat.isBefore(dateRetraitReelle)) {
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
else if (dateAchat != null) {
result.setValeurRetenue(result.getValeurRetenue() +
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) {
var dureeAnneeUtilisation = ChronoUnit.DAYS.between(dateAchat, dateRetraitReelle) / 365d;
if (dureeAnneeUtilisation + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
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;
}
......@@ -109,14 +108,16 @@ public class DureeDeVieEquipementPhysiqueServiceImpl implements DureeDeVieEquipe
} else {
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 {
var dureeDeVieParDefaut = calculerDureeVieDefaut(demandeCalcul);
result.setDureeDeVieParDefaut(dureeDeVieParDefaut);
if (dureeDeVieParDefaut.getValeur() + result.getDureeUsageAmont() + result.getDureeUsageAval() < 1) {
result.setValeurRetenue(1.0);
} else {
result.setValeurRetenue(result.getValeurRetenue() + dureeDeVieParDefaut.getValeur());
}
result.setValeurRetenue(result.getValeurRetenue() + dureeDeVieParDefaut.getValeur());
}
return result;
}
......