@open3cl/engine 1.0.8 → 1.0.10

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 (35) hide show
  1. package/features/dpe/domain/models/dpe.model.ts +7 -3
  2. package/features/dpe/domain/models/{plancher-bas.model.ts → plancher.model.ts} +31 -7
  3. package/features/dpe/domain/models/type-habitation.model.js +8 -0
  4. package/features/dpe/infrastructure/baieVitreeTv.store.js +70 -0
  5. package/features/dpe/infrastructure/baieVitreeTv.store.spec.js +106 -0
  6. package/features/dpe/infrastructure/pontThermiqueTv.store.js +112 -0
  7. package/features/dpe/infrastructure/pontThermiqueTv.store.spec.js +134 -0
  8. package/features/engine/domain/contexte.builder.js +59 -63
  9. package/features/engine/domain/contexte.builder.spec.js +41 -62
  10. package/features/engine/domain/engine.service.js +20 -2
  11. package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +1 -1
  12. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +41 -0
  13. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +3 -3
  14. package/features/engine/domain/enveloppe/deperdition.service.js +2 -3
  15. package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.js +44 -0
  16. package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +81 -0
  17. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +31 -3
  18. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +91 -10
  19. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +48 -2
  20. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +103 -6
  21. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +35 -2
  22. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +82 -7
  23. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +439 -0
  24. package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +636 -0
  25. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +1 -1
  26. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +2 -2
  27. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +1 -1
  28. package/features/engine/domain/logement/nadeq.service.js +62 -0
  29. package/features/engine/domain/logement/nadeq.service.spec.js +71 -0
  30. package/features/engine/domain/logement/surface-sud-equivalente.service.js +169 -0
  31. package/features/engine/domain/logement/surface-sud-equivalente.service.spec.js +210 -0
  32. package/features/engine/domain/models/contexte.model.ts +10 -5
  33. package/features/engine/domain/models/deperdition.model.ts +1 -1
  34. package/package.json +1 -1
  35. package/features/dpe/domain/models/plancher-haut.model.ts +0 -33
@@ -1,4 +1,5 @@
1
- import { TypeHabitation } from '../../dpe/domain/models/type-habitation.model.js';
1
+ import { TypeDpe, TypeHabitation } from '../../dpe/domain/models/type-habitation.model.js';
2
+ import enums from '../../../enums.js';
2
3
 
3
4
  /**
4
5
  * Génère un contexte du logement à étudier avec des données persistées durant l'analyse
@@ -11,14 +12,30 @@ export class ContexteBuilder {
11
12
  * @return {Contexte}
12
13
  */
13
14
  fromDpe(dpe) {
15
+ const caracteristiqueGenerale = dpe.logement.caracteristique_generale;
16
+
14
17
  return {
15
- zoneClimatiqueId: dpe.logement.meteo?.enum_zone_climatique_id.toString(),
16
- typeHabitation: this.#getTypeHabitation(dpe),
17
- enumPeriodeConstructionId:
18
- dpe.logement.caracteristique_generale.enum_periode_construction_id?.toString(),
18
+ zoneClimatique: this.#zoneClimatique(dpe),
19
+ typeHabitation: this.#getTypeHabitation(caracteristiqueGenerale),
20
+ typeDpe: this.#getTypeDpe(caracteristiqueGenerale),
21
+ enumPeriodeConstructionId: caracteristiqueGenerale.enum_periode_construction_id?.toString(),
19
22
  effetJoule: this.#hasEffetJoule(dpe),
20
- surfaceHabitable: this.#getSurfaceHabitable(dpe),
21
- hauteurSousPlafond: dpe.logement.caracteristique_generale.hsp
23
+ surfaceHabitable: this.#getSurfaceHabitable(caracteristiqueGenerale),
24
+ hauteurSousPlafond: caracteristiqueGenerale.hsp,
25
+ nombreAppartement: caracteristiqueGenerale.nombre_appartement
26
+ };
27
+ }
28
+
29
+ /**
30
+ * La zone climatique à partir du type de DPE
31
+ * @param dpe {Dpe}
32
+ * @return {{id: number, value: string}}
33
+ */
34
+ #zoneClimatique(dpe) {
35
+ const zoneClimatiqueId = parseInt(dpe.logement.meteo?.enum_zone_climatique_id);
36
+ return {
37
+ id: zoneClimatiqueId.toString(),
38
+ value: enums.zone_climatique[zoneClimatiqueId]
22
39
  };
