@open3cl/engine 1.11.2 → 1.11.4

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.
Files changed (154) hide show
  1. package/10_besoin_fr.spec.js +1 -1
  2. package/10_clim.js +1 -1
  3. package/10_clim.spec.js +5 -9
  4. package/11_besoin_ecs.spec.js +1 -1
  5. package/11_ecs.js +2 -1
  6. package/11_ecs.spec.js +2 -2
  7. package/11_nadeq.js +1 -0
  8. package/11_nadeq.spec.js +1 -1
  9. package/11_rdim_ecs_individuelle_unique.js +78 -0
  10. package/11_rdim_ecs_individuelle_unique.spec.js +136 -0
  11. package/12.4_pac.js +5 -3
  12. package/12.4_pac.spec.js +10 -18
  13. package/13.2_generateur_combustion.js +19 -16
  14. package/13.2_generateur_combustion.spec.js +10 -10
  15. package/13.2_generateur_combustion_bouilleur.js +5 -2
  16. package/13.2_generateur_combustion_bouilleur.spec.js +1 -1
  17. package/13.2_generateur_combustion_ch.js +8 -7
  18. package/13.2_generateur_combustion_ch.spec.js +7 -7
  19. package/13.2_generateur_combustion_chaudiere.js +5 -2
  20. package/13.2_generateur_combustion_chaudiere.spec.js +2 -2
  21. package/13.2_generateur_combustion_pdim.js +6 -6
  22. package/13.2_generateur_combustion_pdim.spec.js +1 -1
  23. package/13.2_generateur_combustion_pn.spec.js +1 -1
  24. package/13.2_generateur_pac.js +4 -1
  25. package/13.2_generateur_pac.spec.js +1 -1
  26. package/13_rendement_distribution_ecs.spec.js +1 -1
  27. package/14_generateur_ecs.js +2 -1
  28. package/14_generateur_ecs.spec.js +4 -4
  29. package/15_conso_aux.js +19 -17
  30. package/15_conso_aux.spec.js +8 -8
  31. package/16.2_production_enr.js +4 -3
  32. package/16.2_production_enr.spec.js +1 -1
  33. package/16_conso_eclairage.spec.js +1 -1
  34. package/2021_04_13_confort_ete.spec.js +1 -1
  35. package/2021_04_13_qualite_isolation.js +1 -1
  36. package/2021_04_13_qualite_isolation.spec.js +2 -2
  37. package/3.1_b.spec.js +1 -1
  38. package/3.2.1_mur.js +10 -9
  39. package/3.2.1_mur.spec.js +11 -19
  40. package/3.2.2_plancher_bas.js +4 -3
  41. package/3.2.2_plancher_bas.spec.js +10 -20
  42. package/3.2.3_plancher_haut.js +1 -1
  43. package/3.2.3_plancher_haut.spec.js +2 -2
  44. package/3.3.1.4_porte.js +1 -1
  45. package/3.3.1.4_porte.spec.js +2 -2
  46. package/3.3_baie_vitree.js +2 -2
  47. package/3.3_baie_vitree.spec.js +3 -3
  48. package/3.4_pont_thermique.js +6 -4
  49. package/3.4_pont_thermique.spec.js +7 -7
  50. package/3_deperdition.js +1 -0
  51. package/3_deperdition.spec.js +3 -3
  52. package/4_ventilation.js +2 -2
  53. package/4_ventilation.spec.js +1 -1
  54. package/5_conso_ventilation.spec.js +1 -1
  55. package/6.1_apport_gratuit.spec.js +2 -2
  56. package/6.2_surface_sud_equivalente.js +12 -9
  57. package/6.2_surface_sud_equivalente.spec.js +3 -3
  58. package/7_inertie.js +7 -4
  59. package/7_inertie.spec.js +1 -1
  60. package/8_intermittence.spec.js +1 -1
  61. package/9_besoin_ch.js +5 -3
  62. package/9_besoin_ch.spec.js +3 -3
  63. package/9_chauffage.js +12 -11
  64. package/9_chauffage.spec.js +7 -7
  65. package/9_conso_ch.spec.js +3 -3
  66. package/9_emetteur_ch.js +5 -5
  67. package/9_emetteur_ch.spec.js +1 -1
  68. package/9_generateur_ch.js +16 -13
  69. package/9_generateur_ch.spec.js +6 -6
  70. package/README.md +19 -19
  71. package/apport_et_besoin.spec.js +1 -1
  72. package/conso.js +18 -14
  73. package/conso.spec.js +3 -3
  74. package/core/assets/domain/synchronize-assets.js +2 -0
  75. package/core/assets/domain/synchronize-c1-tables.js +2 -0
  76. package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.js +2 -0
  77. package/core/assets/domain/synchronize-enum-tables.js +2 -0
  78. package/core/assets/domain/synchronize-solicitations-tables.js +2 -0
  79. package/core/assets/domain/synchronize-valeur-tables.js +6 -0
  80. package/core/file/infrastructure/adapter/csv-parser.store.js +2 -1
  81. package/dpe-sanitizer.service.js +1 -0
  82. package/engine.js +11 -2
  83. package/engine.spec.js +23 -2
  84. package/enums.d.ts +1257 -0
  85. package/features/dpe/domain/models/baie-ets.model.ts +8 -11
  86. package/features/dpe/domain/models/baie-vitree.model.ts +28 -96
  87. package/features/dpe/domain/models/climatisation.model.ts +13 -23
  88. package/features/dpe/domain/models/dpe-xsd.generated.ts +2797 -0
  89. package/features/dpe/domain/models/dpe.model.ts +105 -181
  90. package/features/dpe/domain/models/ets.model.ts +10 -18
  91. package/features/dpe/domain/models/installation-chauffage.model.ts +92 -99
  92. package/features/dpe/domain/models/installation-ecs.model.ts +45 -77
  93. package/features/dpe/domain/models/mur.model.ts +10 -38
  94. package/features/dpe/domain/models/plancher.model.ts +22 -63
  95. package/features/dpe/domain/models/pont-thermique.model.ts +10 -20
  96. package/features/dpe/domain/models/porte.model.ts +10 -30
  97. package/features/dpe/domain/models/production-elec-enr.model.ts +13 -27
  98. package/features/dpe/domain/models/sortie.model.ts +32 -176
  99. package/features/dpe/domain/models/type-generateur.model.js +4 -3
  100. package/features/dpe/domain/models/type-habitation.model.js +8 -6
  101. package/features/dpe/domain/models/type-stockage.model.js +4 -3
  102. package/features/dpe/domain/models/type-ventilation.model.js +4 -3
  103. package/features/dpe/domain/models/ventilation.model.ts +15 -25
  104. package/features/dpe/infrastructure/ch/chTv.store.js +2 -2
  105. package/features/dpe/infrastructure/ecs/ecsTv.store.js +3 -3
  106. package/features/dpe/infrastructure/enveloppe/baieVitreeTv.store.js +1 -1
  107. package/features/dpe/infrastructure/froid/frTv.store.js +3 -3
  108. package/features/dpe/infrastructure/froid/frTv.store.spec.js +1 -1
  109. package/features/dpe/infrastructure/tv.store.js +1 -1
  110. package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.js +3 -0
  111. package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.js +3 -1
  112. package/features/engine/domain/apport_et_besoin/ch/besoin-ch.service.js +3 -1
  113. package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.js +9 -3
  114. package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +1 -1
  115. package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.js +2 -1
  116. package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.js +4 -1
  117. package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.js +3 -1
  118. package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.js +7 -2
  119. package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +1 -1
  120. package/features/engine/domain/ch/emetteur-ch.service.js +3 -1
  121. package/features/engine/domain/ch/emetteur-ch.service.spec.js +1 -1
  122. package/features/engine/domain/ch/generateur-ch.service.js +4 -1
  123. package/features/engine/domain/ch/generateur-ch.service.spec.js +3 -3
  124. package/features/engine/domain/ch/installation-ch.service.js +2 -0
  125. package/features/engine/domain/conso/conso.service.js +2 -0
  126. package/features/engine/domain/conso/froid/conso-froid.service.js +5 -1
  127. package/features/engine/domain/contexte.builder.js +2 -0
  128. package/features/engine/domain/ecs/generateur-ecs.service.js +1 -0
  129. package/features/engine/domain/ecs/installation-ecs.service.js +3 -0
  130. package/features/engine/domain/engine.service.js +1 -0
  131. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +4 -1
  132. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +3 -0
  133. package/features/engine/domain/enveloppe/deperdition.service.js +8 -4
  134. package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.js +4 -1
  135. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +3 -1
  136. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +3 -1
  137. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +2 -2
  138. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +4 -2
  139. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +9 -1
  140. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +1 -1
  141. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +3 -1
  142. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +3 -1
  143. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +1 -1
  144. package/features/engine/domain/logement/nadeq.service.js +1 -1
  145. package/features/engine/domain/logement/nadeq.service.spec.js +1 -1
  146. package/features/engine/domain/models/contexte.model.ts +2 -2
  147. package/features/normalizer/domain/dpe-normalizer.service.js +1 -0
  148. package/ficheTechnique.js +4 -2
  149. package/globals.d.ts +14 -0
  150. package/package.json +3 -2
  151. package/preprocessor/index.js +1 -0
  152. package/tv.d.ts +759 -0
  153. package/tvs.d.ts +2 -7
  154. package/utils.js +8 -6
