@open3cl/engine 1.0.9 → 1.0.11

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 (45) hide show
  1. package/features/dpe/domain/models/type-habitation.model.js +8 -0
  2. package/features/dpe/infrastructure/ecs/ecsTv.store.js +22 -0
  3. package/features/dpe/infrastructure/ecs/ecsTv.store.spec.js +33 -0
  4. package/features/dpe/infrastructure/{baieVitreeTv.store.js → enveloppe/baieVitreeTv.store.js} +74 -4
  5. package/features/dpe/infrastructure/{baieVitreeTv.store.spec.js → enveloppe/baieVitreeTv.store.spec.js} +106 -0
  6. package/features/dpe/infrastructure/{pontThermiqueTv.store.js → enveloppe/pontThermiqueTv.store.js} +3 -3
  7. package/features/dpe/infrastructure/froid/frTv.store.js +36 -0
  8. package/features/dpe/infrastructure/froid/frTv.store.spec.js +52 -0
  9. package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.js +74 -0
  10. package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +85 -0
  11. package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.js +134 -0
  12. package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.spec.js +167 -0
  13. package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.js +58 -0
  14. package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +67 -0
  15. package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.js +131 -0
  16. package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +229 -0
  17. package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.js +168 -0
  18. package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +230 -0
  19. package/features/engine/domain/contexte.builder.js +103 -64
  20. package/features/engine/domain/contexte.builder.spec.js +99 -64
  21. package/features/engine/domain/engine.service.js +16 -2
  22. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +2 -2
  23. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +1 -1
  24. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +19 -0
  25. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +3 -3
  26. package/features/engine/domain/enveloppe/deperdition.service.js +2 -3
  27. package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.js +44 -0
  28. package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +81 -0
  29. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +3 -3
  30. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +30 -10
  31. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +2 -2
  32. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +18 -6
  33. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +2 -2
  34. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +21 -7
  35. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +1 -1
  36. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +1 -1
  37. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +1 -1
  38. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +2 -2
  39. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +1 -1
  40. package/features/engine/domain/logement/nadeq.service.js +63 -0
  41. package/features/engine/domain/logement/nadeq.service.spec.js +61 -0
  42. package/features/engine/domain/models/contexte.model.ts +19 -5
  43. package/features/engine/domain/models/deperdition.model.ts +1 -1
  44. package/package.json +1 -1
  45. /package/features/dpe/infrastructure/{pontThermiqueTv.store.spec.js → enveloppe/pontThermiqueTv.store.spec.js} +0 -0
@@ -1,24 +1,24 @@
1
1
  import { ContexteBuilder } from './contexte.builder.js';
2
- import { beforeEach, describe, expect, test } from 'vitest';
2
+ import { beforeEach, describe, expect, test, vi } from 'vitest';
3
+ import { TypeDpe, TypeHabitation } from '../../dpe/domain/models/type-habitation.model.js';
4
+ import { NadeqService } from './logement/nadeq.service.js';
5
+
6
+ /** @type {NadeqService} **/
7
+ let nadeqService;
3
8
 
4
9
  /** @type {ContexteBuilder} **/
5
10
  let contexteBuilder;
6
11
 