23
40
  }
24
41
 
@@ -39,43 +56,20 @@ export class ContexteBuilder {
39
56
 
40
57
  /**
41
58
  * Le type d'habitation est détecté à partir du type de DPE
42
- * @param dpe {Dpe}
59
+ * @param caracteristiqueGenerale {CaracteristiqueGenerale}
43
60
  * @return {TypeHabitation}
44
61
  */
45
- #getTypeHabitation(dpe) {
46
- const methodeApplication =
47
- dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id;
62
+ #getTypeHabitation(caracteristiqueGenerale) {
63
+ const methodeApplication = parseInt(
64
+ caracteristiqueGenerale.enum_methode_application_dpe_log_id
65
+ );
48
66
 
49
- if (['1', '14', '18'].includes(methodeApplication)) {
67
+ if ([1, 14, 18].includes(methodeApplication)) {
50
68
  return TypeHabitation.MAISON;
51
69
  } else if (
52
70
  [
53
- '2',
54
- '3',
55
- '4',
56
- '5',
57
- '10',
58
- '11',
59
- '12',
60
- '13',
61
- '15',
62
- '16',
63
- '19',
64
- '20',
65
- '22',
66
- '23',
67
- '24',
68
- '25',
69
- '31',
70
- '32',
71
- '33',
72
- '34',
73
- '35',
74
- '36',
75
- '37',
76
- '38',
77
- '39',
78
- '40'
71
+ 2, 3, 4, 5, 10, 11, 12, 13, 15, 16, 19, 20, 22, 23, 24, 25, 31, 32, 33, 34, 35, 36, 37, 38,
72
+ 39, 40
79
73
  ].includes(methodeApplication)
80
74
  ) {
81
75
  return TypeHabitation.APPARTEMENT;
@@ -84,10 +78,28 @@ export class ContexteBuilder {
84
78
  }
85
79
 
86
80
  /**
87
- * @param dpe {Dpe}
81
+ * Le type de DPE est détecté à partir du type de DPE
82
+ * @param caracteristiqueGenerale {CaracteristiqueGenerale}
83
+ * @return {TypeDpe}
84
+ */
85
+ #getTypeDpe(caracteristiqueGenerale) {
86
+ const methodeApplication = parseInt(
87
+ caracteristiqueGenerale.enum_methode_application_dpe_log_id
88
+ );
89
+
90
+ if ([1, 14, 18].includes(methodeApplication)) {
91
+ return TypeDpe.MAISON;
92
+ } else if ([2, 3, 4, 5, 31, 32, 35, 36, 37].includes(methodeApplication)) {
93
+ return TypeDpe.APPARTEMENT;
94
+ }
95
+ return TypeDpe.IMMEUBLE;
96
+ }
97
+
98
+ /**
99
+ * @param caracteristiqueGenerale {CaracteristiqueGenerale}
88
100
  * @return {number}
89
101
  */
90
- #getSurfaceHabitable(dpe) {
102
+ #getSurfaceHabitable(caracteristiqueGenerale) {
91
103
  /**
92
104
  * Certains DPE appartement sont générés à partir des données du DPE immeuble, la surface à prendre en compte est
93
105
  * celle de l'immeuble pour les besoins ECS
@@ -110,31 +122,15 @@ export class ContexteBuilder {
110
122
  * 40 - dpe appartement généré à partir des données DPE immeuble chauffage collectif ecs mixte (collectif-individuel)
111
123
  */
112
124
  if (
113
- [
114
- '10',
115
- '11',
116
- '12',
117
- '13',
118
- '15',
119
- '16',
120
- '19',
121
- '20',
122
- '22',
123
- '23',
124
- '24',
125
- '25',
126
- '33',
127
- '34',
128
- '38',
129
- '39',
130
- '40'
131
- ].includes(dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id)
125
+ [10, 11, 12, 13, 15, 16, 19, 20, 22, 23, 24, 25, 33, 34, 38, 39, 40].includes(
126
+ parseInt(caracteristiqueGenerale.enum_methode_application_dpe_log_id)
127
+ )
132
128
  ) {
133
- return dpe.logement.caracteristique_generale.surface_habitable_immeuble;
129
+ return caracteristiqueGenerale.surface_habitable_immeuble;
134
130
  }
135
131
 
136
- return this.#getTypeHabitation(dpe) === TypeHabitation.IMMEUBLE
137
- ? dpe.logement.caracteristique_generale.surface_habitable_immeuble
138
- : dpe.logement.caracteristique_generale.surface_habitable_logement;
132
+ return this.#getTypeHabitation(caracteristiqueGenerale) === TypeHabitation.IMMEUBLE
133
+ ? caracteristiqueGenerale.surface_habitable_immeuble
134
+ : caracteristiqueGenerale.surface_habitable_logement;
139
135
  }
140
136
  }