@@ -38,7 +38,7 @@ const { calc_sse_j } = await import('./6.2_surface_sud_equivalente.js');
38
38
 
39
39
  /**
40
40
  * 10. Calcul des besoins de froid (Bfr)
41
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
41
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
42
42
  */
43
43
  describe('calc_besoin_fr_j - besoin de froid journalier', () => {
44
44
  test('retourne 0 lorsque le nombre de jours de référence est nul', () => {
package/10_clim.js CHANGED
@@ -5,7 +5,7 @@ function tv_seer(di, de, du, zc_id) {
5
5
  enum_zone_climatique_id: zc_id,
6
6
  enum_periode_installation_fr_id: requestInputID(de, du, 'periode_installation_fr')
7
7
  };
8
- const row = tv('seer', matcher, de);
8
+ const row = tv('seer', matcher);
9
9
  if (row) {
10
10
  de.tv_seer_id = Number(row.tv_seer_id);
11
11
  di.eer = row.eer;
package/10_clim.spec.js CHANGED
@@ -31,7 +31,7 @@ beforeEach(() => {
31
31
 
32
32
  /**
33
33
  * 10. Calcul de la consommation de climatisation (froid)
34
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
34
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
35
35
  */
36
36
  describe('calc_clim - consommation de climatisation', () => {
37
37
  test('prorate le besoin de froid au ratio surface_clim / Sh', () => {
@@ -69,14 +69,10 @@ describe('calc_clim - consommation de climatisation', () => {
69
69
 
70
70
  calc_clim(c, 1000, 1500, '2', 100);
71
71
 
72
- expect(tv).toHaveBeenCalledWith(
73
- 'seer',
74
- {
75
- enum_zone_climatique_id: '2',
76
- enum_periode_installation_fr_id: '4'
77
- },
78
- c.donnee_entree
79
- );
72
+ expect(tv).toHaveBeenCalledWith('seer', {
73
+ enum_zone_climatique_id: '2',
74
+ enum_periode_installation_fr_id: '4'
75
+ });
80
76
  });
81
77
 
82
78
  test.each([['6'], ['7'], ['8']])(
@@ -23,7 +23,7 @@ const { default: calc_besoin_ecs, calc_besoin_ecs_j } = await import('./11_besoi
23
23
 
24
24
  /**
25
25
  * 11. Calcul du besoin d'eau chaude sanitaire (Becs)
26
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §11
26
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §11
27
27
  */
28
28
  describe('calc_besoin_ecs_j - besoin ECS journalier', () => {
29
29
  test('valeur de référence en mode conventionnel (56 L/j/personne)', () => {
package/11_ecs.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @import { InstallationEcsDE } from './features/dpe/domain/models/installation-ecs.model.js' */
1
2
  import enums from './enums.js';
2
3
  import calc_gen_ecs from './14_generateur_ecs.js';
3
4
  import { tv, requestInput, mois_liste, Njj } from './utils.js';
@@ -196,7 +197,7 @@ const TYPES_INSTALLATION_ECS_COLLECTIVE = ['2', '3'];
196
197
  * @see Moteur_DPE.dll Calcul_batiment.cs l.583-592 (Becs / Rdim seulement pour une installation
197
198
  * individuelle en immeuble ; Becs × Sh_ecs / SH sans Rdim pour une installation collective)
198
199
  * @param th {string} type de bâtiment (maison, appartement, immeuble)
199
- * @param de {Donnee_entree} donnée d'entrée de l'installation ECS
200
+ * @param de {InstallationEcsDE} donnée d'entrée de l'installation ECS
200
201
  * @returns {boolean}
201
202
  */
202
203
  export function isRdimEcsNeutralise(th, de) {
package/11_ecs.spec.js CHANGED
@@ -61,7 +61,7 @@ beforeEach(() => {
61
61
 
62
62
  /**
63
63
  * 11. Prise en compte de l'ECS (ratio de besoin + rendement de distribution)
64
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §11 / §17.2.1
64
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §11 / §17.2.1
65
65
  */
66
66
  describe('calc_ecs - ratio de besoin ECS', () => {
67
67
  test('virtualisation : le ratio est la clé de répartition ECS', () => {
@@ -87,7 +87,7 @@ describe('calc_ecs - ratio de besoin ECS', () => {
87
87
  * Immeuble à ECS individuelles de surfaces différentes (cas CSTB IC1-0-3 / IC1-0-5 : 4
88
88
  * appartements de 20, 30, 45 et 80 m² sur 175 m², rdim 1) : besoin au prorata de la surface
89
89
  * desservie, comme Tribu (Becs appartement 1 = Becs immeuble × 20 / 175).
90
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §11.4
90
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §11.4
91
91
  */
92
92
  test('immeuble à ECS individuelles : ratio = surface desservie / surface de l’immeuble', () => {
93
93
  const des = [20, 30, 45, 80].map((surface) => ({
package/11_nadeq.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @import { Logement } from './features/dpe/domain/models/dpe.model.js' */
1
2
  export class Nadeq {
2
3
  /**
3
4
  * Return nadeq for maison or individual logement
package/11_nadeq.spec.js CHANGED
@@ -3,7 +3,7 @@ import { describe, expect, test } from 'vitest';
3
3
 
4
4
  describe('Nadeq unit tests', () => {
5
5
  /**
6
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf Page 70
6
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf Page 70
7
7
  */
8
8
  const nadeq = new Nadeq();
9
9
 
@@ -60,3 +60,81 @@ export function reconstituerRdimEcsIndividuelleUnique(th, instal_ecs, surfaceHab
60
60
  instal_ecs[0].donnee_entree.rdim_reconstitue = true;
61
61
  return true;
62
62
  }
63
+
64
+ /**
65
+ * DPE immeuble avec plusieurs installations ECS individuelles, chacune décrite pour un logement type.
66
+ *
67
+ * Même convention d'export que l'installation unique (3.0.x, 2.0.x, 1.1.x) : pour chaque
68
+ * installation i, `surface_habitable` = Sh_i d'un logement type et `nombre_logement` = N_i, sans
69
+ * `rdim`, avec Σ Sh_i × N_i = SH. Tribu traite chaque installation indépendamment avec Rdim_i = N_i :
70
+ * Becs_i = Becs_immeuble × Sh_i × Rdim_i / SH / Rdim_i, puis Cecs = Σ Cecs_i × Rdim_i. L'export ADEME
71
+ * le confirme : besoin_ecs_i = Becs_immeuble × Sh_i / SH et conso_ecs = Σ conso_ecs_i × N_i.
72
+ *
73
+ * Sans rdim, Σ Sh_i ≠ SH : Open3CL se replie sur Becs_immeuble / nombre_appartement par
74
+ * installation et ne remultiplie pas la conso par N_i.
75
+ *
76
+ * Gardes :
77
+ * - Σ Sh_i × N_i ≈ SH (TOLERANCE_SURFACE_LOGEMENT_TYPE) : exclut les exports où Sh_i est déjà
78
+ * la surface totale desservie (Σ Sh_i = SH, ex. N_i fractionnaires) ;
79
+ * - au moins un N_i > 1 : sinon rdim = 1 partout, sans effet (LICIEL, nombre_logement = 1).
80
+ *
81
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - § 11.4 et § 17.1.3.2
82
+ * @see Tribu : Calcul_batiment.cs l. 581-588 (boucle par installation, Ratio = Sh·Rdim/SH,
83
+ * Becs / Rdim), l. 1660-1662 (Cecs_i / Rdim puis × Rdim) ; Calcul_installation_ECS.cs l. 75
84
+ * @see Guide Tribu TE-211208 « Particularités d'une répétition de systèmes d'ECS individuel dans un
85
+ * immeuble collectif » (Sh_ecs = surface d'un logement, Rdim = nombre d'installations identiques)
86
+ */
87
+
88
+ /**
89
+ * Rdim implicites des installations ECS individuelles multiples d'un immeuble (dans l'ordre des
90
+ * installations), ou null si non concernées.
91
+ *
92
+ * @param th {string} type de bâtiment (maison, appartement, immeuble)
93
+ * @param instal_ecs {Array} installation_ecs
94
+ * @param surfaceHabitableImmeuble {number|string} surface habitable de l'immeuble (SH)
95
+ * @return {number[]|null}
96
+ */
97
+ export function rdimsImplicitesEcsIndividuellesMultiples(th, instal_ecs, surfaceHabitableImmeuble) {
98
+ if (th !== 'immeuble' || !Array.isArray(instal_ecs) || instal_ecs.length < 2) return null;
99
+
100
+ const des = instal_ecs.map((inst) => inst?.donnee_entree);
101
+ const concernees = des.every(
102
+ (de) => de && String(de.enum_type_installation_id) === '1' && !de.rdim
103
+ );
104
+ if (!concernees) return null;
105
+
106
+ const SH = Number(surfaceHabitableImmeuble);
107
+ if (!(SH > 0)) return null;
108
+
109
+ const surfaces = des.map((de) => Number(de.surface_habitable));
110
+ const rdims = des.map((de) => Number(de.nombre_logement) || 1);
111
+ if (!surfaces.every((sh) => sh > 0) || !rdims.every((n) => n > 0)) return null;
112
+ if (!rdims.some((n) => n > 1)) return null;
113
+
114
+ const sommeShN = surfaces.reduce((acc, sh, i) => acc + sh * rdims[i], 0);
115
+ return Math.abs(sommeShN - SH) <= TOLERANCE_SURFACE_LOGEMENT_TYPE * SH ? rdims : null;
116
+ }
117
+
118
+ /**
119
+ * Reconstitue le rdim des installations ECS individuelles multiples d'un immeuble décrites pour un
120
+ * logement type. Chaque installation reçoit `rdim` = nombre_logement (1 si absent) et le flag
121
+ * `rdim_reconstitue`.
122
+ *
123
+ * @param th {string} type de bâtiment
124
+ * @param instal_ecs {Array} installation_ecs
125
+ * @param surfaceHabitableImmeuble {number|string} surface habitable de l'immeuble (SH)
126
+ * @return {boolean} true si les rdim ont été reconstitués
127
+ */
128
+ export function reconstituerRdimEcsIndividuellesMultiples(
129
+ th,
130
+ instal_ecs,
131
+ surfaceHabitableImmeuble
132
+ ) {
133
+ const rdims = rdimsImplicitesEcsIndividuellesMultiples(th, instal_ecs, surfaceHabitableImmeuble);
134
+ if (rdims === null) return false;
135
+ instal_ecs.forEach((inst, i) => {
136
+ inst.donnee_entree.rdim = rdims[i];
137
+ inst.donnee_entree.rdim_reconstitue = true;
138
+ });
139
+ return true;
140
+ }
@@ -1,7 +1,9 @@
1
1
  import { describe, expect, test } from 'vitest';
2
2
  import {
3
3
  rdimImpliciteEcsIndividuelleUnique,
4
+ rdimsImplicitesEcsIndividuellesMultiples,
4
5
  reconstituerRdimEcsIndividuelleUnique,
6
+ reconstituerRdimEcsIndividuellesMultiples,
5
7
  TOLERANCE_SURFACE_LOGEMENT_TYPE
6
8
  } from './11_rdim_ecs_individuelle_unique.js';
7
9
 
@@ -111,3 +113,137 @@ describe("Rdim de l'installation ECS individuelle unique d'un immeuble", () => {
111
113
  });
112
114
  });
113
115
  });
116
+
117
+ /**
118
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - § 11.4 et § 17.1.3.2
119
+ * @see Tribu : Calcul_batiment.cs l. 581-588 et l. 1660-1662 ; Calcul_installation_ECS.cs l. 75
120
+ */
121
+ describe("Rdim des installations ECS individuelles multiples d'un immeuble", () => {
122
+ /** Installation ECS individuelle décrite pour un logement type */
123
+ const inst = (surface_habitable, nombre_logement, de = {}) => ({
124
+ donnee_entree: { enum_type_installation_id: '1', surface_habitable, nombre_logement, ...de }
125
+ });
126
+ /** Cas type 2244E3039157K : 48,82 × 2 + 78,09 × 6 = 566,18 ≈ SH = 566,16 */
127
+ const ecs = () => [inst(48.82, 2), inst(78.09, 6)];
128
+
129
+ describe('rdimsImplicitesEcsIndividuellesMultiples', () => {
130
+ test('installations individuelles, Σ Sh × N = SH, sans rdim : rdim_i = nombre_logement_i', () => {
131
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), 566.16)).toEqual([2, 6]);
132
+ expect(
133
+ rdimsImplicitesEcsIndividuellesMultiples(
134
+ 'immeuble',
135
+ [
136
+ inst('48.82', '2', { enum_type_installation_id: 1 }),
137
+ inst('78.09', '6', { enum_type_installation_id: 1 })
138
+ ],
139
+ '566.16'
140
+ )
141
+ ).toEqual([2, 6]);
142
+ });
143
+
144
+ test('nombre_logement absent sur une installation : rdim = 1 pour celle-ci', () => {
145
+ // 100 × 4 + 50 × 1 = 450
146
+ expect(
147
+ rdimsImplicitesEcsIndividuellesMultiples(
148
+ 'immeuble',
149
+ [inst(100, 4), inst(50, undefined)],
150
+ 450
151
+ )
152
+ ).toEqual([4, 1]);
153
+ });
154
+
155
+ test('tolérance de 5 % sur Σ Sh × N ≈ SH', () => {
156
+ // Σ = 100 × 4 + 50 × 2 = 500 ; |500 − SH| ≤ 0,05 × SH ⇔ 476,19 ≤ SH ≤ 526,31
157
+ const deux = () => [inst(100, 4), inst(50, 2)];
158
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 526)).toEqual([4, 2]);
159
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 477)).toEqual([4, 2]);
160
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 527)).toBeNull();
161
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 476)).toBeNull();
162
+ });
163
+
164
+ test('surfaces exportées comme surface totale desservie (Σ Sh = SH) : non concerné', () => {
165
+ // Cas type 2224E1374434V : 74,4 × 3 + 31 × 1 = 254,2 ≠ SH = 105,4 = Σ Sh
166
+ expect(
167
+ rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(74.4, 3), inst(31, 1)], 105.4)
168
+ ).toBeNull();
169
+ });
170
+
171
+ test('tous les nombre_logement à 1 (LICIEL) : non concerné', () => {
172
+ expect(
173
+ rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(60, 1), inst(40, 1)], 100)
174
+ ).toBeNull();
175
+ });
176
+
177
+ test('un rdim exporté sur une installation : on conserve la saisie', () => {
178
+ expect(
179
+ rdimsImplicitesEcsIndividuellesMultiples(
180
+ 'immeuble',
181
+ [inst(48.82, 2, { rdim: 2 }), inst(78.09, 6)],
182
+ 566.16
183
+ )
184
+ ).toBeNull();
185
+ });
186
+
187
+ test('une installation collective : non concerné', () => {
188
+ expect(
189
+ rdimsImplicitesEcsIndividuellesMultiples(
190
+ 'immeuble',
191
+ [inst(48.82, 2), inst(78.09, 6, { enum_type_installation_id: '2' })],
192
+ 566.16
193
+ )
194
+ ).toBeNull();
195
+ });
196
+
197
+ test('maison ou appartement : non concerné', () => {
198
+ expect(rdimsImplicitesEcsIndividuellesMultiples('maison', ecs(), 566.16)).toBeNull();
199
+ expect(rdimsImplicitesEcsIndividuellesMultiples('appartement', ecs(), 566.16)).toBeNull();
200
+ });
201
+
202
+ test('installation unique : non concerné (cf. rdimImpliciteEcsIndividuelleUnique)', () => {
203
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(64, 10)], 640)).toBeNull();
204
+ });
205
+
206
+ test('données manquantes ou invalides : non concerné', () => {
207
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', undefined, 566.16)).toBeNull();
208
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', [], 566.16)).toBeNull();
209
+ expect(
210
+ rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(48.82, 2), {}], 566.16)
211
+ ).toBeNull();
212
+ expect(
213
+ rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(48.82, 2), null], 566.16)
214
+ ).toBeNull();
215
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), undefined)).toBeNull();
216
+ expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), 0)).toBeNull();
217
+ expect(
218
+ rdimsImplicitesEcsIndividuellesMultiples(
219
+ 'immeuble',
220
+ [inst(48.82, 2), inst(undefined, 6)],
221
+ 566.16
222
+ )
223
+ ).toBeNull();
224
+ expect(
225
+ rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(100, 4), inst(50, -2)], 300)
226
+ ).toBeNull();
227
+ });
228
+ });
229
+
230
+ describe('reconstituerRdimEcsIndividuellesMultiples', () => {
231
+ test('installations concernées : rdim et flag positionnés sur chacune', () => {
232
+ const installations = ecs();
233
+ expect(reconstituerRdimEcsIndividuellesMultiples('immeuble', installations, 566.16)).toBe(
234
+ true
235
+ );
236
+ expect(installations[0].donnee_entree).toMatchObject({ rdim: 2, rdim_reconstitue: true });
237
+ expect(installations[1].donnee_entree).toMatchObject({ rdim: 6, rdim_reconstitue: true });
238
+ });
239
+
240
+ test('installations non concernées : inchangées', () => {
241
+ const installations = [inst(60, 1), inst(40, 1)];
242
+ expect(reconstituerRdimEcsIndividuellesMultiples('immeuble', installations, 100)).toBe(false);
243
+ installations.forEach((i) => {
244
+ expect(i.donnee_entree.rdim).toBeUndefined();
245
+ expect(i.donnee_entree.rdim_reconstitue).toBeUndefined();
246
+ });
247
+ });
248
+ });
249
+ });
package/12.4_pac.js CHANGED
@@ -1,9 +1,11 @@
1
+ /** @import { GenerateurChauffageDE, GenerateurChauffageDI } from './features/dpe/domain/models/installation-chauffage.model.js' */
2
+ /** @import { GenerateurEcsDE, GenerateurEcsDI } from './features/dpe/domain/models/installation-ecs.model.js' */
1
3
  import { requestInputID, tv } from './utils.js';