7
12
  describe('Generateur du contexte du calcul', () => {
8
13
  beforeEach(() => {
9
- contexteBuilder = new ContexteBuilder();
14
+ nadeqService = new NadeqService();
15
+ contexteBuilder = new ContexteBuilder(nadeqService);
10
16
  });
11
17
 
12
18
  test('Contexte avec effet joule', () => {
13
19
  const dpe = {
14
20
  logement: {
15
- meteo: { enum_zone_climatique_id: 1 },
16
- caracteristique_generale: {
17
- enum_periode_construction_id: 1,
18
- surface_habitable_logement: 48.9,
19
- surface_habitable_immeuble: 105,
20
- hsp: 2.8
21
- },
21
+ caracteristique_generale: {},
22
22
  installation_chauffage_collection: {
23
23
  installation_chauffage: [
24
24
  {
@@ -31,26 +31,15 @@ describe('Generateur du contexte du calcul', () => {
31
31
  }
32
32
  };
33
33
 
34
- expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
35
- effetJoule: true,
36
- enumPeriodeConstructionId: '1',
37
- zoneClimatiqueId: '1',
38
- hauteurSousPlafond: 2.8,
39
- surfaceHabitable: 105,
40
- typeHabitation: 'IMMEUBLE'
34
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
35
+ effetJoule: true
41
36
  });
42
37
  });
43
38
 
44
39
  test('Contexte sans effet joule', () => {
45
40
  const dpe = {
46
41
  logement: {
47
- meteo: { enum_zone_climatique_id: 1 },
48
- caracteristique_generale: {
49
- enum_periode_construction_id: 1,
50
- surface_habitable_logement: 48.9,
51
- surface_habitable_immeuble: 105,
52
- hsp: 2.8
53
- },
42
+ caracteristique_generale: {},
54
43
  installation_chauffage_collection: {
55
44
  installation_chauffage: [
56
45
  {
@@ -65,88 +54,134 @@ describe('Generateur du contexte du calcul', () => {
65
54
  }
66
55
  };
67
56
 
68
- expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
69
- effetJoule: false,
70
- enumPeriodeConstructionId: '1',
71
- zoneClimatiqueId: '1',
72
- hauteurSousPlafond: 2.8,
73
- surfaceHabitable: 105,
74
- typeHabitation: 'IMMEUBLE'
57
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
58
+ effetJoule: false
75
59
  });
76
60
  });
77
61
 
78
62
  test('Contexte sans chauffage', () => {
79
63
  const dpe = {
80
64
  logement: {
81
- meteo: { enum_zone_climatique_id: 1 },
82
- caracteristique_generale: {
83
- enum_periode_construction_id: 1,
84
- surface_habitable_logement: 48.9,
85
- surface_habitable_immeuble: 105,
86
- hsp: 2.8
87
- }
65
+ caracteristique_generale: {}
88
66
  }
89
67
  };
90
68
 
91
- expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
92
- effetJoule: false,
93
- enumPeriodeConstructionId: '1',
94
- zoneClimatiqueId: '1',
95
- hauteurSousPlafond: 2.8,
96
- surfaceHabitable: 105,
97
- typeHabitation: 'IMMEUBLE'
69
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
70
+ effetJoule: false
98
71
  });
99
72
  });
100
73
 
101
74
  test('Contexte sans emetteur de chauffage', () => {
102
75
  const dpe = {
103
76
  logement: {
104
- meteo: { enum_zone_climatique_id: 1 },
105
- caracteristique_generale: {
106
- enum_periode_construction_id: 1,
107
- surface_habitable_logement: 48.9,
108
- surface_habitable_immeuble: 105,
109
- hsp: 2.8
110
- },
77
+ caracteristique_generale: {},
111
78
  installation_chauffage_collection: {}
112
79
  }
113
80
  };
114
81
 
115
- expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
116
- effetJoule: false,
117
- enumPeriodeConstructionId: '1',
118
- zoneClimatiqueId: '1',
119
- hauteurSousPlafond: 2.8,
120
- surfaceHabitable: 105,
121
- typeHabitation: 'IMMEUBLE'
82
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
83
+ effetJoule: false
122
84
  });
123
85
  });
124
86
 
125
- test('Récupération de la surface habitable du logement concerné par le DPE', () => {
87
+ test('Contexte avec calcul du nadeq', () => {
88
+ vi.spyOn(nadeqService, 'execute').mockReturnValue(1.58);
89
+ const dpe = {
90
+ logement: {
91
+ caracteristique_generale: {},
92
+ installation_chauffage_collection: {}
93
+ }
94
+ };
95
+
96
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
97
+ nadeq: 1.58
98
+ });
99
+ });
100
+
101
+ test('Récupération des informations du logement concerné par le DPE', () => {
126
102
  let dpe = {
127
103
  logement: {
104
+ meteo: {
105
+ enum_zone_climatique_id: 1,
106
+ enum_classe_altitude_id: 2
107
+ },
128
108
  caracteristique_generale: {
129
- enum_periode_construction_id: 1,
109
+ enum_periode_construction_id: 4,
130
110
  surface_habitable_logement: 48.9,
131
111
  surface_habitable_immeuble: 105,
132
- hsp: 2.8
112
+ hsp: 2.8,
113
+ nombre_appartement: 18
133
114
  }
134
115
  }
135
116
  };
136
117
 
137
118
  dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '1';
138
119
  expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
139
- surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement
120
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement,
121
+ typeHabitation: TypeHabitation.MAISON,
122
+ typeDpe: TypeDpe.MAISON,
123
+ enumPeriodeConstructionId: '4',
124
+ hauteurSousPlafond: 2.8,
125
+ nombreAppartement: 18,
126
+ zoneClimatique: {
127
+ id: '1',
128
+ value: 'h1a'
129
+ },
130
+ altitude: {
131
+ id: '2',
132
+ value: '400-800m'
133
+ }
140
134
  });
141
135
 
142
136
  dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '5';
137
+ dpe.logement.meteo.enum_zone_climatique_id = '4';
138
+ dpe.logement.meteo.enum_classe_altitude_id = '3';
143
139
  expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
144
- surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement
140
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement,
141
+ typeHabitation: TypeHabitation.APPARTEMENT,
142
+ typeDpe: TypeDpe.APPARTEMENT,
143
+ zoneClimatique: {
144
+ id: '4',
145
+ value: 'h2a'
146
+ },
147
+ altitude: {
148
+ id: '3',
149
+ value: 'supérieur à 800m'
150
+ }
145
151
  });
146
152
 
147
153
  dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '8';
148
154
  expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
149
- surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_immeuble
155
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_immeuble,
156
+ typeHabitation: TypeHabitation.IMMEUBLE,
157
+ typeDpe: TypeDpe.IMMEUBLE
150
158
  });
