= Spcécification des règles de calcul de G4IT
:toc:
:toclevels: 4 
:sectnums:

== Historique des modifications
|===
|type de changement|date|type de modification
|majeur|28/06/2022|Création du document
|majeur|Avril 2023|Ouverture en Open Source
|majeur|01/02/2023|Partage des équipements entre les contextes personnels et professionnels (changement règles de calculs avec le tauxUtilisation & modeUtilisation)
|majeur|22/02/2023|Intégrer des nouveaux impact au référentiel(déplacements collaborateurs, bâtiments) -> Création d'une nouvelle API facteurscaracterisation
|majeur|02/05/2023|Charger et lancer un calcul sur les nouveaux impacts (réseau, déplacements, bâtiments, maintenance) -> import de nouveaux csv OperationNonIT puis création d'indicateurs associés
|majeur|17/05/2023|Inclure dans l'évaluation d'impact des informations sur la qualité des données -> ajout d'un champ qualité à l'import puis transmission de la qualité jusqu'aux indicateurs en sortie

|===

[#_documents_de_reference]
== Documents de référence

|===
|identifiant|intitulé du document|source
|1|G4IT|Sopra Steria
|2|Référentiel services numériques_v1.0_FR|ADEME|Principes généraux pour
l’affichage environnemental des produits de grande consommation
|3|WeNR Methodology Note|weNR - https://wenr.isit-europe.org/wenr-methodology-note/|méthode de calcul
|4|BOAVIZTA|https://boavizta.org/
|===

== Introduction

NumEcoEval est une solution permettant, à partir de données de dimensionnement du SI et de données de références, de calculer l’empreinte environnementale d'un système d'information.
Cet outil open source a été initialisé à partir des travaux de Sopra Steria [1], de l’ADEME [2],  de l’INR [3], de BOAVIZTA [4] (cf.Documents de référence), avec la contribution d'IJO. 
Cet outil vise à déployer massivement le calcul de l'empreinte environnementale d'un système d'information au sein d'une organisation, en connectant NumEcoEval directement aux sources de données standard de celle-ci (notamment ses CMDB).
Le volume de données pouvant être important, une attention particulière a donc été apportée à la performance de l'outil et explique certains choix d'architecture (notamment l'utilisation de l'asynchronisme).

== Description des principaux concepts

[#_analyse_de_cycle_de_vie]
=== Analyse de cycle de vie
Notre approche s’inspire des méthodes d'Analyse de Cycle de Vie (ACV), cadrées par les normes ISO 14040 et 14044. Ces normes structurent l’analyse d’impact tout au long du cycle de vie d’un produit ou d'un service. L’application de ces normes à un service numérique est encore jeune mais est à ce jour l’approche la plus poussée et celle retenue par les groupes de travail liés à la règlementation (AGEC).
NumEcoEval a été conçu pour pouvoir intégrer d'autres étapes du cycle de vie des produits selon les besoins des organisations, sous réserve que les données disponilbles et/ou les standards évoluent dans ce sens.

4 étapes du cycle de vie d'un produit sont retenues actuellement :

image::cycle_de_vie.jpg[]

|===
|Étape du cycle de vie |Traduction anglaise |description
|Fabrication|Build|Phase de fabrication d'un composant de l'extraction des matières premières à la fin de sa phase de fabrication.
|Utilisation|Use|Phase d'utilisation d'un équipement
|Fin de vie|End Of Life (EOL)| Phase de fin de vie et de recyclage d'un équipement
|Distribution|Dist| Phase d'acheminement du produit et des matières
|===

[#_criteres_dimpacts_environnementaux]
=== Critères d'impacts environnementaux
Les critères d'impact correspondent aux types d'impact environnementaux suivis par l'outil.
Sont retenus actuellement les critères décris dans la PCR Service Numérique ([1] des <<_documents_de_reference>>) comme obligatoire :

* Épuisement des ressources naturelles (minérales et métaux)
* Changement climatique
* Acidification
* Émissions de particules fines
* Radiations ionisantes
* Consommation d’énergie primaire (indicateur de flux - complémentaire)

Le raisonnement multicritère est important car il permet d'éviter les transferts d'impact lors de la planifaction du plan d'action suivant l'acte de mesure de l'empreinte.
Comme pour les étapes ACV, ce moteur de calcul permet nativement l'ajout d'autres critères d'impact environnementaux.

[#_Organisation]
=== L'Organisation
L'organisation regroupe l'ensemble des tiers utilisant NumEcoEval appartenant à une même structure. Une organisation peut contenir différentes entités.

.Exemple
Le Ministère de la Transition Écologique et de la Cohésion des Territoires est une organisation qui sollicite NumEcoEval pour calculer l'empreinte environnementale de son SI.

[#_architecture_fonctionnelle]
== Architecture fonctionnelle de la solution

image::architecture_fonctionnelle_simplifiee_V1.png[]

Comme indiqué dans le schéma d'architecture fonctionnel simplifié ci-dessus, il convient de distinguer différents types de données :

* Les *données brutes* : ce sont les données stockées sans transformation, sous des formes très différentes, dans les outils d'une organisation. Ces données peuvent être statiques (elles ne varient pas ou peu et sont valables à l'échelle d'un an) ou dynamiques (elles varient souvent et doivent être mesurées régulièrement). Elle sont fournies par des sondes, des API... et ne sont pas structurées au format G4IT.
* Les *données d'entrées* :  ce sont les données normalisées (format NumEcoEval), capables d'être comprises par G4IT et peuvent être interprétées par l'outil pour faire ses calculs. Ces données sont donc généralement issues de la transformation des données brutes (traduction, redressement, nettoyage...).
* Les *indicateurs* : ce sont les données pouvant être affichées dans les dashboards SuperSet. Elles sont généralement calculées via les règles présentes dans ce document (exemple : impact en CO2 eq d'un équipement) ou sont issues des données brutes (exemple : nombre d'équipements). Ces indicateurs sont de deux types :

	** Stratégiques : ils permettent au DSI ou aux sponsors des domaines d'avoir l'état de lieux et de fixer les objectifs
    ** Opérationnels : ils permettent au responsable de secteur et AMOE de mettre en place les actions sur leur périmètre.

* Les *références* : ce sont les données normalisées (format NumEcoEval), qui servent de base aux calculs des impacts pour les différentes phases du cycle de vie d'un équipement (cf. <<_analyse_de_cycle_de_vie>>) et pour les différents critères (cf. <<_criteres_dimpacts_environnementaux>>). Ces données peuvent provenir de base de référence externes (NegaOCtet, Base Impact de l'ADEME, base BOAVIZTA...), ou peuvent être calculées par le client (exemple : calcul de la consommation électrique moyenne annuelle d'un équipement).

== Description des Modules

=== Bloc Références
[#_donnees_de_reference]
==== Données de référence

Les données de références correspondent aux données qui ne proviennent pas directement de l'organisation (<<_Organisation>>) souhaitant utiliser NumEcoEval. Ces données peuvent être issues de la littérature scientifique, de bases de données de références externes et reconnues (NegaOctet, Base IMPACT de l'ADEME, bases de données BOAVIZTA...), ou issues de travaux empiriques. Ces données doivent nécessairement être sourcées pour assurer la traçabilité des calculs.

Le tableau suivant permet de connaitre les données de référence utilisées dans les différentes règles de calcul. Ces données seront précédées du préfixe "ref_" suivi d'une suite de lettre permettant d'identifier la table concernée.

exemple :
|===
|Identifiant|Description des données
|ref_Critere|Précise les critères pris en charges par l'outil, leur unité et d'autres informations qui leurs sont associées.
|ref_Etape|Précise les étapes du cycle de vie prises en charge par l'outil.
|ref_Hypothese |Précise les hypothèses nécessaires à certains calculs des indicateurs (par exemple les données par défaut)
|ref_TypeItem |Précise les types d'items autorisés et leur durée de vie par défaut
|ref_CorrespondanceRefEqP|Donne la correspondance entre les équipements présents dans les données d'entrées et les équipements de références présents dans la table Ref_FacteurCaracterisation
|ref_FacteursCaracterisation|Donne l'impact environnemental de différents items selon le critère (<<_criteres_dimpacts_environnementaux>>) et l'étape du cycle de vie (<<_analyse_de_cycle_de_vie>>). Par exemple, il peut s'agir de l'impact sur le changement climatique d'une certaine configuration de serveur à la fabrication.

|===

**Pour chaque type d'objet, des endpoints de CRUD (Create/Read/Update/Delete) sont disponibles**

Le format de ces références est contraint pour garantir la capacité du moteur de calul (cf.<<_moteur_de_calcul>>) à produire les indicateurs.

link:./References.plantuml[Diagramme de classe des référentiels]

Toutes ces données sont nécessaires au calcul des règles d'impact. Elles doivent être chargées par un administrateur NumEcoEval avant d'intégrer les données d'entrée.

**Précisions sur l'import CSV de certains référentiels**


Les API permettant d'importer de nouvelles données et d'exporter les références existantes sont décrites https://gitlab-forge.din.developpement-durable.gouv.fr/pub/numeco/m4g/numecoeval/-/blob/develop/services/common/src/main/resources/static/api-referentiels-openapi.yaml?ref_type=heads[ici].

**Points d'attention **

- Par construction, une suppression sur le référentiel ref_EtapeACV supprime les référentiels référençant cette étape : ref_facteursCaracterisation et ref_ImpactMessagerie.
- Par construction, un import CSV sur le référentiel ref_EtapeACV supprime les référentiels référençant les étapes : ref_facteursCaracterisation et ref_ImpactMessagerie.
- Par construction, une suppression sur le référentiel ref_Critere supprime les référentiels référençant le critère : ref_facteursCaracterisation et ref_ImpactMessagerie.
- Par construction, un import CSV sur le référentiel ref_Critere supprime les référentiels référençant les critères : ref_facteursCaracterisation et ref_ImpactMessagerie.

==== Précision sur les hypothèses
Les hypothèses de travail se trouvent dans la table "Hypothèses".
Elles sont uniques pour une clé donnée.
À l'usage dans la suite du document, une hypothèse peut être retrouvée via la formule :
`ref_Hypothese(<clé d'hypothèse>)`

.Exemple d'hypothèses :
|===
|clé|valeur|source | description
|dureeVieParDefaut|1| dans le cas où la durée de vie d'un type d'équipement ne serait pas renseignée, on considère une hypothèse majorante d'une mise a rebut de l'équipement au bout de 1 an.|
|===

[#_api_donnees_dentrees]
=== API pour les données d'entrées

L'API pour les données d'entrées permet d'importer des données dans le système NumEcoEval via des endpoints REST.

Toutes les informations reçues sont envoyées simultanément :
- Au bloc Données d'entrées pour historisation des données reçues si le module est activé
- Au bloc Calcul afin de produire les indicateurs issus des règles de calculs décrites dans ce document.

==== Endpoints de l'API

Les données de ce bloc sont exposées via les points suivants :
|===
|Endpoint API REST|Description|Paramètres|Sortie
|POST /entrees/csv|Envoi d'un objet en_DonneesEntree aux blocs Calculs (et enregistre ces Données Entrées si ce bloc "donnée d'entrée) est activé) | Les fichiers CSV correspondant aux différentes classes présentes dans les données d'entrée (équipement physiques, virtuels, datacenter...) 
|Rapports par fichier CSV contenant le nombre de lignes en erreur, le nombre d'objets intégrés, la liste des erreurs par lignes).
|===

=== Bloc Données d'entrées (optionnel)
Ce bloc est optionnel, il n'est pas nécessaire au calcul des indicateurs mais il permet d'historiser les données de dimensionnement de l'organisation, permettant de réaliser des rejeux de calculs et de connaitre les valeurs utilisé à un instant t.

[#_donnees_dentrees]
==== Données d'entrées

Les données d'entrée du sytème se trouvent dans la base "Entree".
Dans la spécification, les objets représentant des données d'entrées sont précédées du préfixe "en_"
et sont classées en 5 catégories :

* en_EqP: liste des équipements physiques (type d'équipement)
* en_EqV : liste des équipements virtuels (vCPU, équipement physique sous jacent...)
* en_DC : liste des datacenters (identification, PUE)
* en_App : liste des applications
* en_OperationsNonIT: liste des opérationsNonIT (réseau, déplacements, bâtiments, maintenance)

Tous ces objets sont groupés dans un objet en_DonneesEntree avant d'être envoyés dans l'outil.
Dans un premier temps, il est possible d'envoyer les objets par groupes.

le format de ces données d'entrée est contraint pour garantir la capacité du moteur de calul (cf.<<_moteur_de_calcul>>) à produire les indicateurs/
link:./DonneeEntree.plantuml[Diagramme de classe des entrées]

[#_bloc_calcul]
=== Bloc Calcul
Ce bloc représente le coeur de métier de la solution NumEcoEval.
Il permet de produire des indicateurs en se basant sur :

* Les référentiels exposés par le bloc Références (comprenant les critères, les étapes ACV, les hypothèses,... cf. <<_donnees_de_reference>>)
* Les données d'entrées reçues via un objet en_DonneesEntree : cf <<_donnees_dentrees>>

Le moteur de calcul permet d'intégrer toutes les règles de calcul (<<_regles_de_calcul>>) qui se basent sur les données de références et les données d'entrées.
Il permet de calculer des indicateurs qui pourront ensuite être utilisés unitairement ou associés entre eux pour fournir une vision de l'empreinte environnementale d'un périmètre et aider les utilisateurs à piloter leurs plans d'action.

cf.<<_moteur_de_calcul>>

[#_bloc_indicateurs]
=== Bloc Indicateurs
==== Historisation des indicateurs

Ce module permet d'historiser les indicateurs produits par le bloc de calcul.
Les indicateurs sont stockés dans des tables dédiées.

Tous les indicateurs sont autoporteurs, c'est-à-dire qu'ils sont compréhensibles et apportent de la valeur unitairement : ils font référence à un seul critère et une seule étape ACV, et la valeur de l'indicateur est toujours couplée avec une unité.

link:./Indicateurs.plantuml[Diagramme de classes des indicateurs]

==== Exposition du bloc

Le bloc Indicateurs expose les points suivants :
|===
|Méthode d'exposition dans la spécification|Description|Paramètres|Sortie
|[[sauvegarder_impact]]sauvegarder_impact(ind_Impact)|Persiste un objet ind_Impact (ou une des classes filles) en base de données|L'objet ind_Impact à sauvegarder en base de données| Aucunes
|===


[#_cles_de_lecture]
== Clés de lectures du pseudocode

* Pour faciliter la lecture des règles de calcul, chaque donnée est préfixée selon le module à laquelle elle appartient :
** Les données en entrée du système sont préfixées par en_
** Les données de référence sont préfixées par ref_ 

* Les objects manipulés ont la forme suivante  `nomDeClasse nomObjet`
** Exemple : `en_EqP EqP` indique qu'un objet `EqP` de classe `en_EqP` est disponible

* Pour les référentiels et les hypothèses : les éléments entre `()` correspondent aux clés uniques de lecture
** Exemples:
*** `ref_Hypothese(dureeVieParDefaut)` correspond à utiliser l'API GET /referentiels/hypotheses?cle={cle} avec la clé `dureeVieParDefaut` (cf.<<GET_Hypotheses>>)
pour obtenir l'objet ref_Hypothese correspondant
*** `ref_facteurCaracterisation(nom,etape,critere)` (cf.<<GET_FacteursCaracterisation>>) correspond à utiliser l'API GET /referentiels/facteursCaracterisation?nom={nomFacteurCaracterisation}&etapeacv={etapeacv}&critere={critere}& avec les paramètres `Etape`,`Critere` et `Nom` correspondants

* Le "." derrière un objet (déclaré ou obtenu après une méthode d'exposition) indique l'accès à un attribut de l'objet.
** Exemples :
*** `ref_Hypothese(dureeVieParDefaut).valeur` correspond au champ valeur de l'objet ref_Hypothese de clé `dureeVieParDefaut`
*** `ref_facteurCaracterisation(nom,etape,critere).valeur` correspond au champ valeur de l'objet ref_FacteurCaracterisation correspondant à `Etape`,`Critere` et `Nom`

* Tous les indicateurs créés sont enregistrés en base de données grâce à la méthode sauvegarder_impact(ImpactUnitaire) : cf.<<sauvegarder_impact>>


[#_moteur_de_calcul]
== Moteur de calcul

Le déclenchement des règles présentes dans le Bloc Calcul se réalise à la soumission des calculs sur un lot donné via le endpoint POST /entrees/calculs/soumission.

Le body de la requête est composé :

* du nomLot : qui permet de récupérer toutes les données d'entrées liées à cette demande de calcul
* d'une liste d'étapes facultative : permet de lancer le calcul uniquement sur un sous-ensemble d'étapes présentes dans les références. Si la liste n'est pas renseignée, alors on ne filtre pas (on lance le calcul sur toutes les étapes présentes dans la table ref_etapeacv)
* d'une liste de critères facultative : permet de lancer le calcul uniquement sur un sous-ensemble de critères présents dans les références. Si la liste n'est pas renseignée, alors on ne filtre pas (on lance le calcul sur tous les critères présents dans la table ref_critere)

Il existe 2 paramètres associés à cette requête :

* mode : le mode de traitement, SYNC ou ASYNC (ASYNC est la valeur par défaut)
* dureeUsage : la méthode de calcul de la durée de vie des équipements physiques utilisée, qui peut être 
** FIXE (valeur par defaut): la méthode de calcul de la durée de vie se base sur l'attribut 'dureeUsageInterne' de l'équipement physique
** REEL : la méthode de calcul de la durée de vie se base sur l'âge réel de l'équipement physique (dateRetrait-dateAchat quand les données sont disponibles) 

NumEcoEval effectue alors les calculs des indicateurs et les sauvegardes dans la base correspondante.

La cinématique globale est décrite ci-dessous :

image::cinématique.png[]

Voici l'algorithme général permettant le caclul des indicateurs

pseudocode
----
CalculDesIndicateurs(en_DonneesEntree) {
	List<ref_EtapeACV> etapes = GET /referentiels/etapes;
	SI en_DonneesEntree.etapesDemandees est renseigné
		ALORS mettre à jour la liste etapes pour ne contenir que les étapes demandées
	FIN SI

	List<ref_Critere> criteres = GET /referentiels/criteres;
	SI en_DonneesEntree.criteresDemandees est renseigné
		ALORS mettre à jour la liste criteres pour ne contenir que les critères demandés
	FIN SI

    BOUCLE SUR CHAQUE etape DE LA LISTE ref_EtapeACV
        BOUCLE SUR CHAQUE criteres DE LA LISTE ref_Critere

			initialisation d'un compteur d'impact applicatif

			BOUCLE SUR CHAQUE en_EqP de en_DonneesEntree
				// Exécutions des règles sur les équipements physiques
				calculIndicateurImpactEquipementPhysique(etape, critere, en_DonneesEntree.nomOrganisation, en_EqP, en_DC, ind_ImpactEquipementPhysique)

				SI en_EqP.type est un serveur (ref_TypeItem.serveur est vrai)
					ALORS initialisation de la variable NbvCPU correspondant à la SOMME des vCPU de tous les équipements virtuels de l'équipement physique si ce dernier est renseigné ou à l'équipement physique dans le cas contraire
					ET initialisation de la variable stockageTotalVirtuel correspondant à la SOMME des capaciteStockage de tous les équipements virtuels de l'équipement physique si ce dernier est renseigné ou à l'équipement physique dans le cas contraire
					ET initialisation de la variable nbEqV correspondant au nombre de équipements virtuels de l'équipement physique si ce dernier est renseigné ou à l'équipement physique dans le cas contraire
					ET initialisation du bouléen vCPUoK indiquant que l'ensemble des équipements virtuels de l'équipement physique (si ce dernier est renseigné ou à l'équipement physique dans le cas contraire) possède un vCPU renseigné, entier et > à 0
					ET initialisation du bouléen stockoK indiquant que l'ensemble des équipements virtuels de l'équipement physique (si ce dernier est renseigné ou à l'équipement physique dans le cas contraire) possède un vCPU renseigné, entier et > à 0

					Soit ImpactEqP = ind_ImpactEquipementPhysique.ImpactUnitaire/ind_ImpactEquipementPhysique.quantite calculé dans cette boucle
					Soit ConsoElecEqP = ind_ImpactEquipementPhysique.consoElecMoyenne/ind_ImpactEquipementPhysique.quantite calculé dans cette boucle calculée dans cette boucle

					BOUCLE SUR CHAQUE en_EqV DE en_DonneesEntree dont l'équipement physique (en_EqV.nomEquipementPhysique) correspond à celui traité dans cette boucle
						
						ind_ImpactEquipementVirtuel = calculIndicateurImpactEquipementVirtuel(etape, critere, en_EqV, ImpactEqP, ConsoElecEqP, NbvCPU, nbEqV, vCPUoK, stockageTotalVirtuel, stockoK, ind_ImpactEquipement)
						
						// Calcul des impacts applicatifs : ils correspondent, pour l'impact unitaire, à la somme des impacts unitaires des équipements virtuels d'une application pour un type d'environnement, un critere et une étape ACV, et, pour la consommation electrique, à la somme des consommations électriques des équipements virtuels sous jacent.
						BOUCLE SUR CHAQUE en_App  DE en_DonneesEntree pour en_App.nomEquipementVirtuel = en_EqV.nomEquipementVirtuel
							SI AUCUN impact applicatif n'a été enregistré pour en_App.nomApplication, en_App.typEnvironnement, en_App.critere et en_App.etapeACV
								ALORS ENREGISRER l'impact applicatif
							SINON 
								AJOUTER ind_ImpactEquipementVirtuel à l'impact applicatif précedemment enregirsté 
							FIN SI

						FIN BOUCLE
					FIN BOUCLE			
				FIN SI

				// Calcul de l'impact réseau associé à ces équipements
				CalculImpactReseau(en_EqP, etape, critere, ind_ImpactReseau)
			
			FIN BOUCLE

			BOUCLE SUR CHAQUE en_OpNIT de en_DonneesEntree
				// Exécutions des règles sur les opérations non IT
				calculIndicateurImpactOperationNonIT(etape, critere, en_DonneesEntree.nomOrganisation, en_OpNIT, ind_ImpactOperationNonIT)
			FIN BOUCLE

        FIN BOUCLE

    FIN BOUCLE

    // Messagerie
	BOUCLE SUR CHAQUE critere DE LA LISTE ref_Critere
		SI ref_ImpactMessagerie.critere EXISTE pour le ref_Critere en cours
			BOUCLE SUR CHAQUE en_Messagerie DE LA LISTE en_DonneesEntree.messageries
				calculImpactMessagerie(en_Messagerie, critere, ref_ImpactMessagerie, ind_ImpactMessagerie)
			FIN BOUCLE
		FIN SI
	FIN BOUCLE

	SAUVERGARDER les indicateurs d'impact applicatif une fois l'ensemble des boucles terminées.
}
----

Liens vers les principaux éléments de cet algorithme

* <<GET_Etapes>>
* <<GET_Criteres>>
* <<_regles_de_calcul>>
** <<_calcul_impact_EqP_unitaire>>
** <<_calcul_impact_EqV_unitaire>>
** <<_calculIndicateurImpactApplicatif>>
** <<_calcul_impact_OperationNonIT_unitaire>>
** <<_calculImpactMessagerie>>




[#_regles_de_calcul]
== Règles de calcul

=== Règles Générales

[#_rg_transfertdonnees]
==== Transfert de données

Certaines données reçues via les données d'entrées sont des données transmises
en mode "passe-plat" de l'entrée jusqu'aux indicateurs.
Ces données servent divers objectifs tels que :

- Le regroupement des indicateurs par lot
- La recherche dans les indicateurs
- Permettre d'agréger les données qui concernent une même catégorie (Organisation, entité, type d'équipement...)
- Les traces

Les champs de même nom dans les objets d'entrées (en_*) et les objets indicateurs (ind_*)
doivent être transmis à l'identique sans traitement particulier par le moteur de calcul.

Les champs concernés sont les suivants :

|===
|Nom du champ|Obligatoire|Objet Source|Objet de Sortie|Description et usage
|dateLot|Facultatif|en_DonneesEntree|Tous les objets indicateurs|Date du lot de rattachement des données, permet de regrouper les données d'indicateurs. Définit une seule fois pour tous les objets.
|nomOrganisation|Obligatoire|en_DonneesEntree|Tous les objets indicateurs|Nom de l'organisation rattachée aux données, permet de regrouper les données d'indicateurs. Définit une seule fois pour tous les objets.
|nomEntite|Facultatif|Tous les objets d'entrées|Objets indicateurs du même niveau|Nom de l'entité responsable pouvant agir sur l'objet. Elle est définie dans les données d'entrées et alimente les indicateurs associés.
|qualité|Facultatif|en_DonneesEntree|Tous les objets indicateurs|Qualité des données d'inventaire afin de connaître la précision du cadre de l'étude et les hypothèses prises.
|===



[#_rg_traceCalcul]
==== RG_TraceCalcul

Pour chaque calcul produisant un indicateur (classe héritant de ind_Impact),
le moteur de calcul produit une trace représentée par un objet d'une des classes suivantes :

- TraceCalculImpactEquipementPhysique : la trace du calcul d'impact d'équipement physique cf. <<_calcul_impact_EqP_unitaire>>
- TraceCalculImpactEquipementVirtuel : la trace du calcul d'impact d'équipement virtuel cf. <<_calcul_impact_EqV_unitaire>>
- TraceCalculOperationNonIT : la trace du calcul d'une opération non IT cf. <<_calcul_impact_OperationNonIT_unitaire>>
- TraceCalculImpactMessagerie : la trace du calcul d'impact de la messagerie cf. <<_calculImpactMessagerie>>

Tous les objets de trace de calcul possèdent un champ "formule" permettant de vérifier le calcul de l'impact.
La formule se présente comme un calcul mathématique avec le nom des variables et leurs valeurs entre parenthèses.

_Exemple de valeur pour le champ formule :_
`ImpactEquipementPhysique = (Quantité(1.0) * ConsoElecAnMoyenne(29.198638586342973) * MixElectrique(0.0813225) * NbJourUtiliseAn(365.0) * tauxUtilisation(1.0)) / 365`

_Les formules originales (sans variable) sont visibles dans les différentes règles de calcul._

En fonction des règles concernées, des champs supplémentaires sont alimentés pour faciliter la vérification.

link:./Traces.plantuml[Diagramme de classes des objets relatifs aux traces]


[#_rg_dureevieitem]
==== RG_DureeVieItem : durée de vie d'un item (équipement physique, bâtiment...)

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle à dire d'expert
|===

La durée de vie d'un item détermine la manière dont est amortie l'impact de sa fabrication.
Elle est exprimée en années et autorise les décimales.


|===
|parametre|entree/sortie|Description
|item|entrée|L'item dont on cherche à calculer la durée de vie
|dureeVieItem|sortie|La durée de vie de l'item
|===

[pseudocode]
----
Règle RG_DureeVieItem(equipementPhysique, dureeVieItem) {

	SI methodeDureeUsage=="REEL"
	ALORS
		'dans le cas où il est possible de calculer l'age réel de l'item (c'est à dire sa durée de vie au sein de l'organisation), 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) / 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 pour éviter d'avoir un impact supérieur à l'impact total de l'équipement sur l'ensemble de son cycle de vie
			'En effet : impact = facteurCaracterisation/dureeDeVie. Si la dureeDeVie est inférieure à 1, alors impact > facteurCaracterisation de l'équipement.
			ALORS dureeVieItem = 1
			SINON dureeVieItem= (((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 renseignée
			SI ((equipementPhysique.DateRetrait - date du jour) / 365 + equipementPhysique.dureeUsageAmont + equipementPhysique.dureeUsageAval < 1)
			ALORS dureeVieItem= 1
			SINON dureeVieItem= (((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
			SI (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
			ALORS dureeVieItem= 1
			SINON dureeVieItem= (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 + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
			ALORS dureeVieItem= 1
			SINON dureeVieItem= (equipementPhysique.DureeUsageInterne + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
		SINON
			SI (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval < 1)
			ALORS dureeVieItem= 1
			SINON dureeVieItem= (RG_DureeVieItem_Defaut(equipementPhysique) + equipementPhysique.DureeUsageAmont + equipementPhysique.DureeUsageAval)
		FIN SI
	FIN SI
}

Règle RG_DureeVieItem(operationNonIT, dureeVieItem) {

	'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
		SI operationNonIT.dureeDeVie < 1
		ALORS dureeVieItem= 1
		SINON dureeVieItem= operationNonIT.dureeDeVie
	'dans les autres cas, une durée de vie moyenne de l'équipement est déduite
	SINON
		SI RG_DureeVieItem_Defaut(operationNonIT) < 1
		ALORS dureeVieItem= 1
		SINON dureeVieItem= RG_DureeVieItem_Defaut(operationNonIT)
	FIN SI
}
----

cf.<<_rg_dureevieitem_defaut>>

[#_rg_dureevieitem_defaut]
==== RG_DureeVieItem_Defaut : durée de vie des items par défaut

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle à dire d'expert
|===

La durée de vie des items peut être déterminée par défaut dans le cas où l'âge réel ne serait pas renseigné. Elle est alors calculée sur la base suivante :

|===
|paramètre|entree/sortie|Description
|item|entrée|L'item dont on cherche à calculer la durée de Vie par défaut
|dureeVieItem_Defaut|sortie|La durée de vie par défaut de l'item
|===

[pseudocode]
----
Règle RG_DureeVieItem_Defaut(Item, dureeVieItem_Defaut) {
		'la durée de vie par défaut des items est celle renseignée dans la table des types d'items
		SI l'item en entrée est présent dans la table des références d'items (si Item.type = ref_TypeItem.nom)
			ALORS dureeVieItem_Defaut= ref_TypeItem.dureeVieDefaut
		'on retient l'hypothèse d'une durée de vie par défaut des items égale à la durée de vie des items enregistrés dans les hypothèses
		SINON (SI Item='equipementPhysique' ET SI ref_Hypothese(dureeVieParDefaut) existe)
			ALORS dureeVieItem_Defaut= ref_Hypothese(dureeVieParDefaut).valeur
		SINON (SI Item='operationNonIT' ET SI ref_Hypothese(dureeVieBatimentParDefaut) existe)
			ALORS dureeVieItem_Defaut= ref_Hypothese(dureeVieBatimentParDefaut).valeur
		SINON
			ErrCalcul("la durée de vie par défaut de l'item n'a pas pu être déterminée")
		FIN SI
}
----

[#_rg_correspondance_RefEquipement]
==== RG Correspondance entre les équipements et leur références :

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle
|===

Cette règle permet de retrouver l'équipement de référence, c'est à dire celui dont les facteurs d'impact seront utilisés afin d'évaluer l'impact de l'équipement en cours de traitement.

|===
|paramètre|entree/sortie|Description
|organisation|entrée|l'organisation en cours de traitement
|equipement|entrée|l'équipement dont on cherche la référence
|refEquipementRetenu|sortie|l'équipement dont l'impact servira de référence
|===

[pseudocode]
----
Règle RG_correspondanceRefEquipement(equipement, refEquipementRetenu) { 
	
		SI ref_CorrespondanceRefEqP(equipement.modele) existe 
			refEquipementRetenu= ref_CorrespondanceRefEqP(equipement.modele).refEquipementCible
		SINON SI ref_TypeItem(equipement.type).refEquipementParDefaut existe 
			refEquipementRetenu= ref_TypeItem(equipement.type).refEquipementParDefaut 
		SINON
			ErrCalcul("aucune correspondance avec un équipement de référence n'a pu être déterminée")
		FIN SI

}
----

[#_rg_correspondance_RefOperationNonIT]
==== RG Correspondance entre les opérations Non IT et leur références :

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle
|===

Cette règle permet de retrouver l'item de référence, c'est à dire celui dont les facteurs d'impact seront utilisés afin d'évaluer l'impact de l'opération non IT en cours de traitement.

|===
|paramètre|entree/sortie|Description
|organisation|entrée|l'organisation en cours de traitement
|item|entrée|l'item dont on cherche la référence
|refItemRetenu|sortie|l'item dont l'impact servira de référence
|===

[pseudocode]
----
Règle RG_correspondanceRefOperationNonIT(nomOrganisation, item, refItemRetenu) {

		SI ref_TypeItem(item.type).refItemParDefaut existe
			refItemRetenu = ref_TypeItem(equipement.type).refItemParDefaut
		SINON
			ErrCalcul("aucune correspondance avec un item de référence n'a pu être déterminée")
		FIN SI

}
----

=== Calculs d'impacts unitaires

[#_calcul_impact_EqP_unitaire]
==== Calcul impact unitaire équipement physique

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle à dire d'expert
|===

Cette règle permet le calcul de l'impact moyen d'un équipement physique sur une année. Elle possède 3 paramètres : l'équipement dont on cherche à déterminer l'impact, l'étapeACV qui permet de déterminer quelle étape du cycle de vie de l'équipement est regardée et le critère d'impact que l'on souhaite extraire.

|===
|parametre|entree/sortie|Description
|critere|entrée|le critere dont on cherche à calculer la durée de Vie par défaut
|etapeACV|entrée|l'étape ACV dont on cherche à calculer la durée de Vie par défaut
|nomOrganisation|entrée|le nom de l'organisation en cours de traitement, récupéré de en_DonneesEntrees.nomOrganisation
|equipementPhysique|entrée|l'équipement physique dont on cherche à calculer l'impact environnemental
|en_DC|entrée|le PUE du datacenter lié à l'équipement physique.
|ind_ImpactEquipementPhysique.nomEquipement|sortie|le nom de l'équipement physique calculé
|ind_ImpactEquipementPhysique.critere|sortie|le critere calculé
|ind_ImpactEquipementPhysique.etapeACV|sortie|l'étape ACV calculé
|ind_ImpactEquipementPhysique.type|sortie|en_EqP.type
|ind_ImpactEquipementPhysique.impactUnitaire|sortie|L'impact calculé pour le critère et l'étape ACV, vaut null en cas d'erreur
|ind_ImpactEquipementPhysique.quantite|sortie|la quantité d'équipement physique
|ind_ImpactEquipementPhysique.tauxUtilisation|sortie|le taux d'utilisation de l'équipement physique
|ind_ImpactEquipementPhysique.modeUtilisation|sortie|le mode d'utilisation de l'équipement, il n'est utilisé que si le taux d'utilisation n'est pas renseigné. Les deux modes possibles sont (COPE & BYOD), les taux d'utilisation correspondants son enregistrés dans la table ref_hypotheses
|ind_ImpactEquipementPhysique.unite|sortie|l'unité présente dans le référentiel correspondant au critère en cours
|ind_ImpactEquipementPhysique.consoElecMoyenne|sortie|la consommation électrique déterminée par la règle suivante
|ind_ImpactEquipementPhysique.qualite|sortie|la qualité de la donnée d'inventaire

|===

[pseudocode]
----
soit equipementPhysique = EqP

Règle calculIndicateurImpactEquipementPhysique(critere, etape, nomOrganisation, EqP, en_DC, ind_ImpactEquipementPhysique) {
	'Récupération de la correspondance de refEquipement
	refEquipementRetenu = RG_correspondanceRefEquipement(equipementPhysique)
	result=0

	SI EtapeACV.code = "UTILISATION"

		result= result + EqP.quantité

		SI EqP.consoElecAnnuelle est renseigné      
			result = result x EqP.consoElecAnnuelle
			'enregistrement de la consommation electrique retenue
			ind_ImpactEquipementPhysique.consoElecMoyenne = EqP.consoElecAnnuelle
		SINON SI
			'récupération de la consommation électrique de la référence de l'équipement retenue
			result = result x Ref_FacteurCaracterisation(refEquipementRetenu, EtapeACV, Critere).consoElecAnMoyenne
			'enregistrement de la consommation electrique retenue
			ind_ImpactEquipementPhysique.consoElecMoyenne = Ref_FacteurCaracterisation(refEquipementRetenu, EtapeACV, Critere).consoElecAnMoyenne
		SINON 
			ErrCalcFonc("donnée de consommation electrique manquante") 
			Arret du calcul
		FIN SI

		SI EqP.NomCourtDatacenter est renseigné

			SI n_DC(EqP.NomCourtDatacenter).PUE existe
				result = result x en_DC(EqP.NomCourtDatacenter).PUE
			SINON SI ref_Hypothese(PUEParDefaut) existe
				result = result x ref_Hypothese(PUEParDefaut).valeur
			SINON 
				ErrCalcFonc("le PUE est manquant et ne permet le calcul de l'impact à l'usage de l'équipement") 
				Arret du calcul
			FIN SI

			result = result x ref_FacteurCaracterisation(EtapeACV, Critere, Categorie=electricity-mix, Localisation = en_DC(NomCourtDatacenter).localisation).valeur
		SINON
			result = result x ref_FacteurCaracterisation(EtapeACV, Critere, Categorie=electricity-mix, Localisation = EqP.PaysDUtilisation).valeur

		FIN SI

	SINON
		result= result + EqP.quantité

		'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
		result = result x Ref_FacteurCaracterisation(refEquipementretenu, EtapeACV, Critere).valeur
		
		result = result/ RG_DureeVieItem_Defaut(equipementPhysique)
	FIN SI

	'pour toutes les étapes, on multiplie par un taux d'utilisation
	SI EqP.tauxUtilisation est renseigné
			result = result x EqP.tauxUtilisation
		SINON SI EqP.modeUtilisation est renseigné
			SI ref_Hypothese(EqP.modeUtilisation) existe
				EqP.tauxUtilisation = ref_Hypothese(EqP.modeUtilisation).valeur
				result = result x EqP.tauxUtilisation
			SINON 
				EqP.tauxUtilisation = 1.0
				result = result x EqP.tauxUtilisation
		SINON 
			EqP.tauxUtilisation = 1.0
			result = result x EqP.tauxUtilisation
		FIN SI

ind_ImpactEquipementPhysique.impactUnitaire= result	

}
----

.Calcul de l'impact "moyen" en CO2 lié à l'utilisation d'un serveur sur 1 an
====
Equipement = exemple d'un serveur d'un client, sur une DataCenter possédant un PUE de 1.13

EqP.quantité = 1
x en_EqP.ConsoElecAnMoyenne= 1000 kWh
x en_EqP.tauxUtilisation = 0,85
x en_DC(NomCourtDatacenter = "googleCloud").PUE = 1,13
x ref_FacteurCaracterisation("Changement Climatique", "FABRICATION", Categorie=electricity-mix, Localisation = "France").valeur = 0,0813225

ImpactUnitaireEqP = 78,11 kg CO2eq /an
====


[#_calcul_impact_EqV_unitaire]
==== Calcul d'impact d'une machine virtuelle

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle à dire d'expert
|===

Cette règle permet le calcul de l'impact moyen d'un équipement virtuel sur une année.
L'impact alloué à la machine virtuelle correspond à une part de l'impact de l'équipement physique sous-jacent (décrit ici <<_calcul_impact_EqP_unitaire>>)

|===
|parametre|entree/sortie|Description
|critere|entrée|le critère dont on cherche à calculer la durée de Vie par défaut
|etapeACV|entrée|l'étape ACV dont on cherche à calculer la durée de Vie par défaut
|en_EqV|entrée|l'équipement virtuel dont on cherche à calculer l'impact environnemental
|ImpactEqP|entrée|l'équipement physique dont l'impact est en cours de calcul
|ConsoElecEqP|entrée|la consommation electrique retenue de l'équipement physique dont l'impact est en cours de calcul
|NbvCPU|entrée|le nombre de vCPU total de l'ensemble des machines virtuelles associées à l'équipement physique sous-jacent de l'équipement virtuel en cours de calcul
|nbEqV|entrée| le nombre total d'équipements virtuels associées à l'équipement physique sous-jacent de l'équipement virtuel en cours de calcul
|vCPUoK|entrée| le booléen indiquant que l'ensemble des VM du serveur possèdent un vCPU correctement renseigné
|ind_ImpactEquipementVirtuel.nomEquipement|sortie|le nom de l'équipement virtuel calculé
|ind_ImpactEquipementVirtuel.critere|sortie|le critère calculé
|ind_ImpactEquipementVirtuel.etapeACV|sortie|l'étape ACV calculée
|ind_ImpactEquipementVirtuel.cluster|sortie|le cluster présent dans les données d'entrée pour cette équipements virtuels
|ind_ImpactEquipementVirtuel.impactUnitaire|sortie|l'impact calculé pour le critère et l'étape ACV
|ind_ImpactEquipementVirtuel.unite|sortie|l'unité présente dans le référentiel correspondant au critère en cours
|ind_ImpactEquipementVirtuel.consoElecMoyenne|sortie|la consommation électrique renseignée en entrée
|ind_ImpactEquipementVirtuel.qualite|sortie|la qualité de la donnée d'inventaire

|===


[pseudocode]
----
soit en_EqV(nomEquipementVirtuel) = EqV

Règle calculIndicateurImpactEquipementVirtuel(critere, etape, en_EqV, ImpactEqP, ConsoElecEqP, NbvCPU, nbEqV, vCPUoK, stockageTotalVirtuel, ind_ImpactEquipementVirtuel) {

	SI EqV.cleRepartition est renseigné
		ind_ImpactEquipementVirtuel.ImpactUnitaire = ImpactEqP x EqV.cleRepartition 
		ind_ImpactEquipementVirtuel.consoElecMoyenne = ConsoElecEqP x EqV.cleRepartition

	SINON SI EqV.typeEqV = "calcul" et vCPUoK est vrai
		ind_ImpactEquipementVirtuel.ImpactUnitaire = ImpactEqP x EqV.vCPU / NbvCPU
		ind_ImpactEquipementVirtuel.consoElecMoyenne = ConsoElecEqP x EqV.vCPU / NbvCPU

	SINON SI EqV.typeEqV = "stockage" et stockoK est vrai
		ind_ImpactEquipementVirtuel.ImpactUnitaire = ImpactEqP x EqV.capaciteStockage / stockageTotalVirtuel
		ind_ImpactEquipementVirtuel.consoElecMoyenne = ConsoElecEqP x EqV.capaciteStockage / stockageTotalVirtuel

	SINON
		'Si l'info des vCPU est manquante sur au moins un des équipement virtuel de l'équipement, on répartis l'impact à parts égale sur l'ensemble des équipements virtuels
		ind_ImpactEquipementVirtuel.ImpactUnitaire = ImpactEqP / nbEqV
		ind_ImpactEquipementVirtuel.consoElecMoyenne = ConsoElecEqP / nbEqV
	FIN SI

}
----


[#_calculIndicateurImpactApplicatif]
==== Calcul impact associé à une application 

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle à dire d'expert
|===

Cet indicateur correspond l'impact moyen annuel d'une application. 
Il est calculé *directement dans le moteur de calcul* <<_moteur_de_calcul>> et part de l'hypothèse qu'un application tourne sur une ou plusieurs équipements virtuels dédiée(s). L'impact alloué à une application correspond alors l'impact des équipements virtuels sous-jacent (décrit ici <<_calcul_impact_EqV_unitaire>>).

|===
|parametre|entree/sortie|Description
|critere|entrée|le critère dont on cherche à calculer la durée de Vie par defaut
|etapeACV|entrée|l'étape ACV dont on cherche à calculer la durée de Vie par defaut
|nomApp|entrée|nom de l'applicaton 
|typeEnvironnement|entrée|type d'environnement sur lequel
|ind_ImpactApplicatif.nomApplication|sortie|en_App.nomApplication
|ind_ImpactApplicatif.critere|sortie|critère calculé
|ind_ImpactApplicatif.etapeACV|sortie|étape ACV calculée
|ind_ImpactApplicatif.typeEnvironnement|sortie|en_App.typeEnvironnement
|ind_ImpactApplicatif.domaine|sortie|en_App.domaine
|ind_ImpactApplicatif.sousDomaine|sortie|en_App.sousDomaine
|ind_ImpactApplicatif.unite|sortie|l'unité présente dans le référentiel correspondant au critère en cours
|ind_ImpactApplicatif.consoElecMoyenne|sortie|la consomation électrique calculée (correspondant à la somme des consommations éléctriques des équipements virtuels sous-jacentes)
|ind_ImpactApplicatif.qualite|sortie|la qualité de la donnée d'inventaire

|===

[#_calcul_impact_OperationNonIT_unitaire]
==== Calcul impact unitaire d'une opérationNonIT

|===
|Version|Type de changement|Description
|V1|création|Initialisation de la règle à dire d'expert
|===

Cette règle permet le calcul de l'impact moyen d'une opération Non IT sur une année. Elle possède 3 paramètres : l'opération/l'item dont on cherche à déterminer l'impact, l'étapeACV qui permet de déterminer quelle étape du cycle de vie de l'item est regardée et le critère d'impact que l'on souhaite extraire.

|===
|parametre|entree/sortie|Description
|critere|entrée|le critere dont on cherche à calculer la durée de Vie par défaut
|etapeACV|entrée|l'étape ACV dont on cherche à calculer la durée de Vie par défaut
|nomOrganisation|entrée|le nom de l'organisation en cours de traitement
|operationNonIT|entrée|l'opération non IT dont on cherche à calculer l'impact environnemental
|ind_ImpactOperationNonIT.nomItemNonIT|sortie|le nom de l'item dont on a calculé l'impact
|ind_ImpactOperationNonIT.critere|sortie|le critere calculé
|ind_ImpactOperationNonIT.etapeACV|sortie|l'étape ACV calculée
|ind_ImpactOperationNonIT.typeItem|sortie|le type d'item
|ind_ImpactOperationNonIT.impactUnitaire|sortie|l'impact calculé pour le critère et l'étape ACV, vaut null en cas d'erreur
|ind_ImpactOperationNonIT.quantite|sortie|la quantité d'items
|ind_ImpactOperationNonIT.unite|sortie|l'unité présente dans le référentiel correspondant au critère en cours
|ind_ImpactOperationNonIT.consoElecMoyenne|sortie|la consommation électrique
|ind_ImpactOperationNonIT.qualite|sortie| operationNonIT.qualite
|===

[pseudocode]
----
soit operationNonIT = OpNIT

Règle calculIndicateurImpactOperationNonIT(critere, etape, nomOrganisation, OpNIT, ind_ImpactOperationNonIT) {

	'Récupération de la correspondance de refItem
	refItemRetenu = RG_correspondanceRefOperationNonIT(nomOrganisation, OpNIT)
	result = 0
	SI OpNIT.categorie = "RESEAU_MOBILE" OU "RESEAU_FIXE" OU "MAINTENANCE" OU "BATIMENT"
		SI EtapeACV.code = "UTILISATION"
			result= result + OpNIT.quantité

			SI OpNIT.consoElecAnnuelle est renseigné
				result= result x OpNIT.consoElecAnnuelle
				'enregistrement de la consommation electrique retenue
				ind_ImpactOperationNonIT.consoElecMoyenne = OpNIT.consoElecAnnuelle
			SINON SI
				'récupération de la consommation électrique de la référence de l'équipement retenue
				result= result x Ref_FacteurCaracterisation(refItemRetenu, EtapeACV, Critere).consoElecAnMoyenne
				'enregistrement de la consommation electrique retenue
				ind_ImpactOperationNonIT.consoElecMoyenne = Ref_FacteurCaracterisation(refItemRetenu, EtapeACV, Critere).consoElecAnMoyenne
			SINON
				ErrCalcFonc("donnée de consommation electrique manquante")
				Arret du calcul
			FIN SI

			result= result x ref_FacteurCaracterisation(EtapeACV, Critere, Categorie=electricity-mix, Localisation = OpNIT.Localisation).valeur
		
		SINON SI EtapeACV.code != "UTILISATION"
			result= result + OpNIT.quantité

			'récupération de l'impact pour le critère, de l'étape ACV en cours et de la référence de l'item retenu
			result= result x Ref_FacteurCaracterisation(refItemRetenu, EtapeACV, Critere).valeur

		    SI OpNIT.categorie = "RESEAU_FIXE"
				referenceHypothese= ref_TypeItem(OpNIT.type).refHypothese
				SI referenceHypothese existe 
					SI ref_Hypothese(referenceHypothese) existe
			   			result= result / ref_Hypothese(referenceHypothese).valeur

		    SINON SI OpNIT.categorie = "BATIMENT"
			   result= result / RG_DureeVieItem_Defaut(operationNonIT)
		FIN SI

	SINON SI OpNIT.categorie = "DEPLACEMENT_ELECTRIQUE" OU "DEPLACEMENT_ESSENCE" OU DEPLACEMENT_HYBRIDE
		'la quantité est dans ce cas relative au nombre de kilomètres parcourus par le véhicule
		result= result + OpNIT.quantité

		'récupération de la consommation moyenne pour le véhicule choisi, valeur récupérée dans ref_hypothèses
		referenceHypothese= ref_TypeItem(OpNIT.type).refHypothese
		SI referenceHypothese existe 
			SI ref_Hypothese(referenceHypothese) existe
			   	result= result x ref_Hypothese(referenceHypothese).valeur

		SI OpNIT.categorie = "DEPLACEMENT_ELECTRIQUE"
			'récupération du mix électrique pour le critère de Fabrication et pour l'étape ACV en cours
			result= result x ref_FacteurCaracterisation(FABRICATION, Critère, mix elec, OpNIT.Localisation).valeur

		SINON SI OpNIT.categorie = "DEPLACEMENT_ESSENCE"
			'récupération de l'impact de la production d'essence pour le critère de Fabrication et pour l'étape ACV en cours
			result= result x  ref_FacteurCaracterisation(FABRICATION, Critère, Production essence).valeur

		SINON SI OpNIT.categorie = "DEPLACEMENT_HYBRIDE"
			'récupération de l'impact de la production d'essence pour le critère de Fabrication et pour l'étape ACV en cours
			result= result x  ref_FacteurCaracterisation(FABRICATION, Critère, Production essence).valeur
			'récupération du taux utile pour le calcul d'impact des véhicules hybrides, valeur récupérée dans ref_hypothèses
			result= result x  ref_Hypothese('taux_vehicule_hybride').valeur

		FIN SI
	FIN SI
ind_ImpactOperationNonIT.impactUnitaire = result

}
----

.Calcul de l'impact "moyen" en CO2 lié à l'utilisation d'un réseau fixe sur 1 an
====
Item = exemple d'un réseau fixe localisé en France

OpNIT.quantité = 400
x ref_FacteurCaracterisation(reseau-fixe, UTILISATION, Changement Climatique).ConsoElecAnMoyenne = 180 kWh
x ref_FacteurCaracterisation( UTILISATION, Changement Climatique,mixelec,France).valeur = 0.0813225
/ ref_Hypothese(CAPACITE_LIGNE_FIXE_FR) = 2640

ImpactUnitaireOpNIT = 2,21788 kg CO2eq /an
====

[#_calculImpactMessagerie]
==== Calcul impact lié à la Messagerie

|===
|version|type de changement|description 
|V1|création|Initialisation de la règle à dire d'expert
|===

*Note importante* : cette règle de calcul ne fait pas l'objet d'un consensus 
Cette règle permet un calcul approximatif de l'impact lié à la messagerie. Il prend en compte l'impact moyen d'un mail établi à partir de différentes sources et en prenant en compte le poids des PJ (cf. sources)

|===
|parametre|entree/sortie|Description
|en_Messagerie|entrée|les données d'entrée liées à la messagerie
|ref_Critere|entrée|Critère d'impact en cours de travaux
|ref_Messagerie|entrée|Les paramètres associées à la fonction affine pour le critère en cours.
|ind_ImpactMessagerie.impactMensuel|sortie|l'impact calculé avec la fonction affine et les paramètre du référentiel
|ind_ImpactMessagerie.MoisAnnee|sortie|en_Messagerie.MoisAnnee
|ind_ImpactMessagerie.critere|sortie|ref_Critere.nomCritere
|ind_ImpactMessagerie|sortie|Autant d'indicateurs qu'il y a d'objet en_Messagerie en entrée
|===

[pseudocode]
----
Règle calculImpactMessagerie(en_Messagerie, ref_Critere, ref_ImpactMessagerie, ind_ImpactMessagerie) {

	'Production d'un indicateur ind_ImpactMessagerie par entrée en_Messagerie
		'calcul du poids moyen d'un mail en Go
		Double poidsMoyenMail = en_Messagerie.volumeTotalMailEmis/en_Messagerie.nombreMailEmis
		'on applique la fonction affine en utilisant les éléments du ref_ImpactMessagerie pour connaitre l'impact d'un mail en C02 selon son poids, et on le multiplie par le volume de mail envoyés
		ind_ImpactMessagerie.impactMensuel = (ref_ImpactMessagerie.constanteCoefficientDirecteur * poidsMoyenMail + ref_ImpactMessagerie.constanteOrdonneeOrigine) * en_Messagerie.nombreMailEmisXDestinataires
		ind_ImpactMessagerie.MoisAnnee = en_Messagerie.MoisAnnee
		ind_ImpactMessagerie.critere = ref_Critere.nomCritere

}
----


== Gestion des erreurs

=== ErrCalcFonc
Les erreurs fonctionnelles sont de la forme suivante : "ErrCalcFonc : [règle calculée et paramètres de la fonction associée] ; [message d'erreur]"
Au déclenchement de ce type d'erreur, une ligne s'affiche dans les logs, avec le nom de la règle où l'erreur s'est produite, les paramètres entrant de la règle et le message indiqués entre parenthèse.

.Erreur de calcul de l'impact réseau
====
 "ErrCalcFonc : ImpactUnitaireOperationNonIT(item, etapeACV, critere) ; la référence "impactReseauMobileMoyen" n'existe pas"
====

=== ErrCalcTech
Cette erreur se déclenche durant les calculs en cas d'erreurs non prévues et sont de la forme suivante : "ErrCalcTech : [règle calculée et paramètres de la fonction associée] ; [code de l'erreur technique]"