2
4
 
3
5
  /**
4
6
  * Calcul ou récupération des paramètres scop ou cop
5
- * @param di {Donnee_intermediaire}
6
- * @param de {Donnee_entree}
7
+ * @param di {GenerateurChauffageDI|GenerateurEcsDI}
8
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
7
9
  * @param du {Object}
8
10
  * @param zc_id {string}
9
11
  * @param ed_id {string|null}
@@ -31,7 +33,7 @@ function tv_scop(di, de, du, zc_id, ed_id, type) {
31
33
  };
32
34
  matcher[`enum_type_generateur_${type}_id`] = requestInputID(de, du, `type_generateur_${type}`);
33
35
  if (ed_id) matcher.enum_type_emission_distribution_id = ed_id;
34
- const row = tv('scop', matcher, de);
36
+ const row = tv('scop', matcher);
35
37
  if (row) {
36
38
  const scop = row.scop_ou_cop;
37
39
  di[scop] = Number(row.scop);
package/12.4_pac.spec.js CHANGED
@@ -26,7 +26,7 @@ beforeEach(() => {
26
26
 
27
27
  /**
28
28
  * 12.4 - Détermination du SCOP / COP des pompes à chaleur.
29
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §12.4
29
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §12.4
30
30
  */
31
31
  describe('scopOrCop - méthode de saisie "caractéristiques saisies" (id 6)', () => {
32
32
  test('SCOP renseigné : rg et rg_dep prennent la valeur du SCOP sans accès à la table', () => {
@@ -55,14 +55,10 @@ describe('scopOrCop - valeur forfaitaire (table scop)', () => {
55
55
 
56
56
  scopOrCop(di, de, {}, 'h1a', null, 'ch');
57
57
 
58
- expect(tv).toHaveBeenCalledWith(
59
- 'scop',
60
- {
61
- enum_zone_climatique_id: 'h1a',
62
- enum_type_generateur_ch_id: '160'
63
- },
64
- de
65
- );
58
+ expect(tv).toHaveBeenCalledWith('scop', {
59
+ enum_zone_climatique_id: 'h1a',
60
+ enum_type_generateur_ch_id: '160'
61
+ });
66
62
  expect(di.scop).toBe(4.2);
67
63
  expect(di.rg).toBe(4.2);
68
64
  expect(di.rg_dep).toBe(4.2);
@@ -76,15 +72,11 @@ describe('scopOrCop - valeur forfaitaire (table scop)', () => {
76
72
 
77
73
  scopOrCop(di, de, {}, 'h2b', '5', 'ecs');
78
74
 
79
- expect(tv).toHaveBeenCalledWith(
80
- 'scop',
81
- {
82
- enum_zone_climatique_id: 'h2b',
83
- enum_type_generateur_ecs_id: '10',
84
- enum_type_emission_distribution_id: '5'
85
- },
86
- de
87
- );
75
+ expect(tv).toHaveBeenCalledWith('scop', {
76
+ enum_zone_climatique_id: 'h2b',
77
+ enum_type_generateur_ecs_id: '10',
78
+ enum_type_emission_distribution_id: '5'
79
+ });
88
80
  // scop_ou_cop vaut 'cop' : la valeur est stockée sous di.cop
89
81
  expect(di.cop).toBe(3.1);
90
82
  expect(di.rg).toBe(3.1);
@@ -1,3 +1,6 @@
1
+ /** @import { FullDpe } from './features/dpe/domain/models/dpe.model.js' */
2
+ /** @import { GenerateurChauffage, GenerateurChauffageDE, GenerateurChauffageDI, InstallationChauffage } from './features/dpe/domain/models/installation-chauffage.model.js' */
3
+ /** @import { GenerateurEcsDE, GenerateurEcsDI } from './features/dpe/domain/models/installation-ecs.model.js' */
1
4
  import { bug_for_bug_compat, convertExpression, tv, tvColumnLines } from './utils.js';
2
5
  import enums from './enums.js';
3
6
  import { updateGenerateurBouilleurs } from './13.2_generateur_combustion_bouilleur.js';
@@ -63,7 +66,7 @@ export const PN_MAX_QP0_CHAUDIERE_GAZ = 400000;
63
66
  * (Tribu, `Calcul_generateur.cs` Rpn_chaudieregaz, `Math.Min(400.0, Pn)`) plafonne Pn à 400 kW :
64
67
  * au-delà, la formule n'est plus représentative (elle décroît et devient négative vers 1 500 kW).
65
68
  * Le plafond ne s'applique pas aux chaudières fioul (Rpn_chaudierefioul : Pn non plafonné).
66
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
69
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
67
70
  *
68
71
  * @param row {object} ligne de la table generateur_combustion
69
72
  * @param pnCollectif {number} puissance nominale du générateur (W)
@@ -154,7 +157,7 @@ export function pnEstimee(GV, tbase, ratioSurface = 1) {
154
157
  * pour le chauffage, 8 pour l'ECS) du générateur.
155
158
  *
156
159
  * @param dpe {FullDpe}
157
- * @param de {Donnee_entree}
160
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
158
161
  * @param type {'ch' | 'ecs'}
159
162
  * @returns {boolean|undefined} undefined si non renseigné
160
163
  */
@@ -170,7 +173,7 @@ export function chaudiereMurale(dpe, de, type) {
170
173
  * générateur ECS mixte de même `reference_generateur_mixte`, sinon générateur ECS mixte unique.
171
174
  *
172
175
  * @param dpe {FullDpe}
173
- * @param de {Donnee_entree} données du générateur de chauffage
176
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE} données du générateur de chauffage
174
177
  * @returns {number|undefined}
175
178
  */
176
179
  export function volumeStockageEcsMixte(dpe, de) {
@@ -200,7 +203,7 @@ export function volumeStockageEcsMixte(dpe, de) {
200
203
  * pour une installation collective, Pch est conservée (comportement historique).
201
204
  *
202
205
  * @param dpe {FullDpe}
203
- * @param de {Donnee_entree} données du générateur
206
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE} données du générateur
204
207
  * @param type {'ch' | 'ecs'}
205
208
  * @param pch {number} Pch (W) proratisée à la surface desservie
206
209
  * @param optionsPn {{installationIndividuelle?: boolean, volumeStockage?: number}}
@@ -249,8 +252,8 @@ export function pnEstimeeGenerateur(dpe, de, type, pch, optionsPn = {}) {
249
252
  * 5 - caractéristiques saisies à partir de la plaque signalétique ou d'une documentation technique du système à combustion : pn, rpn,rpint,qp0,temp_fonc_30,temp_fonc_100
250
253
  *
251
254
  * @param dpe {FullDpe}
252
- * @param di {Donnee_intermediaire} données du générateur
253
- * @param de {Donnee_entree} données du générateur
255
+ * @param di {GenerateurChauffageDI|GenerateurEcsDI} données du générateur
256
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE} données du générateur
254
257
  * @param type {'ecs'|'ch'}
255
258
  * @param GV {number} déperdition de l'enveloppe
256
259
  * @param tbase {number} température de fonctionnement du générateur
@@ -392,8 +395,8 @@ export function tv_generateur_combustion(
392
395
  * dans Cper). Le XML ne transporte pas cette donnée : elle est lue dans la fiche technique du
393
396
  * générateur. Sans fiche technique, la ventouse est conservée comme approximation (choix
394
397
  * Open3CL, la méthode ne prévoyant pas de valeur par défaut).
395
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
396
- * @see : Tribu Calcul_generateur.cs (ventilateur_combustion)
398
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
399
+ * @see Tribu Calcul_generateur.cs (ventilateur_combustion)
397
400
  */
398
401
  const indexEF = de.ventilateurCombustion ?? de.presence_ventouse;
399
402
  const E = E_tab[indexEF];
@@ -474,7 +477,7 @@ export function tv_generateur_combustion(
474
477
  /**
475
478
  * Mise à jour du type de générateur si besoin
476
479
  * @param dpe {FullDpe}
477
- * @param de {Donnee_entree}
480
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
478
481
  * @param type {'ch' | 'ecs'}
479
482
  */
480
483
  export function updateGenerateurCombustion(dpe, de, type) {
@@ -515,7 +518,7 @@ export function valeurVeilleuse(valeur) {
515
518
  * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.4 / §14.1 (« Pveil : si veilleuse »)
516
519
  *
517
520
  * @param dpe {FullDpe}
518
- * @param de {Donnee_entree}
521
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
519
522
  * @param type {'ch' | 'ecs'}
520
523
  * @returns {1 | 0 | undefined} 1 si veilleuse, 0 si pas de veilleuse, undefined si non renseigné
521
524
  */
@@ -558,7 +561,7 @@ export function presenceVeilleuse(dpe, de, type) {
558
561
  * Récupération d'informations complémentaires issues des fiches techniques pour les générateurs
559
562
  *
560
563
  * @param dpe {FullDpe}
561
- * @param de {Donnee_entree}
564
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
562
565
  * @param type {'ch' | 'ecs'}
563
566
  */
564
567
  function addInfosFromFichesTechniques(dpe, de, type) {
@@ -590,7 +593,7 @@ function addInfosFromFichesTechniques(dpe, de, type) {
590
593
  * Vérifier que les informations du générateur ECS sont bien les mêmes que celles du générateur de chauffage
591
594
  * Dans le cas d'une génération mixte, le type du générateur doit être le même
592
595
  * @param dpe {FullDpe}
593
- * @param de {Donnee_entree}
596
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
594
597
  * @param typeGenerateurKey {string}
595
598
  * @returns {string}
596
599
  */
@@ -612,7 +615,7 @@ function checkEcsVsChauffageForMixteGeneration(dpe, de, typeGenerateurKey) {
612
615
  }
613
616
 
614
617
  /**
615
- * @type {InstallationChauffageItem[]}
618
+ * @type {InstallationChauffage[]}
616
619
  */
617
620
  const installationsCh = dpe.logement.installation_chauffage_collection.installation_chauffage;
618
621
 
@@ -668,9 +671,9 @@ function checkEcsVsChauffageForMixteGeneration(dpe, de, typeGenerateurKey) {
668
671
  * 3. même énergie (`enum_type_energie_id`), si un seul générateur de chauffage mixte correspond ;
669
672
  * 4. générateur de chauffage mixte unique du DPE, si son énergie n'est pas incompatible.
670
673
  *
671
- * @param generateursChMixtes {GenerateurChauffageItem[]} générateurs de chauffage d'usage 'chauffage + ecs'
672
- * @param de {Donnee_entree} données du générateur ECS
673
- * @returns {GenerateurChauffageItem|null} null si aucun jumeau ne peut être identifié sans ambiguïté
674
+ * @param generateursChMixtes {GenerateurChauffage[]} générateurs de chauffage d'usage 'chauffage + ecs'
675
+ * @param de {GenerateurEcsDE} données du générateur ECS
676
+ * @returns {GenerateurChauffage|null} null si aucun jumeau ne peut être identifié sans ambiguïté
674
677
  */
675
678
  export function findGenerateurChMixteJumeau(generateursChMixtes, de) {
676
679
  const sameValue = (a, b) =>
@@ -121,7 +121,7 @@ const ROW_DEFAUT = {
121
121
 
122
122
  /**
123
123
  * 13.2 - Récupération des caractéristiques forfaitaires d'un générateur à combustion.
124
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2
124
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2
125
125
  */
126
126
  describe('tv_generateur_combustion - caractéristiques du générateur', () => {
127
127
  test('puissance nominale calculée à partir de GV et Tbase lorsqu’elle est absente', () => {
@@ -358,7 +358,7 @@ describe('tv_generateur_combustion - compatibilité bug_for_bug_compat', () => {
358
358
 
359
359
  /**
360
360
  * Système collectif par défaut : chaudière fioul standard datant de la construction du bâtiment.
361
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §17.2.1.1
361
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §17.2.1.1
362
362
  */
363
363
  describe('système collectif par défaut : chaudière selon l’année de construction', () => {
364
364
  test('CH 119 + ligne compatible : type et ligne de la période de construction retenus', () => {
@@ -668,7 +668,7 @@ describe('tv_generateur_combustion - génération mixte (checkEcsVsChauffageForM
668
668
  /**
669
669
  * Issue #210 : l'ECS mixte doit être appariée avec SON générateur de chauffage mixte (même appareil),
670
670
  * et non avec le premier générateur de chauffage mixte du DPE.
671
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §14
671
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §14
672
672
  */
673
673
  describe('findGenerateurChMixteJumeau - appariement ECS / chauffage mixte (issue #210)', () => {
674
674
  const ch = (donnees) => ({ donnee_entree: { enum_usage_generateur_id: '3', ...donnees } });
@@ -876,7 +876,7 @@ const dpeFiches = (...fiches) => ({
876
876
 
877
877
  /**
878
878
  * 13.2 - Orchestration des substitutions de générateurs et enrichissement fiches techniques.
879
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2
879
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2
880
880
  */
881
881
  describe('updateGenerateurCombustion - orchestration des substitutions', () => {
882
882
  test('délègue aux trois routines de substitution avec les mêmes arguments', () => {
@@ -983,7 +983,7 @@ describe('updateGenerateurCombustion - orchestration des substitutions', () => {
983
983
  /**
984
984
  * Issue #35 : les coefficients (E, F) de la formule qp0 dépendent de la présence d'un ventilateur
985
985
  * dans le circuit de combustion (fiche technique), la ventouse n'étant qu'un repli.
986
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
986
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
987
987
  */
988
988
  describe('tv_generateur_combustion - coefficients (E, F) selon le ventilateur de combustion (#35)', () => {
989
989
  const ROW_EF = { ...ROW_DEFAUT, rpn: 'E*40', qp0_perc: 'Pn*(E+F*log10(Pn))/100' };
@@ -1032,7 +1032,7 @@ describe('tv_generateur_combustion - coefficients (E, F) selon le ventilateur de
1032
1032
  * Issue #39 : présence d'une veilleuse lue dans la sous-fiche technique du générateur.
1033
1033
  * Tribu : entrée `Is_veilleuse` (DPE.DataClasses/generateur.cs), Pveil1 = 0 si absente
1034
1034
  * (DPE.Core/Calcul_generateur.cs).
1035
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.4 / §14.1
1035
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.4 / §14.1
1036
1036
  */
1037
1037
  describe('presenceVeilleuse - fiche technique « Présence d’une veilleuse »', () => {
1038
1038
  const ficheGen = (desc, veilleuse) => [
@@ -1151,7 +1151,7 @@ describe('presenceVeilleuse - fiche technique « Présence d’une veilleuse »'
1151
1151
  /**
1152
1152
  * Issue #124 : générateur collectif virtualisé, puissance saisie collective (Pn) ou individualisée
1153
1153
  * (Pe = a × Pn) selon les logiciels.
1154
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §17.2.1
1154
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §17.2.1
1155
1155
  */
1156
1156
  describe('tv_generateur_combustion - convention de puissance d’un générateur virtualisé (#124)', () => {
1157
1157
  const ROW_PN = {
@@ -1418,7 +1418,7 @@ describe('caracteristiquesGenerateurCombustion - selon la méthode de saisie', (
1418
1418
  /**
1419
1419
  * Plafond de Pn à 400 kW dans Qp0 = Pn × (E + F × log Pn) / 100 des chaudières gaz après 2015
1420
1420
  * (moteur de référence Tribu : Calcul_generateur.cs, Rpn_chaudieregaz, Math.Min(400.0, Pn)).
1421
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
1421
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
1422
1422
  */
1423
1423
  describe('puissanceFormuleQp0 - plafond de Pn à 400 kW pour les chaudières gaz', () => {
1424
1424
  const ROW_GAZ = {
@@ -1486,7 +1486,7 @@ describe('puissanceFormuleQp0 - plafond de Pn à 400 kW pour les chaudières gaz
1486
1486
 
1487
1487
  /**
1488
1488
  * Estimation de la puissance nominale d'un générateur à combustion (pn absente).
1489
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4
1489
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4
1490
1490
  */
1491
1491
  describe('pnEstimee - puissance nominale estimée (issue #264)', () => {
1492
1492
  // 1,2 × 200 × (19 − (−9)) / 0,95³ -- valeur de référence de régression
@@ -1518,7 +1518,7 @@ describe('pnEstimee - puissance nominale estimée (issue #264)', () => {
1518
1518
 
1519
1519
  /**
1520
1520
  * Pn estimée par la puissance de dimensionnement (issue #271).
1521
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4
1521
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4
1522
1522
  */
1523
1523
  describe('pnEstimeeGenerateur - Pdim = max(Pch ; Pecs) et table Pdim → Pn (issue #271)', () => {
1524
1524
  const dpeAvecEcsMixte = (generateursEcs) => ({
@@ -1,9 +1,12 @@
1
+ /** @import { FullDpe } from './features/dpe/domain/models/dpe.model.js' */
2
+ /** @import { GenerateurChauffageDE } from './features/dpe/domain/models/installation-chauffage.model.js' */
3
+ /** @import { GenerateurEcsDE } from './features/dpe/domain/models/installation-ecs.model.js' */
1
4
  import getFicheTechnique from './ficheTechnique.js';
2
5
 
3
6
  /**
4
7
  * Pour les générateurs "poêles à bois bouilleur", les calculs sont faits comme pour les chaudières bois
5
8
  * @param dpe {FullDpe}
6
- * @param de {Donnee_entree}
9
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
7
10
  * @param type {'ch' | 'ecs'}
8
11
  */
9
12
  export function updateGenerateurBouilleurs(dpe, de, type) {
@@ -121,7 +124,7 @@ export function updateGenerateurBouilleurs(dpe, de, type) {
121
124
  * - Pour un poêle à bois bouilleur bûche installé avant 1948, on prendra la chaudière bois bûche avant 1978
122
125
  * @param dpe {FullDpe}
123
126
  * @param ids
124
- * @param de {Donnee_entree}
127
+ * @param de {GenerateurChauffageDE|GenerateurEcsDE}
125
128
  * @param type {'ch' | 'ecs'}
126
129
  */
127
130
  function updateGenerateurBouilleur(dpe, ids, de, type) {
@@ -18,7 +18,7 @@ beforeEach(() => {
18
18
  /**
19
19
  * 13.1 - Les poêles à bois bouilleur sont assimilés à des chaudières bois de la
20
20
  * période correspondante.
21
- * @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.1
21
+ * @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.1
22
22
  */
23
23
  describe('updateGenerateurBouilleurs - substitution par une chaudière bois équivalente', () => {
24
24
  test('type non concerné : aucune substitution', () => {