151
159
  });
160
+
161
+ test('Contexte avec calcul ilpa', () => {
162
+ const dpe = {
163
+ logement: {
164
+ caracteristique_generale: {},
165
+ meteo: {
166
+ batiment_materiaux_anciens: 0
167
+ },
168
+ enveloppe: {
169
+ inertie: {
170
+ enum_classe_inertie_id: 4
171
+ }
172
+ }
173
+ }
174
+ };
175
+
176
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 4, ilpa: 0 } });
177
+
178
+ dpe.logement.enveloppe.inertie.enum_classe_inertie_id = 1;
179
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 1, ilpa: 0 } });
180
+
181
+ dpe.logement.meteo.batiment_materiaux_anciens = 1;
182
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 1, ilpa: 1 } });
183
+
184
+ dpe.logement.enveloppe.inertie.enum_classe_inertie_id = 2;
185
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 2, ilpa: 1 } });
186
+ });
152
187
  });
@@ -2,12 +2,19 @@ import { inject } from 'dioma';
2
2
  import { ContexteBuilder } from './contexte.builder.js';
3
3
  import { DeperditionEnveloppeService } from './enveloppe/deperdition-enveloppe.service.js';
4
4
  import { logger } from '../../../core/util/logger/log-service.js';
5
+ import { ApportEtBesoinService } from './apport_et_besoin/apport-et-besoin.service.js';
5
6
 
