@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.
- package/features/dpe/domain/models/type-habitation.model.js +8 -0
- package/features/dpe/infrastructure/ecs/ecsTv.store.js +22 -0
- package/features/dpe/infrastructure/ecs/ecsTv.store.spec.js +33 -0
- package/features/dpe/infrastructure/{baieVitreeTv.store.js → enveloppe/baieVitreeTv.store.js} +74 -4
- package/features/dpe/infrastructure/{baieVitreeTv.store.spec.js → enveloppe/baieVitreeTv.store.spec.js} +106 -0
- package/features/dpe/infrastructure/{pontThermiqueTv.store.js → enveloppe/pontThermiqueTv.store.js} +3 -3
- package/features/dpe/infrastructure/froid/frTv.store.js +36 -0
- package/features/dpe/infrastructure/froid/frTv.store.spec.js +52 -0
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.js +74 -0
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +85 -0
- package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.js +134 -0
- package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.spec.js +167 -0
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.js +58 -0
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +67 -0
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.js +131 -0
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +229 -0
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.js +168 -0
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +230 -0
- package/features/engine/domain/contexte.builder.js +103 -64
- package/features/engine/domain/contexte.builder.spec.js +99 -64
- package/features/engine/domain/engine.service.js +16 -2
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +2 -2
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +1 -1
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +19 -0
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +3 -3
- package/features/engine/domain/enveloppe/deperdition.service.js +2 -3
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.js +44 -0
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +81 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +3 -3
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +30 -10
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +2 -2
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +18 -6
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +2 -2
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +21 -7
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +1 -1
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +1 -1
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +1 -1
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +2 -2
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +1 -1
- package/features/engine/domain/logement/nadeq.service.js +63 -0
- package/features/engine/domain/logement/nadeq.service.spec.js +61 -0
- package/features/engine/domain/models/contexte.model.ts +19 -5
- package/features/engine/domain/models/deperdition.model.ts +1 -1
- package/package.json +1 -1
- /package/features/dpe/infrastructure/{pontThermiqueTv.store.spec.js → enveloppe/pontThermiqueTv.store.spec.js} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { mois_liste } from '../../../../utils.js';
|
|
2
|
+
import { inject } from 'dioma';
|
|
3
|
+
import { BaieVitreeTvStore } from '../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Calcul de la surface sud équivalente du logement
|
|
7
|
+
* Chapitre 6.2 Détermination de la surface Sud équivalente
|
|
8
|
+
*
|
|
9
|
+
* Methode_de_calcul_3CL_DPE_2021 - Page 45
|
|
10
|
+
* Octobre 2021
|
|
11
|
+
* @see consolide_anne…arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
|
|
12
|
+
*/
|
|
13
|
+
export class SurfaceSudEquivalenteService {
|
|
14
|
+
/**
|
|
15
|
+
* @type {BaieVitreeTvStore}
|
|
16
|
+
*/
|
|
17
|
+
#tvStore;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param tvStore {BaieVitreeTvStore}
|
|
21
|
+
*/
|
|
22
|
+
constructor(tvStore = inject(BaieVitreeTvStore)) {
|
|
23
|
+
this.#tvStore = tvStore;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param ctx {Contexte}
|
|
28
|
+
* @param enveloppe {Enveloppe}
|
|
29
|
+
* @return {number}
|
|
30
|
+
*/
|
|
31
|
+
execute(ctx, enveloppe) {
|
|
32
|
+
return mois_liste.reduce((acc, mois) => acc + this.ssdMois(ctx, enveloppe, mois), 0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Calcul de la surface sud équivalente du logement pour un mois donné
|
|
37
|
+
*
|
|
38
|
+
* @param ctx {Contexte}
|
|
39
|
+
* @param enveloppe {Enveloppe}
|
|
40
|
+
* @param mois {string}
|
|
41
|
+
* @returns {number}
|
|
42
|
+
*/
|
|
43
|
+
ssdMois(ctx, enveloppe, mois) {
|
|
44
|
+
const baiesVitrees = enveloppe.baie_vitree_collection?.baie_vitree || [];
|
|
45
|
+
let ets = enveloppe.ets_collection?.ets || [];
|
|
46
|
+
|
|
47
|
+
let SseVerandaj = 0;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Si une véranda est présente, on calcul l'mpact de l’espace tampon solarisé sur les apports solaires à travers
|
|
51
|
+
* les baies vitrées qui séparent le logement de l'espace tampon
|
|
52
|
+
*
|
|
53
|
+
* 6.3 Traitement des espaces tampons solarisés
|
|
54
|
+
* 10 - 'espace tampon solarisé (véranda,loggia fermée)'
|
|
55
|
+
*/
|
|
56
|
+
if (ets) {
|
|
57
|
+
// Certaines vérandas sont dupliqués dans les DPE.
|
|
58
|
+
if (Array.isArray(ets)) {
|
|
59
|
+
ets = ets[0];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (ets) {
|
|
63
|
+
const bver = ets.donnee_intermediaire.bver;
|
|
64
|
+
const T = ets.donnee_intermediaire.coef_transparence_ets;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Surface sud équivalente représentant l’impact des apports solaires associés au rayonnement solaire
|
|
68
|
+
* traversant directement l’espace tampon pour arriver dans la partie habitable du logement
|
|
69
|
+
* Calculés pour les baies vitrées qui séparent le logement de l'espace tampon
|
|
70
|
+
* @type {number}
|
|
71
|
+
*/
|
|
72
|
+
const Ssdj = this.getBaiesSurEspaceTampon(baiesVitrees).reduce((acc, bv) => {
|
|
73
|
+
return acc + T * this.ssdBaieMois(bv, ctx.zoneClimatique.id, mois);
|
|
74
|
+
}, 0);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Surface sud équivalente représentant les apports solaires indirects dans le logement
|
|
78
|
+
*/
|
|
79
|
+
let baies = ets.baie_ets_collection.baie_ets;
|
|
80
|
+
|
|
81
|
+
if (!Array.isArray(baies)) {
|
|
82
|
+
baies = [baies];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Apports totaux à travers l'espace tampon
|
|
87
|
+
* @type {number}
|
|
88
|
+
*/
|
|
89
|
+
const Sstj = baies.reduce((acc, bv) => {
|
|
90
|
+
return acc + this.ssdBaieMois(bv, ctx.zoneClimatique.id, mois, 0.8 * T + 0.024);
|
|
91
|
+
}, 0);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Surface sud équivalente représentant l’impact des apports solaires indirects associés au rayonnement
|
|
95
|
+
* solaire entrant dans la partie habitable du logement après de multiples réflexions dans l’espace tampon solarisé
|
|
96
|
+
* @type {number}
|
|
97
|
+
*/
|
|
98
|
+
const Ssindj = Sstj - Ssdj;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Impact de l’espace tampon solarisé sur les apports solaires à travers les baies vitrées qui séparent le logement
|
|
102
|
+
* de l'espace tampon
|
|
103
|
+
* @type {number}
|
|
104
|
+
*/
|
|
105
|
+
SseVerandaj = Ssdj + Ssindj * bver;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return baiesVitrees.reduce((acc, baieVitree) => {
|
|
110
|
+
const typeAdjacence = parseInt(baieVitree.donnee_entree.enum_type_adjacence_id);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 6.3 Traitement des espaces tampons solarisés
|
|
114
|
+
* 10 - 'espace tampon solarisé (véranda,loggia fermée)'
|
|
115
|
+
*/
|
|
116
|
+
if (typeAdjacence === 10 && ets) {
|
|
117
|
+
return acc + SseVerandaj;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Pour les fenêtres qui ne donnent pas sur l'extérieur, pas de surface sud équivalente
|
|
121
|
+
if (typeAdjacence !== 1) {
|
|
122
|
+
return acc;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return acc + this.ssdBaieMois(baieVitree, ctx.zoneClimatique.id, mois);
|
|
126
|
+
}, 0);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Retourne la liste des baies vitrées qui donnent sur l'espace tampon solarisé
|
|
131
|
+
* @param baiesVitrees {BaieVitree[]}
|
|
132
|
+
*/
|
|
133
|
+
getBaiesSurEspaceTampon(baiesVitrees) {
|
|
134
|
+
return baiesVitrees.filter((bv) => parseInt(bv.donnee_entree.enum_type_adjacence_id) === 10);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Calcul de la surface sud équivalente pour une baie vitrée bv et pendant un mois donné
|
|
139
|
+
*
|
|
140
|
+
* @param baieVitree {BaieVitree|BaieEts}
|
|
141
|
+
* @param zc {string} zone climatique du logement
|
|
142
|
+
* @param mois {string} mois au cours duquel calculer la surface sur équivalente de la baie vitrée
|
|
143
|
+
* @param coeff {number} coefficient à appliquer à cette surface sud
|
|
144
|
+
* @returns {number}
|
|
145
|
+
*/
|
|
146
|
+
ssdBaieMois(baieVitree, zc, mois, coeff) {
|
|
147
|
+
const baieVitreeDE = baieVitree.donnee_entree;
|
|
148
|
+
const baieVitreeDI = baieVitree.donnee_intermediaire || {};
|
|
149
|
+
|
|
150
|
+
const C1 = this.#tvStore.getCoefficientBaieVitree(
|
|
151
|
+
parseInt(baieVitreeDE.enum_orientation_id),
|
|
152
|
+
parseInt(baieVitreeDE.enum_inclinaison_vitrage_id ?? 3),
|
|
153
|
+
parseInt(zc),
|
|
154
|
+
mois
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const fe1 = baieVitreeDI.fe1 ?? 1;
|
|
158
|
+
const fe2 = baieVitreeDI.fe2 ?? 1;
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
baieVitreeDE.surface_totale_baie *
|
|
162
|
+
C1 *
|
|
163
|
+
(coeff || baieVitree.donnee_intermediaire.sw) *
|
|
164
|
+
fe1 *
|
|
165
|
+
fe2
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import corpus from '../../../../../test/corpus-sano.json';
|
|
2
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
3
|
+
import { DpeNormalizerService } from '../../../normalizer/domain/dpe-normalizer.service.js';
|
|
4
|
+
import { ContexteBuilder } from '../contexte.builder.js';
|
|
5
|
+
import { SurfaceSudEquivalenteService } from './surface-sud-equivalente.service.js';
|
|
6
|
+
import { getAdemeFileJson } from '../../../../../test/test-helpers.js';
|
|
7
|
+
import { BaieVitreeTvStore } from '../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
|
|
8
|
+
|
|
9
|
+
/** @type {SurfaceSudEquivalenteService} **/
|
|
10
|
+
let service;
|
|
11
|
+
|
|
12
|
+
/** @type {DpeNormalizerService} **/
|
|
13
|
+
let normalizerService;
|
|
14
|
+
|
|
15
|
+
/** @type {ContexteBuilder} **/
|
|
16
|
+
let contexteBuilder;
|
|
17
|
+
|
|
18
|
+
/** @type {BaieVitreeTvStore} **/
|
|
19
|
+
let tvStore;
|
|
20
|
+
|
|
21
|
+
describe('Calcul de la surface sud équivalente du logement', () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
tvStore = new BaieVitreeTvStore();
|
|
24
|
+
service = new SurfaceSudEquivalenteService(tvStore);
|
|
25
|
+
normalizerService = new DpeNormalizerService();
|
|
26
|
+
contexteBuilder = new ContexteBuilder();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('Determination de la surface sud équivalente pour une baie vitrée bv et pendant un mois donné', () => {
|
|
30
|
+
test.each([
|
|
31
|
+
{
|
|
32
|
+
enumOrientationId: 2,
|
|
33
|
+
enumInclinaisonVitrageId: 3,
|
|
34
|
+
fe1: 1,
|
|
35
|
+
fe2: 1,
|
|
36
|
+
sw: 0.2,
|
|
37
|
+
coeff: 1,
|
|
38
|
+
expected: 5
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
enumOrientationId: 2,
|
|
42
|
+
enumInclinaisonVitrageId: undefined,
|
|
43
|
+
fe1: 1,
|
|
44
|
+
fe2: 1,
|
|
45
|
+
sw: 0.2,
|
|
46
|
+
coeff: 1,
|
|
47
|
+
expected: 5
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
enumOrientationId: 2,
|
|
51
|
+
enumInclinaisonVitrageId: undefined,
|
|
52
|
+
fe1: 1,
|
|
53
|
+
fe2: 1,
|
|
54
|
+
sw: 0.2,
|
|
55
|
+
coeff: undefined,
|
|
56
|
+
expected: 1
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
enumOrientationId: 2,
|
|
60
|
+
enumInclinaisonVitrageId: 3,
|
|
61
|
+
fe1: 0.5,
|
|
62
|
+
fe2: 0.5,
|
|
63
|
+
sw: 0.2,
|
|
64
|
+
coeff: 1,
|
|
65
|
+
expected: 1.25
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
enumOrientationId: 2,
|
|
69
|
+
enumInclinaisonVitrageId: 3,
|
|
70
|
+
fe1: undefined,
|
|
71
|
+
fe2: undefined,
|
|
72
|
+
sw: 0.2,
|
|
73
|
+
coeff: 1,
|
|
74
|
+
expected: 5
|
|
75
|
+
}
|
|
76
|
+
])(
|
|
77
|
+
'enumOrientationId: $enumOrientationId, enumInclinaisonVitrageId: $enumInclinaisonVitrageId, fe1: $fe1,' +
|
|
78
|
+
'fe2: $fe2, sw: $sw, coeff: $coeff',
|
|
79
|
+
({
|
|
80
|
+
enumOrientationId,
|
|
81
|
+
enumInclinaisonVitrageId = undefined,
|
|
82
|
+
fe1,
|
|
83
|
+
fe2,
|
|
84
|
+
sw,
|
|
85
|
+
coeff = undefined,
|
|
86
|
+
expected
|
|
87
|
+
}) => {
|
|
88
|
+
vi.spyOn(tvStore, 'getCoefficientBaieVitree').mockReturnValue(0.5);
|
|
89
|
+
|
|
90
|
+
/** @type {BaieVitree} */
|
|
91
|
+
const baieVitree = {
|
|
92
|
+
donnee_entree: {
|
|
93
|
+
enum_orientation_id: enumOrientationId,
|
|
94
|
+
enum_inclinaison_vitrage_id: enumInclinaisonVitrageId,
|
|
95
|
+
surface_totale_baie: 10
|
|
96
|
+
},
|
|
97
|
+
donnee_intermediaire: { fe1, fe2, sw }
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const ssd = service.ssdBaieMois(baieVitree, '1', 'Janvier', coeff);
|
|
101
|
+
|
|
102
|
+
if (enumInclinaisonVitrageId === undefined) {
|
|
103
|
+
enumInclinaisonVitrageId = 3;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
expect(tvStore.getCoefficientBaieVitree).toHaveBeenCalledWith(
|
|
107
|
+
enumOrientationId,
|
|
108
|
+
enumInclinaisonVitrageId,
|
|
109
|
+
1,
|
|
110
|
+
'Janvier'
|
|
111
|
+
);
|
|
112
|
+
expect(ssd).toBe(expected);
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('Determination de la surface sud équivalente des baies vitrées bv', () => {
|
|
118
|
+
test("Aucune pour les baies vitrées qui ne donnent pas sur l'extérieur", () => {
|
|
119
|
+
expect(service.execute({}, [])).toBe(0);
|
|
120
|
+
|
|
121
|
+
/** @type {Enveloppe} */
|
|
122
|
+
const enveloppe = {
|
|
123
|
+
baie_vitree_collection: {
|
|
124
|
+
baie_vitree: [
|
|
125
|
+
{
|
|
126
|
+
donnee_entree: { enum_type_adjacence_id: 18 }
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
expect(service.ssdMois({}, enveloppe, 'Janvier')).toBe(0);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("Baies vitrées donnant sur l'extérieur", () => {
|
|
135
|
+
vi.spyOn(tvStore, 'getCoefficientBaieVitree').mockReturnValue(0.5);
|
|
136
|
+
|
|
137
|
+
/** @type {Contexte} */
|
|
138
|
+
const ctx = { zoneClimatique: { id: 1 } };
|
|
139
|
+
|
|
140
|
+
/** @type {Enveloppe} */
|
|
141
|
+
const enveloppe = {
|
|
142
|
+
baie_vitree_collection: {
|
|
143
|
+
baie_vitree: [
|
|
144
|
+
{
|
|
145
|
+
donnee_entree: {
|
|
146
|
+
enum_type_adjacence_id: 1,
|
|
147
|
+
enum_orientation_id: 2,
|
|
148
|
+
surface_totale_baie: 10
|
|
149
|
+
},
|
|
150
|
+
donnee_intermediaire: { sw: 1 }
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
expect(service.ssdMois(ctx, enveloppe, 'Janvier')).toBe(5);
|
|
156
|
+
expect(tvStore.getCoefficientBaieVitree).toHaveBeenCalledWith(2, 3, 1, 'Janvier');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('Baies vitrées donnant sur un espace tampon solarisé', () => {
|
|
160
|
+
vi.spyOn(tvStore, 'getCoefficientBaieVitree').mockReturnValue(0.5);
|
|
161
|
+
|
|
162
|
+
/** @type {Contexte} */
|
|
163
|
+
const ctx = { zoneClimatique: { id: 1 } };
|
|
164
|
+
|
|
165
|
+
/** @type {Enveloppe} */
|
|
166
|
+
const enveloppe = {
|
|
167
|
+
baie_vitree_collection: {
|
|
168
|
+
baie_vitree: [
|
|
169
|
+
{
|
|
170
|
+
donnee_entree: {
|
|
171
|
+
enum_type_adjacence_id: 10,
|
|
172
|
+
enum_orientation_id: 2,
|
|
173
|
+
surface_totale_baie: 10
|
|
174
|
+
},
|
|
175
|
+
donnee_intermediaire: { sw: 1 }
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
donnee_entree: {
|
|
179
|
+
enum_type_adjacence_id: 1,
|
|
180
|
+
enum_orientation_id: 2,
|
|
181
|
+
surface_totale_baie: 10
|
|
182
|
+
},
|
|
183
|
+
donnee_intermediaire: { sw: 1 }
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
ets_collection: {
|
|
188
|
+
ets: {
|
|
189
|
+
donnee_intermediaire: { bver: 0.6, coef_transparence_ets: 0.4 },
|
|
190
|
+
baie_ets_collection: {
|
|
191
|
+
baie_ets: {
|
|
192
|
+
donnee_entree: {
|
|
193
|
+
enum_inclinaison_vitrage_id: 3,
|
|
194
|
+
enum_orientation_id: 1,
|
|
195
|
+
surface_totale_baie: 7
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
expect(service.ssdMois(ctx, enveloppe, 'Janvier')).toBe(6.5224);
|
|
204
|
+
expect(tvStore.getCoefficientBaieVitree).toHaveBeenCalledWith(2, 3, 1, 'Janvier');
|
|
205
|
+
expect(tvStore.getCoefficientBaieVitree).toHaveBeenCalledWith(1, 3, 1, 'Janvier');
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe("Test d'intégration pour surface sud équivalente", () => {
|
|
210
|
+
test.each(corpus)(
|
|
211
|
+
'vérification des DI de la surface sud équivalente pour dpe %s',
|
|
212
|
+
(ademeId) => {
|
|
213
|
+
/**
|
|
214
|
+
* @type {Dpe}
|
|
215
|
+
*/
|
|
216
|
+
let dpeRequest = getAdemeFileJson(ademeId);
|
|
217
|
+
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
218
|
+
|
|
219
|
+
/** @type {Contexte} */
|
|
220
|
+
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
221
|
+
|
|
222
|
+
const sse = service.execute(ctx, dpeRequest.logement.enveloppe);
|
|
223
|
+
expect(sse).toBeCloseTo(
|
|
224
|
+
dpeRequest.logement.sortie.apport_et_besoin.surface_sud_equivalente,
|
|
225
|
+
2
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -1,24 +1,84 @@
|
|
|
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';
|
|
3
|
+
import { NadeqService } from './logement/nadeq.service.js';
|
|
4
|
+
import { inject } from 'dioma';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* Génère un contexte du logement à étudier avec des données persistées durant l'analyse
|
|
5
8
|
*/
|
|
6
9
|
export class ContexteBuilder {
|
|
7
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @type {NadeqService}
|
|
12
|
+
*/
|
|
13
|
+
#nadeqService;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param nadeqService {NadeqService}
|
|
17
|
+
*/
|
|
18
|
+
constructor(nadeqService = inject(NadeqService)) {
|
|
19
|
+
this.#nadeqService = nadeqService;
|
|
20
|
+
}
|
|
8
21
|
|
|
9
22
|
/**
|
|
10
23
|
* @param dpe {Dpe}
|
|
11
24
|
* @return {Contexte}
|
|
12
25
|
*/
|
|
13
26
|
fromDpe(dpe) {
|
|
27
|
+
const caracteristiqueGenerale = dpe.logement.caracteristique_generale;
|
|
28
|
+
|
|
29
|
+
const typeDpe = this.#getTypeDpe(caracteristiqueGenerale);
|
|
30
|
+
const surfaceHabitable = this.#getSurfaceHabitable(caracteristiqueGenerale);
|
|
31
|
+
const inertieId = parseInt(dpe.logement.enveloppe?.inertie?.enum_classe_inertie_id);
|
|
32
|
+
|
|
14
33
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
34
|
+
zoneClimatique: this.#zoneClimatique(dpe),
|
|
35
|
+
altitude: this.#altitude(dpe),
|
|
36
|
+
typeHabitation: this.#getTypeHabitation(caracteristiqueGenerale),
|
|
37
|
+
typeDpe: typeDpe,
|
|
38
|
+
enumPeriodeConstructionId: caracteristiqueGenerale.enum_periode_construction_id?.toString(),
|
|
19
39
|
effetJoule: this.#hasEffetJoule(dpe),
|
|
20
|
-
surfaceHabitable:
|
|
21
|
-
hauteurSousPlafond:
|
|
40
|
+
surfaceHabitable: surfaceHabitable,
|
|
41
|
+
hauteurSousPlafond: caracteristiqueGenerale.hsp,
|
|
42
|
+
nombreAppartement: caracteristiqueGenerale.nombre_appartement,
|
|
43
|
+
nadeq: this.#nadeqService.execute(
|
|
44
|
+
typeDpe,
|
|
45
|
+
surfaceHabitable,
|
|
46
|
+
caracteristiqueGenerale.nombre_appartement
|
|
47
|
+
),
|
|
48
|
+
inertie: {
|
|
49
|
+
id: inertieId,
|
|
50
|
+
ilpa:
|
|
51
|
+
parseInt(dpe.logement.meteo?.batiment_materiaux_anciens) === 1 &&
|
|
52
|
+
[1, 2].includes(inertieId)
|
|
53
|
+
? 1
|
|
54
|
+
: 0
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* La zone climatique à partir du type de DPE
|
|
61
|
+
* @param dpe {Dpe}
|
|
62
|
+
* @return {{id: string, value: string}}
|
|
63
|
+
*/
|
|
64
|
+
#zoneClimatique(dpe) {
|
|
65
|
+
const zoneClimatiqueId = parseInt(dpe.logement.meteo?.enum_zone_climatique_id);
|
|
66
|
+
return {
|
|
67
|
+
id: zoneClimatiqueId.toString(),
|
|
68
|
+
value: enums.zone_climatique[zoneClimatiqueId]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* La classe d'altitude à partir du type de DPE
|
|
74
|
+
* @param dpe {Dpe}
|
|
75
|
+
* @return {{id: string, value: string}}
|
|
76
|
+
*/
|
|
77
|
+
#altitude(dpe) {
|
|
78
|
+
const altitudeId = parseInt(dpe.logement.meteo?.enum_classe_altitude_id);
|
|
79
|
+
return {
|
|
80
|
+
id: altitudeId.toString(),
|
|
81
|
+
value: enums.classe_altitude[altitudeId]
|
|
22
82
|
};
|
|
23
83
|
}
|
|
24
84
|
|
|
@@ -39,43 +99,20 @@ export class ContexteBuilder {
|
|
|
39
99
|
|
|
40
100
|
/**
|
|
41
101
|
* Le type d'habitation est détecté à partir du type de DPE
|
|
42
|
-
* @param
|
|
102
|
+
* @param caracteristiqueGenerale {CaracteristiqueGenerale}
|
|
43
103
|
* @return {TypeHabitation}
|
|
44
104
|
*/
|
|
45
|
-
#getTypeHabitation(
|
|
46
|
-
const methodeApplication =
|
|
47
|
-
|
|
105
|
+
#getTypeHabitation(caracteristiqueGenerale) {
|
|
106
|
+
const methodeApplication = parseInt(
|
|
107
|
+
caracteristiqueGenerale.enum_methode_application_dpe_log_id
|
|
108
|
+
);
|
|
48
109
|
|
|
49
|
-
if ([
|
|
110
|
+
if ([1, 14, 18].includes(methodeApplication)) {
|
|
50
111
|
return TypeHabitation.MAISON;
|
|
51
112
|
} else if (
|
|
52
113
|
[
|
|
53
|
-
|
|
54
|
-
|
|
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'
|
|
114
|
+
2, 3, 4, 5, 10, 11, 12, 13, 15, 16, 19, 20, 22, 23, 24, 25, 31, 32, 33, 34, 35, 36, 37, 38,
|
|
115
|
+
39, 40
|
|
79
116
|
].includes(methodeApplication)
|
|
80
117
|
) {
|
|
81
118
|
return TypeHabitation.APPARTEMENT;
|
|
@@ -84,10 +121,28 @@ export class ContexteBuilder {
|
|
|
84
121
|
}
|
|
85
122
|
|
|
86
123
|
/**
|
|
87
|
-
*
|
|
124
|
+
* Le type de DPE est détecté à partir du type de DPE
|
|
125
|
+
* @param caracteristiqueGenerale {CaracteristiqueGenerale}
|
|
126
|
+
* @return {TypeDpe}
|
|
127
|
+
*/
|
|
128
|
+
#getTypeDpe(caracteristiqueGenerale) {
|
|
129
|
+
const methodeApplication = parseInt(
|
|
130
|
+
caracteristiqueGenerale.enum_methode_application_dpe_log_id
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
if ([1, 14, 18].includes(methodeApplication)) {
|
|
134
|
+
return TypeDpe.MAISON;
|
|
135
|
+
} else if ([2, 3, 4, 5, 31, 32, 35, 36, 37].includes(methodeApplication)) {
|
|
136
|
+
return TypeDpe.APPARTEMENT;
|
|
137
|
+
}
|
|
138
|
+
return TypeDpe.IMMEUBLE;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param caracteristiqueGenerale {CaracteristiqueGenerale}
|
|
88
143
|
* @return {number}
|
|
89
144
|
*/
|
|
90
|
-
#getSurfaceHabitable(
|
|
145
|
+
#getSurfaceHabitable(caracteristiqueGenerale) {
|
|
91
146
|
/**
|
|
92
147
|
* Certains DPE appartement sont générés à partir des données du DPE immeuble, la surface à prendre en compte est
|
|
93
148
|
* celle de l'immeuble pour les besoins ECS
|
|
@@ -110,31 +165,15 @@ export class ContexteBuilder {
|
|
|
110
165
|
* 40 - dpe appartement généré à partir des données DPE immeuble chauffage collectif ecs mixte (collectif-individuel)
|
|
111
166
|
*/
|
|
112
167
|
if (
|
|
113
|
-
[
|
|
114
|
-
|
|
115
|
-
|
|
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)
|
|
168
|
+
[10, 11, 12, 13, 15, 16, 19, 20, 22, 23, 24, 25, 33, 34, 38, 39, 40].includes(
|
|
169
|
+
parseInt(caracteristiqueGenerale.enum_methode_application_dpe_log_id)
|
|
170
|
+
)
|
|
132
171
|
) {
|
|
133
|
-
return
|
|
172
|
+
return caracteristiqueGenerale.surface_habitable_immeuble;
|
|
134
173
|
}
|
|
135
174
|
|
|
136
|
-
return this.#getTypeHabitation(
|
|
137
|
-
?
|
|
138
|
-
:
|
|
175
|
+
return this.#getTypeHabitation(caracteristiqueGenerale) === TypeHabitation.IMMEUBLE
|
|
176
|
+
? caracteristiqueGenerale.surface_habitable_immeuble
|
|
177
|
+
: caracteristiqueGenerale.surface_habitable_logement;
|
|
139
178
|
}
|
|
140
179
|
}
|