@open3cl/engine 1.8.49 → 1.8.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,259 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import {
3
+ ANNEE_CHAUDIERE_MURALE_RECENTE,
4
+ anneeInstallationGenerateur,
5
+ isChaudiere,
6
+ periodeInstallationLibelle,
7
+ pnChaudiere,
8
+ pnEstimeeDimensionnement,
9
+ puissanceEcs,
10
+ valeurChaudiereMurale
11
+ } from './13.2_generateur_combustion_pdim.js';
12
+
13
+ /**
14
+ * Module de calcul pur (aucune dépendance) : pas de mock nécessaire.
15
+ * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4 Calcul des puissances nominales (p.90-91)
16
+ */
17
+ describe('puissanceEcs - puissance de dimensionnement ECS selon le volume de stockage', () => {
18
+ test('production instantanée (Vs = 0) : Pecs = 21 kW', () => {
19
+ expect(puissanceEcs(0)).toBe(21);
20
+ expect(puissanceEcs('0.000')).toBe(21);
21
+ });
22
+
23
+ test('semi-instantanée (0 < Vs ≤ 20) : Pecs = 21 − 0,8 × Vs', () => {
24
+ expect(puissanceEcs(10)).toBeCloseTo(13, 9);
25
+ expect(puissanceEcs(20)).toBeCloseTo(5, 9);
26
+ });
27
+
28
+ test('semi-accumulation (20 < Vs ≤ 150) : Pecs = 5 − 1,751 × (Vs − 20) / 65', () => {
29
+ expect(puissanceEcs(85)).toBeCloseTo(5 - 1.751, 9);
30
+ expect(puissanceEcs(150)).toBeCloseTo(5 - (1.751 * 130) / 65, 9);
31
+ });
32
+
33
+ test('accumulation (Vs > 150) : Pecs = (7,14 × Vs + 428) / 1000', () => {
34
+ expect(puissanceEcs(200)).toBeCloseTo((7.14 * 200 + 428) / 1000, 9);
35
+ });
36
+
37
+ test.each([undefined, null, '', 'abc', -5])('volume %s non exploitable : undefined', (vs) => {
38
+ expect(puissanceEcs(vs)).toBeUndefined();
39
+ });
40
+ });
41
+
42
+ describe('pnChaudiere - table Pdim → Pn des chaudières', () => {
43
+ test.each([
44
+ [3, 18, 5],
45
+ [5, 18, 5],
46
+ [7, 18, 10],
47
+ [12, 18, 13],
48
+ [15, 18, 18],
49
+ [18, 18, 18],
50
+ [20, 24, 24],
51
+ [26, 28, 28],
52
+ [30, 32, 32],
53
+ [40, 40, 40]
54
+ ])('Pdim = %s kW : Pn = %s kW (murale < 2006 ou sol), %s kW (murale ≥ 2006)', (pdim, a, b) => {
55
+ expect(pnChaudiere(pdim, false)).toBe(a);
56
+ expect(pnChaudiere(pdim, true)).toBe(b);
57
+ });
58
+
59
+ test('Pdim > 40 kW : Pn = (Partie entière(Pdim / 5) + 1) × 5, quelle que soit la colonne', () => {
60
+ expect(pnChaudiere(41, false)).toBe(45);
61
+ expect(pnChaudiere(45, true)).toBe(50);
62
+ expect(pnChaudiere(57.3, true)).toBe(60);
63
+ });
64
+
65
+ test('Pn ≥ Pdim sur toute la table', () => {
66
+ for (let pdim = 0.5; pdim < 80; pdim += 0.5) {
67
+ expect(pnChaudiere(pdim, false)).toBeGreaterThanOrEqual(pdim);
68
+ expect(pnChaudiere(pdim, true)).toBeGreaterThanOrEqual(pdim);
69
+ }
70
+ });
71
+ });
72
+
73
+ describe('isChaudiere - générateurs concernés par la table Pdim → Pn', () => {
74
+ test.each([
75
+ ['chaudière gaz à condensation après 2015', true],
76
+ ['pompe à chaleur hybride : partie chaudière chaudière gaz à condensation après 2015', true],
77
+ ['chaudière(s) gaz multi bâtiment modélisée comme un réseau de chaleur', false],
78
+ ['radiateur à gaz indépendant ou autonome après 2006', false],
79
+ ['générateur à air chaud à combustion avant 2006', false],
80
+ ['accumulateur gaz classique après 2000', false],
81
+ [undefined, false]
82
+ ])('%s → %s', (libelle, attendu) => {
83
+ expect(isChaudiere(libelle)).toBe(attendu);
84
+ });
85
+ });
86
+
87
+ describe('periodeInstallationLibelle - période d’installation déduite du type de générateur', () => {
88
+ test.each([
89
+ ['chaudière gaz standard 2001-2015', 2001, 2015],
90
+ ['chaudière gaz classique avant 1981', -Infinity, 1980],
91
+ ['chaudière gaz à condensation après 2015', 2016, Infinity],
92
+ ['poêle à bois bouilleur bûche installé à partir de 2012', 2012, Infinity],
93
+ ['chaudière électrique', -Infinity, Infinity],
94
+ [undefined, -Infinity, Infinity]
95
+ ])('%s → [%s ; %s]', (libelle, min, max) => {
96
+ expect(periodeInstallationLibelle(libelle)).toStrictEqual({ min, max });
97
+ });
98
+ });
99
+
100
+ describe('anneeInstallationGenerateur - année d’installation retenue', () => {
101
+ test('année d’installation saisie prioritaire', () => {
102
+ expect(anneeInstallationGenerateur('2003', 1970, 'chaudière gaz après 2015')).toBe(2003);
103
+ });
104
+
105
+ test('repli : année de construction si elle est compatible avec le type de générateur', () => {
106
+ expect(anneeInstallationGenerateur(undefined, '2010', 'chaudière gaz standard 2001-2015')).toBe(
107
+ 2010
108
+ );
109
+ });
110
+
111
+ test('repli : année de construction ramenée dans la période du type de générateur', () => {
112
+ expect(
113
+ anneeInstallationGenerateur(undefined, 1970, 'chaudière gaz à condensation après 2015')
114
+ ).toBe(2016);
115
+ expect(anneeInstallationGenerateur(undefined, 2020, 'chaudière gaz classique avant 1981')).toBe(
116
+ 1980
117
+ );
118
+ });
119
+
120
+ test('sans année de construction : borne de la période si elle tranche par rapport à 2006', () => {
121
+ expect(anneeInstallationGenerateur(undefined, undefined, 'chaudière gaz après 2015')).toBe(
122
+ 2016
123
+ );
124
+ expect(anneeInstallationGenerateur(undefined, undefined, 'chaudière gaz avant 1981')).toBe(
125
+ 1980
126
+ );
127
+ expect(
128
+ anneeInstallationGenerateur(undefined, undefined, 'chaudière gaz standard 2001-2015')
129
+ ).toBeUndefined();
130
+ expect(
131
+ anneeInstallationGenerateur(undefined, undefined, 'chaudière électrique')
132
+ ).toBeUndefined();
133
+ });
134
+ });
135
+
136
+ describe('valeurChaudiereMurale - sous-fiche « Chaudière murale »', () => {
137
+ test.each([
138
+ ['oui', true],
139
+ [' Oui ', true],
140
+ ['non', false],
141
+ ['NC', undefined],
142
+ [undefined, undefined]
143
+ ])('%s → %s', (valeur, attendu) => {
144
+ expect(valeurChaudiereMurale(valeur)).toBe(attendu);
145
+ });
146
+ });
147
+
148
+ describe('pnEstimeeDimensionnement - Pn estimée (W) d’un générateur sans pn', () => {
149
+ const CHAUDIERE = 'chaudière gaz à condensation après 2015';
150
+
151
+ test('chaudière de chauffage seul, murale récente : Pn = table(Pch) seconde colonne', () => {
152
+ expect(
153
+ pnEstimeeDimensionnement({
154
+ pch: 7800,
155
+ libelleTypeGenerateur: CHAUDIERE,
156
+ murale: true,
157
+ anneeInstallation: 2018
158
+ })
159
+ ).toBe(10000);
160
+ });
161
+
162
+ test('chaudière au sol : première colonne (plancher 18 kW) même installée après 2006', () => {
163
+ expect(
164
+ pnEstimeeDimensionnement({
165
+ pch: 7800,
166
+ libelleTypeGenerateur: CHAUDIERE,
167
+ murale: false,
168
+ anneeInstallation: 2018
169
+ })
170
+ ).toBe(18000);
171
+ });
172
+
173
+ test('chaudière murale installée avant 2006 : première colonne', () => {
174
+ expect(
175
+ pnEstimeeDimensionnement({
176
+ pch: 2300,
177
+ libelleTypeGenerateur: 'chaudière gaz standard 1991-2000',
178
+ murale: true,
179
+ anneeInstallation: ANNEE_CHAUDIERE_MURALE_RECENTE - 1
180
+ })
181
+ ).toBe(18000);
182
+ });
183
+
184
+ test('pose inconnue : seconde colonne si installée à partir de 2006, première sinon', () => {
185
+ const base = { pch: 2300, libelleTypeGenerateur: CHAUDIERE };
186
+ expect(pnEstimeeDimensionnement({ ...base, anneeInstallation: 2006 })).toBe(5000);
187
+ expect(pnEstimeeDimensionnement({ ...base, anneeInstallation: 2005 })).toBe(18000);
188
+ expect(pnEstimeeDimensionnement({ ...base, anneeInstallation: undefined })).toBe(18000);
189
+ });
190
+
191
+ test('chaudière mixte à production instantanée : Pdim = max(Pch ; 21 kW)', () => {
192
+ expect(
193
+ pnEstimeeDimensionnement({
194
+ pch: 7800,
195
+ volumeStockage: 0,
196
+ usageEcs: true,
197
+ libelleTypeGenerateur: CHAUDIERE,
198
+ murale: true,
199
+ anneeInstallation: 2018
200
+ })
201
+ ).toBe(24000);
202
+ });
203
+
204
+ test('chaudière mixte à accumulation : Pecs faible, Pdim = Pch', () => {
205
+ expect(
206
+ pnEstimeeDimensionnement({
207
+ pch: 12500,
208
+ volumeStockage: 200,
209
+ usageEcs: true,
210
+ libelleTypeGenerateur: CHAUDIERE,
211
+ murale: true,
212
+ anneeInstallation: 2018
213
+ })
214
+ ).toBe(13000);
215
+ });
216
+
217
+ test('générateur ECS seul : Pdim = Pecs (Pch ignorée)', () => {
218
+ expect(
219
+ pnEstimeeDimensionnement({
220
+ pch: 30000,
221
+ volumeStockage: 10,
222
+ usageEcs: true,
223
+ usageChauffage: false,
224
+ libelleTypeGenerateur: CHAUDIERE,
225
+ murale: true,
226
+ anneeInstallation: 2018
227
+ })
228
+ ).toBe(13000);
229
+ });
230
+
231
+ test('générateur ECS seul sans volume de stockage : Pch conservée (comportement historique)', () => {
232
+ expect(
233
+ pnEstimeeDimensionnement({
234
+ pch: 7800,
235
+ usageEcs: true,
236
+ usageChauffage: false,
237
+ libelleTypeGenerateur: CHAUDIERE
238
+ })
239
+ ).toBe(7800);
240
+ });
241
+
242
+ test('générateur non-chaudière (radiateur gaz, air chaud…) : Pn = Pdim', () => {
243
+ expect(
244
+ pnEstimeeDimensionnement({
245
+ pch: 7800,
246
+ libelleTypeGenerateur: 'radiateur à gaz indépendant ou autonome après 2006'
247
+ })
248
+ ).toBeCloseTo(7800, 9);
249
+ expect(
250
+ pnEstimeeDimensionnement({
251
+ pch: 3000,
252
+ volumeStockage: 0,
253
+ usageEcs: true,
254
+ usageChauffage: false,
255
+ libelleTypeGenerateur: 'chauffe-eau gaz à production instantanée après 2015'
256
+ })
257
+ ).toBeCloseTo(21000, 9);
258
+ });
259
+ });
@@ -380,7 +380,10 @@ export default function calc_gen_ecs(dpe, gen_ecs, ecs_di, ecs_de, GV, ca_id, zc
380
380
  const tbase = Tbase[ca][zc.slice(0, 2)];
381
381
 
382
382
  const methodeSaisie = parseInt(de.enum_methode_saisie_carac_sys_id);
383
- tv_generateur_combustion(dpe, di, de, 'ecs', GV, tbase, methodeSaisie);
383
+ // §13.2.2.4 : Pn estimée (si absente) à partir de Pecs (volume de stockage) pour les installations individuelles
384
+ tv_generateur_combustion(dpe, di, de, 'ecs', GV, tbase, methodeSaisie, 1, {
385
+ installationIndividuelle: String(ecs_de.enum_type_installation_id) === '1'
386
+ });
384
387
 
385
388
  if (bug_for_bug_compat) {
386
389
  if (di.qp0 < 1) {
package/README.md CHANGED
@@ -370,7 +370,7 @@ Ces résultats sont **générés automatiquement** à la fin de `npm run test:co
370
370
 
371
371
  <!-- CORPUS:START -->
372
372
 
373
- > **Version `1.8.48`** · branche `main` · généré le 2026-10-12
373
+ > **Version `1.8.50`** · branche `main` · généré le 2026-10-12
374
374
  > Seuil de tolérance **5%**
375
375
 
376
376
  <table>
@@ -403,24 +403,24 @@ Ces résultats sont **générés automatiquement** à la fin de `npm run test:co
403
403
 
404
404
  <table>
405
405
  <tr>
406
- <td align="center"><strong>5,92 ms</strong><br/><sub>moyenne</sub></td>
407
- <td align="center"><strong>5,25 ms</strong><br/><sub>médiane</sub></td>
408
- <td align="center"><strong>0,11 ms</strong><br/><sub>min</sub></td>
409
- <td align="center"><strong>590,9 ms</strong><br/><sub>max</sub></td>
406
+ <td align="center"><strong>5,86 ms</strong><br/><sub>moyenne</sub></td>
407
+ <td align="center"><strong>5,18 ms</strong><br/><sub>médiane</sub></td>
408
+ <td align="center"><strong>0,12 ms</strong><br/><sub>min</sub></td>
409
+ <td align="center"><strong>549,4 ms</strong><br/><sub>max</sub></td>
410
410
  </tr>
411
411
  </table>
412
412
 
413
413
  | Corpus | Moyenne | Médiane | Min | Max | p95 | p99 |
414
414
  | :--------------------------------------------- | ------: | ------: | ------: | -------: | ------: | ------: |
415
- | **Généraliste** | 4,99 ms | 4,39 ms | 0,21 ms | 95,5 ms | 9,05 ms | 14,6 ms |
416
- | **Appartement · chauffage individuel (2025)** | 4,42 ms | 4,12 ms | 1,64 ms | 30,2 ms | 7,40 ms | 9,25 ms |
417
- | **Logement individuel (2025)** | 5,71 ms | 5,18 ms | 1,70 ms | 46,8 ms | 10,4 ms | 14,1 ms |
418
- | **Maison individuelle (2025)** | 6,69 ms | 6,10 ms | 1,94 ms | 58,0 ms | 11,7 ms | 15,7 ms |
419
- | **Immeuble · chauffage individuel** | 7,25 ms | 6,20 ms | 0,11 ms | 141,9 ms | 14,6 ms | 23,6 ms |
420
- | **Appartement · chauffage collectif (2025)** | 4,82 ms | 4,57 ms | 1,68 ms | 37,0 ms | 7,67 ms | 9,89 ms |
421
- | **Immeuble · chauffage collectif** | 6,49 ms | 5,77 ms | 0,15 ms | 116,1 ms | 11,7 ms | 20,1 ms |
422
- | **Immeuble · chauffage mixte** | 6,05 ms | 4,97 ms | 0,22 ms | 590,9 ms | 12,7 ms | 20,7 ms |
423
- | **Individuel généré depuis l'immeuble (2026)** | 6,87 ms | 5,95 ms | 1,71 ms | 72,7 ms | 13,3 ms | 22,3 ms |
415
+ | **Généraliste** | 4,94 ms | 4,45 ms | 0,23 ms | 35,1 ms | 9,08 ms | 13,0 ms |
416
+ | **Appartement · chauffage individuel (2025)** | 4,79 ms | 4,42 ms | 1,59 ms | 39,2 ms | 8,31 ms | 11,2 ms |
417
+ | **Logement individuel (2025)** | 5,40 ms | 4,84 ms | 1,68 ms | 42,3 ms | 10,0 ms | 13,4 ms |
418
+ | **Maison individuelle (2025)** | 6,47 ms | 5,87 ms | 1,94 ms | 55,6 ms | 11,4 ms | 14,6 ms |
419
+ | **Immeuble · chauffage individuel** | 7,31 ms | 6,23 ms | 0,12 ms | 153,7 ms | 14,9 ms | 23,5 ms |
420
+ | **Appartement · chauffage collectif (2025)** | 4,94 ms | 4,79 ms | 1,61 ms | 34,7 ms | 7,75 ms | 9,99 ms |
421
+ | **Immeuble · chauffage collectif** | 6,38 ms | 5,54 ms | 0,13 ms | 119,4 ms | 11,9 ms | 21,2 ms |
422
+ | **Immeuble · chauffage mixte** | 5,90 ms | 4,82 ms | 0,22 ms | 549,4 ms | 12,7 ms | 20,4 ms |
423
+ | **Individuel généré depuis l'immeuble (2026)** | 6,63 ms | 5,69 ms | 1,75 ms | 67,7 ms | 12,3 ms | 20,8 ms |
424
424
 
425
425
  <sub>La moyenne est tirée vers le haut par les DPE collectifs, dont le coût atteint plusieurs
426
426
  dizaines de fois la médiane : c’est la médiane qui décrit le cas courant, et p95/p99 le cas
package/conso.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import enums from './enums.js';
2
2
  import calc_conso_eclairage from './16_conso_eclairage.js';
3
3
  import tvs from './tv.js';
4
- import { tv } from './utils.js';
4
+ import { bug_for_bug_compat, tv } from './utils.js';
5
5
 
6
6
  export const COEFF_EP_2_3 = 2.3;
7
7
  export const COEFF_EP_1_9 = 1.9;
@@ -311,53 +311,130 @@ function getConso(coef, type_energie, conso) {
311
311
  return conso;
312
312
  }
313
313
 
314
+ /**
315
+ * Arrêtés « réseaux de chaleur » et table de valeurs associée (modèle de données de l'observatoire
316
+ * DPE, `modele_donnee/arrete_reseau_chaleur.json`). Le nom de la table ne correspond pas à l'année
317
+ * de l'arrêté (ex. l'arrêté du 05/07/2024 publie la table `reseau_chaleur_2023`).
318
+ * - date_arrete : valeur attendue dans `date_arrete_reseau_chaleur` ;
319
+ * - date_application : date à partir de laquelle l'arrêté s'applique (DPE sans date d'arrêté).
320
+ */
321
+ export const ARRETES_RESEAU_CHALEUR = [
322
+ { table: 'reseau_chaleur_2020', date_arrete: '2020-10-12', date_application: '2020-10-17' },
323
+ { table: 'reseau_chaleur_2021', date_arrete: '2021-10-21', date_application: '2022-01-18' },
324
+ { table: 'reseau_chaleur_2022', date_arrete: '2023-03-16', date_application: '2023-04-16' },
325
+ { table: 'reseau_chaleur_2023', date_arrete: '2024-07-05', date_application: '2024-08-09' },
326
+ { table: 'reseau_chaleur_2024', date_arrete: '2025-04-11', date_application: '2025-05-26' },
327
+ { table: 'reseau_chaleur_2025', date_arrete: '2026-04-25', date_application: '2026-05-25' }
328
+ ];
329
+
330
+ /** Facteur « AUTRES RESEAUX DE CHALEUR » (réseau non répertorié ou inconnu), kgCO2/kWh */
331
+ export const COEF_GES_AUTRES_RESEAUX_CHALEUR = 0.385;
332
+
333
+ /**
334
+ * Normalise une date (chaîne ISO ou Date) au format AAAA-MM-JJ, null si invalide.
335
+ * @param date {string|Date|undefined}
336
+ * @returns {string|null}
337
+ */
338
+ function isoDate(date) {
339
+ if (typeof date !== 'string' && !(date instanceof Date)) return null;
340
+ const d = new Date(date);
341
+ return isNaN(d.getTime()) ? null : d.toISOString().slice(0, 10);
342
+ }
343
+
344
+ /**
345
+ * Index (dans ARRETES_RESEAU_CHALEUR) de l'arrêté réseau de chaleur utilisé par le générateur :
346
+ * - `date_arrete_reseau_chaleur` renseignée : dernier arrêté publié à cette date ou avant ;
347
+ * - sinon : dernier arrêté applicable à la date d'établissement du DPE ;
348
+ * - date antérieure au premier arrêté ou illisible : premier arrêté.
349
+ * @param dateArrete {string|undefined} date_arrete_reseau_chaleur du générateur
350
+ * @param dateDpe {string|undefined} date d'établissement du DPE
351
+ * @returns {number}
352
+ */
353
+ export function indexArreteReseauChaleur(dateArrete, dateDpe) {
354
+ const arrete = isoDate(dateArrete);
355
+ const ref = arrete ?? isoDate(dateDpe);
356
+ const champ = arrete ? 'date_arrete' : 'date_application';
357
+ let index = 0;
358
+ if (ref) {
359
+ ARRETES_RESEAU_CHALEUR.forEach((a, i) => {
360
+ if (a[champ] <= ref) index = i;
361
+ });
362
+ }
363
+ return index;
364
+ }
365
+
366
+ /**
367
+ * Contenu CO2 d'un réseau de chaleur répertorié (kgCO2/kWh).
368
+ *
369
+ * Le facteur réglementaire est le contenu CO2 en analyse de cycle de vie (`contenu_co2_acv`) de la
370
+ * table publiée par l'arrêté utilisé. Si l'identifiant n'y figure pas (réseau retiré d'un arrêté plus
371
+ * récent), on retient la table antérieure la plus récente qui le contient. Réseau introuvable :
372
+ * facteur « autres réseaux de chaleur » (0,385).
373
+ *
374
+ * Mode bug_for_bug_compat : avec l'arrêté du 05/07/2024 (table reseau_chaleur_2023), LICIEL
375
+ * transmet au moteur le contenu CO2 hors ACV (`contenu_co2`) : 1 226/1 234 générateurs LICIEL des
376
+ * corpus immeuble, alors que DPEWIN, Pleiades et 4.1.1 exportent la valeur ACV (ex. réseau 6403C
377
+ * de Pau : 0,047 au lieu de 0,061).
378
+ *
379
+ * @param identifiant_reseau {string}
380
+ * @param dateArrete {string|undefined}
381
+ * @param dateDpe {string|undefined}
382
+ * @param versionLogiciel {string|undefined} administratif.diagnostiqueur.version_logiciel
383
+ * @returns {number}
384
+ */
385
+ export function getContenuCo2ReseauChaleur(
386
+ identifiant_reseau,
387
+ dateArrete,
388
+ dateDpe,
389
+ versionLogiciel
390
+ ) {
391
+ const index = indexArreteReseauChaleur(dateArrete, dateDpe);
392
+
393
+ for (let i = index; i >= 0; i--) {
394
+ const { table } = ARRETES_RESEAU_CHALEUR[i];
395
+ const row = tv(table, { identifiant_reseau });
396
+ if (row) {
397
+ const contenuHorsAcv =
398
+ bug_for_bug_compat &&
399
+ table === 'reseau_chaleur_2023' &&
400
+ /liciel/i.test(versionLogiciel || '');
401
+ return Number(contenuHorsAcv ? row.contenu_co2 : row.contenu_co2_acv);
402
+ }
403
+ }
404
+
405
+ console.error(
406
+ `Aucun coefficient GES trouvé pour le réseau de chaleur ${identifiant_reseau} : valeur « autres réseaux de chaleur » ${COEF_GES_AUTRES_RESEAUX_CHALEUR}`
407
+ );
408
+ return COEF_GES_AUTRES_RESEAUX_CHALEUR;
409
+ }
410
+
314
411
  /**
315
412
  * Récupération du coefficient d'émission GES pour le générateur
316
413
  * @param gen_ch {GenerateurChauffageItem||GenerateurEcsItem}
317
414
  * @param suffix {'ch'|'ecs'}
318
415
  * @param dateDpe {string} date d'établissement du DPE
416
+ * @param versionLogiciel {string} version du logiciel de saisie
319
417
  * @returns {number}
320
418
  */
321
- function getGesCoeffForGenerateur(gen_ch, suffix, dateDpe) {
419
+ function getGesCoeffForGenerateur(gen_ch, suffix, dateDpe, versionLogiciel) {
322
420
  const typeEnergie = getTypeEnergie(gen_ch.donnee_entree, suffix);
323
421
 
324
- let anneeDpe;
325
- try {
326
- if (gen_ch.donnee_entree.date_arrete_reseau_chaleur) {
327
- anneeDpe = new Date(gen_ch.donnee_entree.date_arrete_reseau_chaleur).getFullYear() - 1;
328
- } else {
329
- anneeDpe = new Date(dateDpe).getFullYear() - 1;
330
- }
331
-
332
- if (anneeDpe < 2024) {
333
- anneeDpe = 2022;
334
- }
335
- } catch (e) {
336
- anneeDpe = 2022;
337
- }
338
-
339
- const key_reseau_chaleur = `reseau_chaleur_${anneeDpe}`;
340
-
341
422
  /**
342
423
  * Cas spécifique des réseaux de chaleur urbain qui ont des coefficients différents en fonction de réseau de distribution
343
424
  */
344
425
  if (typeEnergie === 'réseau de chauffage urbain') {
345
- const identifiant_reseau = gen_ch.donnee_entree.identifiant_reseau_chaleur;
346
-
347
- if (identifiant_reseau) {
348
- const row = tv(key_reseau_chaleur, { identifiant_reseau });
349
-
350
- if (row) {
351
- return row.contenu_co2_acv;
352
- } else {
353
- console.error(`
354
- Aucun coefficient GES trouvé pour le réseau de chaleur ${identifiant_reseau}
355
- `);
356
- }
357
- } else {
358
- // Prendre la valeur pour "AUTRES RESEAUX DE CHALEUR"
359
- return 0.385;
426
+ const { identifiant_reseau_chaleur, date_arrete_reseau_chaleur } = gen_ch.donnee_entree;
427
+
428
+ if (identifiant_reseau_chaleur) {
429
+ return getContenuCo2ReseauChaleur(
430
+ identifiant_reseau_chaleur,
431
+ date_arrete_reseau_chaleur,
432
+ dateDpe,
433
+ versionLogiciel
434
+ );
360
435
  }
436
+ // Prendre la valeur pour "AUTRES RESEAUX DE CHALEUR"
437
+ return COEF_GES_AUTRES_RESEAUX_CHALEUR;
361
438
  }
362
439
 
363
440
  return coef_ges[typeEnergie] ?? 1;
@@ -377,7 +454,8 @@ export default function calc_conso(
377
454
  coeffEp,
378
455
  nbLogements = 1,
379
456
  ratioSurfaceCollectif = 1,
380
- facteursAc = {}
457
+ facteursAc = {},
458
+ versionLogiciel = undefined
381
459
  ) {
382
460
  const gen_ch = ch.reduce((acc, ch) => {
383
461
  const generateur_chauffage = ch.generateur_chauffage_collection.generateur_chauffage;
@@ -393,7 +471,7 @@ export default function calc_conso(
393
471
  ch.donnee_entree.enum_methode_calcul_conso_id;
394
472
  value.donnee_entree.enum_type_installation_id = ch.donnee_entree.enum_type_installation_id;
395
473
  (value.donnee_utilisateur = value.donnee_utilisateur || {}).coeffEmissionGes =
396
- getGesCoeffForGenerateur(value, 'ch', dateDpe);
474
+ getGesCoeffForGenerateur(value, 'ch', dateDpe, versionLogiciel);
397
475
  });
398
476
  return acc.concat(generateur_chauffage);
399
477
  }, []);
@@ -408,7 +486,7 @@ export default function calc_conso(
408
486
  value.donnee_entree.cle_repartition_ecs =
409
487
  (ecs.donnee_entree.cle_repartition_ecs || 1) * (ecs.donnee_entree.rdim || 1);
410
488
  (value.donnee_utilisateur = value.donnee_utilisateur || {}).coeffEmissionGes =
411
- getGesCoeffForGenerateur(value, 'ecs', dateDpe);
489
+ getGesCoeffForGenerateur(value, 'ecs', dateDpe, versionLogiciel);
412
490
  });
413
491
  }
414
492
  return acc.concat(generateur_ecs);