6
7
  export class EngineService {
7
8
  /**
8
9
  * @type {DeperditionEnveloppeService}
9
10
  */
10
11
  #deperditionService;
12
+
13
+ /**
14
+ * @type {ApportEtBesoinService}
15
+ */
16
+ #apportEtBesoinService;
17
+
11
18
  /**
12
19
  * @type {ContexteBuilder}
13
20
  */
@@ -15,13 +22,16 @@ export class EngineService {
15
22
 
16
23
  /**
17
24
  * @param deperditionService {DeperditionEnveloppeService}
25
+ * @param apportEtBesoinService {ApportEtBesoinService}
18
26
  * @param contextBuilder {ContexteBuilder}
19
27
  */
20
28
  constructor(
21
29
  deperditionService = inject(DeperditionEnveloppeService),
30
+ apportEtBesoinService = inject(ApportEtBesoinService),
22
31
  contextBuilder = inject(ContexteBuilder)
23
32
  ) {
24
33
  this.#deperditionService = deperditionService;
34
+ this.#apportEtBesoinService = apportEtBesoinService;
25
35
  this.#contextBuilder = contextBuilder;
26
36
  }
27
37
 
@@ -55,7 +65,12 @@ export class EngineService {
55
65
  // Calcul des déperditions
56
66
  proceededDpe.logement.sortie.deperdition = this.#deperditionService.deperditions(
57
67
  ctx,
58
- dpe.logement
68
+ proceededDpe.logement
69
+ );
70
+
71
+ proceededDpe.logement.sortie.apport_et_besoin = this.#apportEtBesoinService.execute(
72
+ ctx,
73
+ proceededDpe.logement
59
74
  );
60
75
 
61
76
  // Calcul des déperditions par renouvellement de l'air
@@ -97,7 +112,6 @@ export class EngineService {
97
112
  */
98
113
  #removeComputedData(dpe) {
99
114
  delete dpe.logement.sortie;
100
- delete dpe.logement.enveloppe.inertie;
101
115
 
102
116
  dpe.logement.enveloppe.mur_collection.mur?.map((m) => delete m.donnee_intermediaire);
103
117
  dpe.logement.enveloppe.baie_vitree_collection.baie_vitree?.map((m) => {
@@ -1,6 +1,6 @@
1
1
  import { DeperditionService } from '../deperdition.service.js';
2
2
  import { inject } from 'dioma';
3
- import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/baieVitreeTv.store.js';
3
+ import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
4
4
 
5
5
  /**
6
6
  * Calcul des déperditions des baies vitrées
@@ -31,7 +31,7 @@ export class DeperditionBaieVitreeService extends DeperditionService {
31
31
  surfaceAiu: bvDE.surface_aiu,
32
32
  surfaceAue: bvDE.surface_aue,
33
33
  enumCfgIsolationLncId: bvDE.enum_cfg_isolation_lnc_id,
34
- zoneClimatiqueId: ctx.zoneClimatiqueId
34
+ zoneClimatique: ctx.zoneClimatique?.value
35
35
  });
36
36
 
37
37
  let sw = this.sw(bv);
@@ -4,7 +4,7 @@ import { ContexteBuilder } from '../../contexte.builder.js';
4
4
  import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
5
5
  import { DeperditionBaieVitreeService } from './deperdition-baie-vitree.service.js';
6
6
  import { beforeEach, describe, expect, test, vi } from 'vitest';
7
- import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/baieVitreeTv.store.js';
7
+ import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
8
8
 
9
9
  /** @type {DeperditionBaieVitreeService} **/
10
10
  let service;
@@ -6,6 +6,7 @@ import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plan
6
6
  import { DeperditionVentilationService } from './ventilation/deperdition-ventilation.service.js';
7
7
  import { DeperditionBaieVitreeService } from './baie_vitree/deperdition-baie-vitree.service.js';
8
8
  import { DeperditionPontThermiqueService } from './pont_thermique/deperdition-pont-thermique.service.js';
9
+ import { EspaceTamponService } from './espace_tampon/espace-tampon.service.js';
9
10
 
10
11
  /**
11
12
  * Calcul des déperditions de l’enveloppe
@@ -37,6 +38,11 @@ export class DeperditionEnveloppeService {
37
38
  */
38
39
  #deperditionBaieVitreeService;
39
40
 
41
+ /**
42
+ * @type {EspaceTamponService}
43
+ */
44
+ #espaceTamponService;
45
+
40
46
  /**
41
47
  * @type {DeperditionPontThermiqueService}
42
48
  */
@@ -79,6 +85,7 @@ export class DeperditionEnveloppeService {
79
85
  * @param deperditionPlancherBasService {DeperditionPlancherBasService}
80
86
  * @param deperditionPlancherHautService {DeperditionPlancherHautService}
81
87
  * @param deperditionBaieVitreeService {DeperditionBaieVitreeService}
88
+ * @param espaceTamponService {EspaceTamponService}
82
89
  * @param deperditionPontThermiqueService {DeperditionPontThermiqueService}
83
90
  * @param deperditionVentilationService {DeperditionVentilationService}
84
91
  */
@@ -88,6 +95,7 @@ export class DeperditionEnveloppeService {
88
95
  deperditionPlancherBasService = inject(DeperditionPlancherBasService),
89
96
  deperditionPlancherHautService = inject(DeperditionPlancherHautService),
90
97
  deperditionBaieVitreeService = inject(DeperditionBaieVitreeService),
98
+ espaceTamponService = inject(EspaceTamponService),
91
99
  deperditionPontThermiqueService = inject(DeperditionPontThermiqueService),
92
100
  deperditionVentilationService = inject(DeperditionVentilationService)
93
101
  ) {
@@ -96,6 +104,7 @@ export class DeperditionEnveloppeService {
96
104
  this.#deperditionPlancherBasService = deperditionPlancherBasService;
97
105
  this.#deperditionPlancherHautService = deperditionPlancherHautService;
98
106
  this.#deperditionBaieVitreeService = deperditionBaieVitreeService;
107
+ this.#espaceTamponService = espaceTamponService;
99
108
  this.#deperditionPontThermiqueService = deperditionPontThermiqueService;
100
109
  this.#deperditionVentilationService = deperditionVentilationService;
101
110
  this.#surfaceDeperditive = 0;
@@ -249,6 +258,16 @@ export class DeperditionEnveloppeService {
249
258
  }
250
259
  });
251
260
 
261
+ let ets = enveloppe.ets_collection?.ets;
262
+ if (ets) {
263
+ // Certaines vérandas sont dupliqués dans les DPE.
264
+ if (Array.isArray(ets)) {
265
+ ets = ets[0];
266
+ }
267
+
268
+ ets.donnee_intermediaire = this.#espaceTamponService.execute(ctx, ets);
269
+ }
270
+
252
271
  enveloppe.pont_thermique_collection.pont_thermique?.forEach((pt) => {
253
272
  pt.donnee_intermediaire = this.#deperditionPontThermiqueService.execute(
254
273
  ctx,
@@ -99,7 +99,7 @@ describe('Calcul des déperditions', () => {
99
99
  enumTypeAdjacenceId: '10',
100
100
  surfaceAiu: 8.14,
101
101
  surfaceAue: 22.8,
102
- zoneClimatiqueId: '5',
102
+ zoneClimatique: 'h2c',
103
103
  enumCfgIsolationLncId: '9',
104
104
  label: 'espace tampon solarisé (véranda,loggia fermée)',
105
105
  bExpected: 0.85
@@ -197,7 +197,7 @@ describe('Calcul des déperditions', () => {
197
197
  enumTypeAdjacenceId,
198
198
  surfaceAiu = undefined,
199
199
  surfaceAue = undefined,
200
- zoneClimatiqueId = undefined,
200
+ zoneClimatique = undefined,
201
201
  enumCfgIsolationLncId = undefined,
202
202
  bExpected
203
203
  }) => {
@@ -206,7 +206,7 @@ describe('Calcul des déperditions', () => {
206
206
  surfaceAiu,
207
207
  surfaceAue,
208
208
  enumCfgIsolationLncId,
209
- zoneClimatiqueId
209
+ zoneClimatique
210
210
  };
211
211
 
212
212
  const b = deperditionMurService.b(data);
@@ -1,4 +1,3 @@
1
- import enums from '../../../../enums.js';
2
1
  import { logger } from '../../../../core/util/logger/log-service.js';
3
2
  import { inject } from 'dioma';
4
3
  import { TvStore } from '../../../dpe/infrastructure/tv.store.js';
@@ -71,13 +70,13 @@ export class DeperditionService {
71
70
  * Prise en compte de la zone climatique
72
71
  */
73
72
  if (['10'].includes(enumTypeAdjacenceId)) {
74
- if (!d.zoneClimatiqueId) {
73
+ if (!d.zoneClimatique) {
75
74
  logger.warn(
76
75
  `impossible de calculer b pour TypeAdjacenceId:${enumTypeAdjacenceId} sans zone climatique`
77
76
  );
78
77
  return;
79
78
  }
80
- zc = enums.zone_climatique[parseInt(d.zoneClimatiqueId)];
79
+ zc = d.zoneClimatique;
81
80
  }
82
81
 
83
82
  return this.tvStore.getB(enumTypeAdjacenceId, uVue, d.enumCfgIsolationLncId, rAiuAue, zc);
@@ -0,0 +1,44 @@
1
+ import { DeperditionService } from '../deperdition.service.js';
2
+ import { inject } from 'dioma';
3
+ import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
4
+
5
+ /**
6
+ * Calcul des déperditions des baies vitrées
7
+ * Chapitre 3.3 Calcul des parois vitrées
8
+ *
9
+ * Méthode de calcul 3CL-DPE 2021
10
+ * Octobre 2021
11
+ * @see consolide_anne…arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
12
+ */
13
+ export class EspaceTamponService extends DeperditionService {
14
+ /**
15
+ * @param tvStore {BaieVitreeTvStore}
16
+ */
17
+ constructor(tvStore = inject(BaieVitreeTvStore)) {
18
+ super(tvStore);
19
+ }
20
+
21
+ /**
22
+ * @param ctx {Contexte}
23
+ * @param ets {Ets}
24
+ * @return {EtsDI}
25
+ */
26
+ execute(ctx, ets) {
27
+ const bvDE = ets.donnee_entree;
28
+
29
+ const bver = this.tvStore.getBver(
30
+ ctx.zoneClimatique.value,
31
+ parseInt(bvDE.enum_cfg_isolation_lnc_id)
32
+ );
33
+
34
+ const coef_transparence_ets = this.tvStore.getCoefTransparenceEts(
35
+ parseInt(bvDE.tv_coef_transparence_ets_id)
36
+ );
37
+
38
+ /** @type {EtsDI} */
39
+ return {
40
+ bver,
41
+ coef_transparence_ets
42
+ };
43
+ }
44
+ }
@@ -0,0 +1,81 @@
1
+ import { ContexteBuilder } from '../../contexte.builder.js';
2
+ import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
3
+ import { beforeEach, describe, expect, test, vi } from 'vitest';
4
+ import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
5
+ import { EspaceTamponService } from './espace-tampon.service.js';
6
+ import { getAdemeFileJson } from '../../../../../../test/test-helpers.js';
7
+
8
+ /** @type {EspaceTamponService} **/
9
+ let service;
10
+
11
+ /** @type {DpeNormalizerService} **/
12
+ let normalizerService;
13
+
14
+ /** @type {BaieVitreeTvStore} **/
15
+ let tvStore;
16
+
17
+ /** @type {ContexteBuilder} **/
18
+ let contexteBuilder;
19
+
20
+ describe('Calcul de déperdition des baies vitrées', () => {
21
+ beforeEach(() => {
22
+ tvStore = new BaieVitreeTvStore();
23
+ service = new EspaceTamponService(tvStore);
24
+ normalizerService = new DpeNormalizerService();
25
+ contexteBuilder = new ContexteBuilder();
26
+ });
27
+
28
+ describe('Determination des données intermédiaires', () => {
29
+ test('Doit retourner bver et directement', () => {
30
+ vi.spyOn(tvStore, 'getBver').mockReturnValue(0.55);
31
+ vi.spyOn(tvStore, 'getCoefTransparenceEts').mockReturnValue(0.62);
32
+
33
+ /**
34
+ * @type {Contexte}
35
+ */
36
+ const ctx = {
37
+ zoneClimatique: { value: 'h1a' }
38
+ };
39
+
40
+ /**
41
+ * @type {Ets}
42
+ */
43
+ const ets = {
44
+ donnee_entree: {
45
+ enum_cfg_isolation_lnc_id: '10',
46
+ tv_coef_transparence_ets_id: '2'
47
+ }
48
+ };
49
+
50
+ let etsDI = service.execute(ctx, ets);
51
+ expect(tvStore.getBver).toHaveBeenCalledWith('h1a', 10);
52
+ expect(tvStore.getCoefTransparenceEts).toHaveBeenCalledWith(2);
53
+ expect(etsDI).toStrictEqual({ bver: 0.55, coef_transparence_ets: 0.62 });
54
+ });
55
+ });
56
+
57
+ describe("Test d'intégration des ets", () => {
58
+ test.each(['2273E0303205P', '2364E0984413P', '2283E0131604Y'])(
59
+ 'vérification des DI des ets pour dpe %s',
60
+ (ademeId) => {
61
+ let dpeRequest = getAdemeFileJson(ademeId);
62
+ dpeRequest = normalizerService.normalize(dpeRequest);
63
+
64
+ /** @type {Contexte} */
65
+ const ctx = contexteBuilder.fromDpe(dpeRequest);
66
+
67
+ let ets = dpeRequest.logement.enveloppe.ets_collection?.ets || {};
68
+ if (ets && Array.isArray(ets)) {
69
+ ets = ets[0];
70
+ }
71
+
72
+ const di = service.execute(ctx, ets);
73
+ expect(di.bver).toBeCloseTo(ets.donnee_intermediaire.bver, 2);
74
+ expect(di.coef_transparence_ets).toBeCloseTo(
75
+ ets.donnee_intermediaire.coef_transparence_ets,
76
+ 2
77
+ );
78
+ }
79
+ );
80
+ });
81
+ });
@@ -34,7 +34,7 @@ export class DeperditionMurService extends DeperditionService {
34
34
  surfaceAue: murDE.surface_aue,
35
35
  enumCfgIsolationLncId: murDE.enum_cfg_isolation_lnc_id,
36
36
  tvCoefReductionDeperditionId: murDE.tv_coef_reduction_deperdition_id,
37
- zoneClimatiqueId: ctx.zoneClimatiqueId
37
+ zoneClimatique: ctx.zoneClimatique.value
38
38
  });
39
39
 
40
40
  /** @type {MurDI} */
@@ -65,14 +65,14 @@ export class DeperditionMurService extends DeperditionService {
65
65
  case '2': // isolation inconnue (table forfaitaire)
66
66
  umur = Math.min(
67
67
  umurNu,
68
- this.tvStore.getUmur(ctx.enumPeriodeConstructionId, ctx.zoneClimatiqueId, ctx.effetJoule)
68
+ this.tvStore.getUmur(ctx.enumPeriodeConstructionId, ctx.zoneClimatique.id, ctx.effetJoule)
69
69
  );
70
70
  break;
71
71
  case '7': // année d'isolation différente de l'année de construction
72
72
  case '8': // année de construction saisie
73
73
  umur = Math.min(
74
74
  umurNu,
75
- this.tvStore.getUmur(enumPeriodeIsolationId, ctx.zoneClimatiqueId, ctx.effetJoule)
75
+ this.tvStore.getUmur(enumPeriodeIsolationId, ctx.zoneClimatique.id, ctx.effetJoule)
76
76
  );
77
77
  break;
78
78
  case '3': // epaisseur isolation saisie justifiée par mesure ou observation