@@ -1,5 +1,6 @@
1
1
  import { ContexteBuilder } from './contexte.builder.js';
2
2
  import { beforeEach, describe, expect, test } from 'vitest';
3
+ import { TypeDpe, TypeHabitation } from '../../dpe/domain/models/type-habitation.model.js';
3
4
 
4
5
  /** @type {ContexteBuilder} **/
5
6
  let contexteBuilder;
@@ -12,13 +13,7 @@ describe('Generateur du contexte du calcul', () => {
12
13
  test('Contexte avec effet joule', () => {
13
14
  const dpe = {
14
15
  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
- },
16
+ caracteristique_generale: {},
22
17
  installation_chauffage_collection: {
23
18
  installation_chauffage: [
24
19
  {
@@ -31,26 +26,15 @@ describe('Generateur du contexte du calcul', () => {
31
26
  }
32
27
  };
33
28
 
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'
29
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
30
+ effetJoule: true
41
31
  });
42
32
  });
43
33
 
44
34
  test('Contexte sans effet joule', () => {
45
35
  const dpe = {
46
36
  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
- },
37
+ caracteristique_generale: {},
54
38
  installation_chauffage_collection: {
55
39
  installation_chauffage: [
56
40
  {
@@ -65,88 +49,83 @@ describe('Generateur du contexte du calcul', () => {
65
49
  }
66
50
  };
67
51
 
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'
52
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
53
+ effetJoule: false
75
54
  });
76
55
  });
77
56
 
78
57
  test('Contexte sans chauffage', () => {
79
58
  const dpe = {
80
59
  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
- }
60
+ caracteristique_generale: {}
88
61
  }
89
62
  };
90
63
 
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'
64
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
65
+ effetJoule: false
98
66
  });
99
67
  });
100
68
 
101
69
  test('Contexte sans emetteur de chauffage', () => {
102
70
  const dpe = {
103
71
  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
- },
72
+ caracteristique_generale: {},
111
73
  installation_chauffage_collection: {}
112
74
  }
113
75
  };
114
76
 
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'
77
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
78
+ effetJoule: false
122
79
  });
123
80
  });
124
81
 
125
- test('Récupération de la surface habitable du logement concerné par le DPE', () => {
82
+ test('Récupération des informations du logement concerné par le DPE', () => {
126
83
  let dpe = {
127
84
  logement: {
85
+ meteo: {
86
+ enum_zone_climatique_id: 1
87
+ },
128
88
  caracteristique_generale: {
129
- enum_periode_construction_id: 1,
89
+ enum_periode_construction_id: 4,
130
90
  surface_habitable_logement: 48.9,
131
91
  surface_habitable_immeuble: 105,
132
- hsp: 2.8
92
+ hsp: 2.8,
93
+ nombre_appartement: 18
133
94
  }
134
95
  }
135
96
  };
136
97
 
137
98
  dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '1';
138
99
  expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
139
- surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement
100
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement,
101
+ typeHabitation: TypeHabitation.MAISON,
102
+ typeDpe: TypeDpe.MAISON,
103
+ enumPeriodeConstructionId: '4',
104
+ hauteurSousPlafond: 2.8,
105
+ nombreAppartement: 18,
106
+ zoneClimatique: {
107
+ id: '1',
108
+ value: 'h1a'
109
+ }
140
110
  });
141
111
 
142
112
  dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '5';
113
+ dpe.logement.meteo.enum_zone_climatique_id = '4';
143
114
  expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
144
- surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement
115
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement,
116
+ typeHabitation: TypeHabitation.APPARTEMENT,
117
+ typeDpe: TypeDpe.APPARTEMENT,
118
+ zoneClimatique: {
119
+ id: '4',
120
+ value: 'h2a'
121
+ }
145
122
  });
146
123
 
147
124
  dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '8';
148
125
  expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
149
- surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_immeuble
126
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_immeuble,
127
+ typeHabitation: TypeHabitation.IMMEUBLE,
128
+ typeDpe: TypeDpe.IMMEUBLE
150
129
  });
151
130
  });
152
131
  });
@@ -1,12 +1,20 @@
1
1
  import { inject } from 'dioma';
2
2
  import { ContexteBuilder } from './contexte.builder.js';
3
3
  import { DeperditionEnveloppeService } from './enveloppe/deperdition-enveloppe.service.js';
4
+ import { logger } from '../../../core/util/logger/log-service.js';
5
+ import { SurfaceSudEquivalenteService } from './logement/surface-sud-equivalente.service.js';
4
6
 
5
7
  export class EngineService {
6
8
  /**
7
9
  * @type {DeperditionEnveloppeService}
8
10
  */
9
11
  #deperditionService;
12
+
13
+ /**
14
+ * @type {SurfaceSudEquivalenteService}
15
+ */
16
+ #surfaceSudEquivalenteService;
17
+
10
18
  /**
11
19
  * @type {ContexteBuilder}
12
20
  */
@@ -14,13 +22,16 @@ export class EngineService {
14
22
 
15
23
  /**
16
24
  * @param deperditionService {DeperditionEnveloppeService}
25
+ * @param surfaceSudEquivalenteService {SurfaceSudEquivalenteService}
17
26
  * @param contextBuilder {ContexteBuilder}
18
27
  */
19
28
  constructor(
20
29
  deperditionService = inject(DeperditionEnveloppeService),
30
+ surfaceSudEquivalenteService = inject(SurfaceSudEquivalenteService),
21
31
  contextBuilder = inject(ContexteBuilder)
22
32
  ) {
23
33
  this.#deperditionService = deperditionService;
34
+ this.#surfaceSudEquivalenteService = surfaceSudEquivalenteService;
24
35
  this.#contextBuilder = contextBuilder;
25
36
  }
26
37
 
@@ -33,7 +44,7 @@ export class EngineService {
33
44
  /** @type {Dpe} */
34
45
  const proceededDpe = this.#removeComputedData(JSON.parse(JSON.stringify(dpe)));
35
46
 
36
- console.error(`Process DPE ${proceededDpe.numero_dpe}`);
47
+ logger.info(`Process DPE ${proceededDpe.numero_dpe}`);
37
48
 
38
49
  proceededDpe.logement.sortie = {
39
50
  deperdition: undefined,
@@ -54,9 +65,16 @@ export class EngineService {
54
65
  // Calcul des déperditions
55
66
  proceededDpe.logement.sortie.deperdition = this.#deperditionService.deperditions(
56
67
  ctx,
57
- dpe.logement
68
+ proceededDpe.logement
58
69
  );
59
70
 
71
+ proceededDpe.logement.sortie.apport_et_besoin = {
72
+ surface_sud_equivalente: this.#surfaceSudEquivalenteService.execute(
73
+ ctx,
74
+ proceededDpe.logement.enveloppe
75
+ )
76
+ };
77
+
60
78
  // Calcul des déperditions par renouvellement de l'air
61
79
 
62
80
  // Calcul de l'intermittence
@@ -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);
@@ -5,6 +5,8 @@ import { DeperditionPlancherBasService } from './plancher_bas/deperdition-planch
5
5
  import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plancher-haut.service.js';
6
6
  import { DeperditionVentilationService } from './ventilation/deperdition-ventilation.service.js';
7
7
  import { DeperditionBaieVitreeService } from './baie_vitree/deperdition-baie-vitree.service.js';
8
+ import { DeperditionPontThermiqueService } from './pont_thermique/deperdition-pont-thermique.service.js';
9
+ import { EspaceTamponService } from './espace_tampon/espace-tampon.service.js';
8
10
 
9
11
  /**
10
12
  * Calcul des déperditions de l’enveloppe
@@ -36,6 +38,16 @@ export class DeperditionEnveloppeService {
36
38
  */
37
39
  #deperditionBaieVitreeService;
38
40
 
41
+ /**
42
+ * @type {EspaceTamponService}
43
+ */
44
+ #espaceTamponService;
45
+
46
+ /**
47
+ * @type {DeperditionPontThermiqueService}
48
+ */
49
+ #deperditionPontThermiqueService;
50
+
39
51
  /**
40
52
  * @type {DeperditionVentilationService}
41
53
  */
@@ -73,6 +85,8 @@ export class DeperditionEnveloppeService {
73
85
  * @param deperditionPlancherBasService {DeperditionPlancherBasService}
74
86
  * @param deperditionPlancherHautService {DeperditionPlancherHautService}
75
87
  * @param deperditionBaieVitreeService {DeperditionBaieVitreeService}
88
+ * @param espaceTamponService {EspaceTamponService}
89
+ * @param deperditionPontThermiqueService {DeperditionPontThermiqueService}
76
90
  * @param deperditionVentilationService {DeperditionVentilationService}
77
91
  */
78
92
  constructor(
@@ -81,6 +95,8 @@ export class DeperditionEnveloppeService {
81
95
  deperditionPlancherBasService = inject(DeperditionPlancherBasService),
82
96
  deperditionPlancherHautService = inject(DeperditionPlancherHautService),
83
97
  deperditionBaieVitreeService = inject(DeperditionBaieVitreeService),
98
+ espaceTamponService = inject(EspaceTamponService),
99
+ deperditionPontThermiqueService = inject(DeperditionPontThermiqueService),
84
100
  deperditionVentilationService = inject(DeperditionVentilationService)
85
101
  ) {
86
102
  this.#deperditionMurService = deperditionMurService;
@@ -88,6 +104,8 @@ export class DeperditionEnveloppeService {
88
104
  this.#deperditionPlancherBasService = deperditionPlancherBasService;
89
105
  this.#deperditionPlancherHautService = deperditionPlancherHautService;
90
106
  this.#deperditionBaieVitreeService = deperditionBaieVitreeService;
107
+ this.#espaceTamponService = espaceTamponService;
108
+ this.#deperditionPontThermiqueService = deperditionPontThermiqueService;
91
109
  this.#deperditionVentilationService = deperditionVentilationService;
92
110
  this.#surfaceDeperditive = 0;
93
111
  this.#surfaceIsolee = 0;
@@ -145,6 +163,7 @@ export class DeperditionEnveloppeService {
145
163
  deperdition_plancher_bas: 0,
146
164
  deperdition_plancher_haut: 0,
147
165
  deperdition_baie_vitree: 0,
166
+ deperdition_pont_thermique: 0,
148
167
  deperdition_porte: 0
149
168
  };
150
169
 
@@ -239,6 +258,28 @@ export class DeperditionEnveloppeService {
239
258
  }
240
259
  });
241
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
+
271
+ enveloppe.pont_thermique_collection.pont_thermique?.forEach((pt) => {
272
+ pt.donnee_intermediaire = this.#deperditionPontThermiqueService.execute(
273
+ ctx,
274
+ enveloppe,
275
+ pt.donnee_entree
276
+ );
277
+ deperditions.deperdition_pont_thermique +=
278
+ pt.donnee_entree.l *
279
+ pt.donnee_intermediaire.k *
280
+ (pt.donnee_entree.pourcentage_valeur_pont_thermique || 1);
281
+ });
282
+
242
283
  return deperditions;
243
284
  }
244
285
 
@@ -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/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/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
+ });