@open3cl/engine 1.0.7 → 1.0.9
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/baie-vitree.model.ts +8 -6
- package/features/dpe/domain/models/dpe.model.ts +7 -3
- package/features/dpe/domain/models/{plancher-bas.model.ts → plancher.model.ts} +31 -7
- package/features/dpe/infrastructure/baieVitreeTv.store.js +292 -0
- package/features/dpe/infrastructure/baieVitreeTv.store.spec.js +352 -0
- package/features/dpe/infrastructure/pontThermiqueTv.store.js +112 -0
- package/features/dpe/infrastructure/pontThermiqueTv.store.spec.js +134 -0
- package/features/dpe/infrastructure/tv.store.js +0 -33
- package/features/dpe/infrastructure/tv.store.spec.js +0 -83
- package/features/engine/domain/engine.service.js +2 -1
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +292 -0
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +484 -0
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +38 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +28 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +61 -0
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +46 -0
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +85 -0
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +33 -0
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +61 -0
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +439 -0
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +636 -0
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +49 -0
- package/package.json +1 -1
- package/features/dpe/domain/models/plancher-haut.model.ts +0 -33
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import corpus from '../../../../../../test/corpus-sano.json';
|
|
2
|
+
import { getAdemeFileJson } from '../../../../../../test/test-helpers.js';
|
|
3
|
+
import { ContexteBuilder } from '../../contexte.builder.js';
|
|
4
|
+
import { DpeNormalizerService } from '../../../../normalizer/domain/dpe-normalizer.service.js';
|
|
5
|
+
import { DeperditionBaieVitreeService } from './deperdition-baie-vitree.service.js';
|
|
6
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
7
|
+
import { BaieVitreeTvStore } from '../../../../dpe/infrastructure/baieVitreeTv.store.js';
|
|
8
|
+
|
|
9
|
+
/** @type {DeperditionBaieVitreeService} **/
|
|
10
|
+
let service;
|
|
11
|
+
|
|
12
|
+
/** @type {DpeNormalizerService} **/
|
|
13
|
+
let normalizerService;
|
|
14
|
+
|
|
15
|
+
/** @type {BaieVitreeTvStore} **/
|
|
16
|
+
let tvStore;
|
|
17
|
+
|
|
18
|
+
/** @type {ContexteBuilder} **/
|
|
19
|
+
let contexteBuilder;
|
|
20
|
+
|
|
21
|
+
describe('Calcul de déperdition des baies vitrées', () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
tvStore = new BaieVitreeTvStore();
|
|
24
|
+
service = new DeperditionBaieVitreeService(tvStore);
|
|
25
|
+
normalizerService = new DpeNormalizerService();
|
|
26
|
+
contexteBuilder = new ContexteBuilder();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe('Determination du coefficient sw', () => {
|
|
30
|
+
test('Doit retourner sw_saisi directement', () => {
|
|
31
|
+
vi.spyOn(tvStore, 'getSw').mockReturnValue(18.8);
|
|
32
|
+
/**
|
|
33
|
+
* @type {BaieVitree}
|
|
34
|
+
*/
|
|
35
|
+
let bv = {
|
|
36
|
+
donnee_entree: {
|
|
37
|
+
enum_type_materiaux_menuiserie_id: '1',
|
|
38
|
+
enum_type_vitrage_id: '2',
|
|
39
|
+
enum_type_baie_id: '6',
|
|
40
|
+
vitrage_vir: '1',
|
|
41
|
+
enum_type_pose_id: '3',
|
|
42
|
+
sw_saisi: 4.5
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
let sw = service.sw(bv);
|
|
47
|
+
expect(tvStore.getSw).not.toHaveBeenCalled();
|
|
48
|
+
expect(sw).toBe(4.5);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('Ne doit pas utiliser vitrage_vir et enum_type_pose_id si enum_type_materiaux_menuiserie_id = 1 ou 2', () => {
|
|
52
|
+
vi.spyOn(tvStore, 'getSw').mockReturnValue(18.8);
|
|
53
|
+
/**
|
|
54
|
+
* @type {BaieVitree}
|
|
55
|
+
*/
|
|
56
|
+
let bv = {
|
|
57
|
+
donnee_entree: {
|
|
58
|
+
enum_type_materiaux_menuiserie_id: '1',
|
|
59
|
+
enum_type_vitrage_id: '2',
|
|
60
|
+
enum_type_baie_id: '6',
|
|
61
|
+
vitrage_vir: '1',
|
|
62
|
+
enum_type_pose_id: '3'
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
let sw = service.sw(bv);
|
|
67
|
+
expect(tvStore.getSw).toHaveBeenCalledWith('2', '6', '1', undefined, undefined);
|
|
68
|
+
expect(sw).toBe(18.8);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('Doit utiliser vitrage_vir et enum_type_pose_id si enum_type_materiaux_menuiserie_id != 1 et != 2', () => {
|
|
72
|
+
vi.spyOn(tvStore, 'getSw').mockReturnValue(18.8);
|
|
73
|
+
/**
|
|
74
|
+
* @type {BaieVitree}
|
|
75
|
+
*/
|
|
76
|
+
let bv = {
|
|
77
|
+
donnee_entree: {
|
|
78
|
+
enum_type_materiaux_menuiserie_id: '4',
|
|
79
|
+
enum_type_vitrage_id: '2',
|
|
80
|
+
enum_type_baie_id: '6',
|
|
81
|
+
vitrage_vir: '1',
|
|
82
|
+
enum_type_pose_id: '3'
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
let sw = service.sw(bv);
|
|
87
|
+
expect(tvStore.getSw).toHaveBeenCalledWith('2', '6', '4', '1', '3');
|
|
88
|
+
expect(sw).toBe(18.8);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('Doit prendre en compte le survitrage si présent', () => {
|
|
92
|
+
vi.spyOn(tvStore, 'getSw').mockReturnValue(18.8);
|
|
93
|
+
/**
|
|
94
|
+
* @type {BaieVitree}
|
|
95
|
+
*/
|
|
96
|
+
let bv = {
|
|
97
|
+
donnee_entree: {
|
|
98
|
+
enum_type_materiaux_menuiserie_id: '4',
|
|
99
|
+
enum_type_vitrage_id: '2',
|
|
100
|
+
enum_type_baie_id: '6',
|
|
101
|
+
vitrage_vir: '1',
|
|
102
|
+
enum_type_pose_id: '3',
|
|
103
|
+
double_fenetre: 1
|
|
104
|
+
},
|
|
105
|
+
baie_vitree_double_fenetre: {
|
|
106
|
+
donnee_entree: {
|
|
107
|
+
enum_type_materiaux_menuiserie_id: '4',
|
|
108
|
+
enum_type_vitrage_id: '2',
|
|
109
|
+
enum_type_baie_id: '6',
|
|
110
|
+
vitrage_vir: '1',
|
|
111
|
+
enum_type_pose_id: '3'
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
let sw = service.sw(bv);
|
|
117
|
+
expect(tvStore.getSw).toHaveBeenNthCalledWith(2, '2', '6', '4', '1', '3');
|
|
118
|
+
expect(sw).toBe(18.8 * 18.8);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('Determination du coefficient uw', () => {
|
|
123
|
+
test('Doit retourner uw_saisi directement', () => {
|
|
124
|
+
vi.spyOn(tvStore, 'getUw').mockReturnValue(18.8);
|
|
125
|
+
|
|
126
|
+
let uw = service.uw({ donnee_entree: { uw_saisi: 16.4 } }, 2.4);
|
|
127
|
+
|
|
128
|
+
expect(tvStore.getUw).not.toHaveBeenCalled();
|
|
129
|
+
expect(uw).toBe(16.4);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('Doit appeler tvStore', () => {
|
|
133
|
+
vi.spyOn(tvStore, 'getUw').mockReturnValue(18.8);
|
|
134
|
+
|
|
135
|
+
let uw = service.uw(
|
|
136
|
+
{ donnee_entree: { enum_type_baie_id: '10', enum_type_materiaux_menuiserie_id: '1' } },
|
|
137
|
+
2.4
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
expect(tvStore.getUw).toHaveBeenCalledWith('10', '1', 2.4);
|
|
141
|
+
expect(uw).toBe(18.8);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('Doit prendre en compte le survitrage si présent', () => {
|
|
145
|
+
vi.spyOn(tvStore, 'getUw').mockReturnValue(18.8);
|
|
146
|
+
/**
|
|
147
|
+
* @type {BaieVitree}
|
|
148
|
+
*/
|
|
149
|
+
let bv = {
|
|
150
|
+
donnee_entree: {
|
|
151
|
+
ug_saisi: 2.5,
|
|
152
|
+
enum_type_materiaux_menuiserie_id: '4',
|
|
153
|
+
enum_type_baie_id: '6',
|
|
154
|
+
double_fenetre: 1
|
|
155
|
+
},
|
|
156
|
+
baie_vitree_double_fenetre: {
|
|
157
|
+
donnee_entree: {
|
|
158
|
+
ug_saisi: 2.5,
|
|
159
|
+
enum_type_materiaux_menuiserie_id: '4',
|
|
160
|
+
enum_type_baie_id: '6'
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
let uw = service.uw(bv, 2.4);
|
|
166
|
+
expect(tvStore.getUw).toHaveBeenNthCalledWith(2, '6', '4', 2.5);
|
|
167
|
+
expect(uw).toBe(1 / (1 / 18.8 + 1 / 18.8 + 0.07));
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('Determination du coefficient ug', () => {
|
|
172
|
+
test('Doit retourner ug_saisi directement', () => {
|
|
173
|
+
vi.spyOn(tvStore, 'getUg').mockReturnValue(18.8);
|
|
174
|
+
|
|
175
|
+
let ug = service.ug({ ug_saisi: 16.4 });
|
|
176
|
+
|
|
177
|
+
expect(tvStore.getUg).not.toHaveBeenCalled();
|
|
178
|
+
expect(ug).toBe(16.4);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('Ne retourne aucune valeur pour les parois en brique ou polycarbonate', () => {
|
|
182
|
+
vi.spyOn(tvStore, 'getUg').mockReturnValue(18.8);
|
|
183
|
+
|
|
184
|
+
let ug = service.ug({ enum_type_baie_id: '1' });
|
|
185
|
+
|
|
186
|
+
expect(tvStore.getUg).not.toHaveBeenCalled();
|
|
187
|
+
expect(ug).toBeUndefined();
|
|
188
|
+
|
|
189
|
+
ug = service.ug({ enum_type_baie_id: '2' });
|
|
190
|
+
|
|
191
|
+
expect(tvStore.getUg).not.toHaveBeenCalled();
|
|
192
|
+
expect(ug).toBeUndefined();
|
|
193
|
+
|
|
194
|
+
ug = service.ug({ enum_type_baie_id: '3' });
|
|
195
|
+
|
|
196
|
+
expect(tvStore.getUg).not.toHaveBeenCalled();
|
|
197
|
+
expect(ug).toBeUndefined();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test('Doit appeler tvStore sans epaisseur, enum_type_gaz_lame_id, enum_inclinaison_vitrage_id, vitrage_vir pour les simples vitrages', () => {
|
|
201
|
+
vi.spyOn(tvStore, 'getUg').mockReturnValue(18.8);
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @type {BaieVitreeDE}
|
|
205
|
+
*/
|
|
206
|
+
let bvDE = {
|
|
207
|
+
enum_type_vitrage_id: '1',
|
|
208
|
+
vitrage_vir: '1',
|
|
209
|
+
enum_inclinaison_vitrage_id: '1',
|
|
210
|
+
enum_type_gaz_lame_id: '1',
|
|
211
|
+
epaisseur_lame: '18'
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
let uw = service.ug(bvDE);
|
|
215
|
+
|
|
216
|
+
expect(tvStore.getUg).toHaveBeenCalledWith('1', undefined, undefined, undefined, undefined);
|
|
217
|
+
expect(uw).toBe(18.8);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test('Doit appeler tvStore avec epaisseur, enum_type_gaz_lame_id, enum_inclinaison_vitrage_id, vitrage_vir pour les doubles vitrages', () => {
|
|
221
|
+
vi.spyOn(tvStore, 'getUg').mockReturnValue(18.8);
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @type {BaieVitreeDE}
|
|
225
|
+
*/
|
|
226
|
+
let bvDE = {
|
|
227
|
+
enum_type_vitrage_id: '2',
|
|
228
|
+
vitrage_vir: '1',
|
|
229
|
+
enum_inclinaison_vitrage_id: '2',
|
|
230
|
+
enum_type_gaz_lame_id: '1',
|
|
231
|
+
epaisseur_lame: '18'
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
let uw = service.ug(bvDE);
|
|
235
|
+
|
|
236
|
+
expect(tvStore.getUg).toHaveBeenCalledWith('2', '1', '2', '1', 18);
|
|
237
|
+
expect(uw).toBe(18.8);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("Doit appeler tvStore avec l'epaisseur la plus proche dans celles qui sont disponibles", () => {
|
|
241
|
+
vi.spyOn(tvStore, 'getUg').mockReturnValue(18.8);
|
|
242
|
+
vi.spyOn(tvStore, 'getEpaisseurAvailableForUg').mockReturnValue([2, 4, 8]);
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @type {BaieVitreeDE}
|
|
246
|
+
*/
|
|
247
|
+
let bvDE = {
|
|
248
|
+
enum_type_vitrage_id: '2',
|
|
249
|
+
vitrage_vir: '1',
|
|
250
|
+
enum_inclinaison_vitrage_id: '2',
|
|
251
|
+
enum_type_gaz_lame_id: '1',
|
|
252
|
+
epaisseur_lame: '18'
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
let uw = service.ug(bvDE);
|
|
256
|
+
|
|
257
|
+
expect(tvStore.getUg).toHaveBeenCalledWith('2', '1', '2', '1', 8);
|
|
258
|
+
expect(uw).toBe(18.8);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('Doit appeler tvStore avec un équivalent double vitrage pour un sur vitrage avec majoration de 0.1', () => {
|
|
262
|
+
vi.spyOn(tvStore, 'getUg').mockReturnValue(18.8);
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @type {BaieVitreeDE}
|
|
266
|
+
*/
|
|
267
|
+
let bvDE = {
|
|
268
|
+
enum_type_vitrage_id: '4',
|
|
269
|
+
vitrage_vir: '0',
|
|
270
|
+
enum_inclinaison_vitrage_id: '3',
|
|
271
|
+
enum_type_gaz_lame_id: '1',
|
|
272
|
+
epaisseur_lame: '20'
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
let uw = service.ug(bvDE);
|
|
276
|
+
|
|
277
|
+
expect(tvStore.getUg).toHaveBeenCalledWith('2', '1', '3', '0', 20);
|
|
278
|
+
expect(uw).toBe(18.8 + 0.1);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
describe('Determination du facteur d’ensoleillement', () => {
|
|
283
|
+
test('Doit retourner fe1 = 1 et fe2 = 1 si aucun masque', () => {
|
|
284
|
+
vi.spyOn(tvStore, 'getMasqueProche').mockReturnValue(1.2);
|
|
285
|
+
vi.spyOn(tvStore, 'getMasqueLointainHomogene').mockReturnValue(3.4);
|
|
286
|
+
vi.spyOn(tvStore, 'getOmbre').mockReturnValue(0.5);
|
|
287
|
+
|
|
288
|
+
let [fe1, fe2] = service.fe({});
|
|
289
|
+
|
|
290
|
+
expect(tvStore.getMasqueProche).not.toHaveBeenCalled();
|
|
291
|
+
expect(tvStore.getMasqueLointainHomogene).not.toHaveBeenCalled();
|
|
292
|
+
expect(tvStore.getOmbre).not.toHaveBeenCalled();
|
|
293
|
+
expect(fe1).toBe(1);
|
|
294
|
+
expect(fe2).toBe(1);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test('Doit utiliser tvStore pour les masques proches', () => {
|
|
298
|
+
vi.spyOn(tvStore, 'getMasqueProche').mockReturnValue(1.2);
|
|
299
|
+
vi.spyOn(tvStore, 'getMasqueLointainHomogene').mockReturnValue(3.4);
|
|
300
|
+
vi.spyOn(tvStore, 'getOmbre').mockReturnValue(0.5);
|
|
301
|
+
|
|
302
|
+
let [fe1, fe2] = service.fe({ tv_coef_masque_proche_id: '1' });
|
|
303
|
+
|
|
304
|
+
expect(tvStore.getMasqueProche).toHaveBeenCalledWith('1');
|
|
305
|
+
expect(tvStore.getMasqueLointainHomogene).not.toHaveBeenCalled();
|
|
306
|
+
expect(tvStore.getOmbre).not.toHaveBeenCalled();
|
|
307
|
+
expect(fe1).toBe(1.2);
|
|
308
|
+
expect(fe2).toBe(1);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test('Doit utiliser tvStore pour les masques lointains homogènes', () => {
|
|
312
|
+
vi.spyOn(tvStore, 'getMasqueProche').mockReturnValue(1.2);
|
|
313
|
+
vi.spyOn(tvStore, 'getMasqueLointainHomogene').mockReturnValue(3.4);
|
|
314
|
+
vi.spyOn(tvStore, 'getOmbre').mockReturnValue(0.5);
|
|
315
|
+
|
|
316
|
+
let [fe1, fe2] = service.fe({ tv_coef_masque_lointain_homogene_id: '2' });
|
|
317
|
+
|
|
318
|
+
expect(tvStore.getMasqueLointainHomogene).toHaveBeenCalledWith('2');
|
|
319
|
+
expect(tvStore.getMasqueProche).not.toHaveBeenCalled();
|
|
320
|
+
expect(tvStore.getOmbre).not.toHaveBeenCalled();
|
|
321
|
+
expect(fe1).toBe(1);
|
|
322
|
+
expect(fe2).toBe(3.4);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test.each([
|
|
326
|
+
{
|
|
327
|
+
label: 'collection masque_lointain_non_homogene_collection undefined',
|
|
328
|
+
masqueLointainNonHomogene: undefined,
|
|
329
|
+
tvStoreMasqueLointainNonHomogene: undefined,
|
|
330
|
+
fe1Expected: 1,
|
|
331
|
+
fe2Expected: 1
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
label: 'collection masque_lointain_non_homogene_collection vide',
|
|
335
|
+
masqueLointainNonHomogene: { masque_lointain_non_homogene: undefined },
|
|
336
|
+
tvStoreMasqueLointainNonHomogene: undefined,
|
|
337
|
+
fe1Expected: 1,
|
|
338
|
+
fe2Expected: 1
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
label: 'collection masque_lointain_non_homogene_collection vide',
|
|
342
|
+
masqueLointainNonHomogene: { masque_lointain_non_homogene: [] },
|
|
343
|
+
tvStoreMasqueLointainNonHomogene: undefined,
|
|
344
|
+
fe1Expected: 1,
|
|
345
|
+
fe2Expected: 1
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
label: 'collection masque_lointain_non_homogene_collection non array',
|
|
349
|
+
masqueLointainNonHomogene: {
|
|
350
|
+
masque_lointain_non_homogene: { tv_coef_masque_lointain_non_homogene_id: '1' }
|
|
351
|
+
},
|
|
352
|
+
tvStoreMasqueLointainNonHomogene: '1',
|
|
353
|
+
fe1Expected: 1,
|
|
354
|
+
fe2Expected: 0.8
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
label: 'collection masque_lointain_non_homogene_collection array',
|
|
358
|
+
masqueLointainNonHomogene: {
|
|
359
|
+
masque_lointain_non_homogene: [
|
|
360
|
+
{ tv_coef_masque_lointain_non_homogene_id: '1' },
|
|
361
|
+
{ tv_coef_masque_lointain_non_homogene_id: '2' }
|
|
362
|
+
]
|
|
363
|
+
},
|
|
364
|
+
tvStoreMasqueLointainNonHomogene: '1',
|
|
365
|
+
fe1Expected: 1,
|
|
366
|
+
fe2Expected: 0.6
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
label: 'collection masque_lointain_non_homogene_collection array and fe2 min 0',
|
|
370
|
+
masqueLointainNonHomogene: {
|
|
371
|
+
masque_lointain_non_homogene: [
|
|
372
|
+
{ tv_coef_masque_lointain_non_homogene_id: '1' },
|
|
373
|
+
{ tv_coef_masque_lointain_non_homogene_id: '2' }
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
tvStoreMasqueLointainNonHomogene: '1',
|
|
377
|
+
tvStoreGetOmbreValue: 60,
|
|
378
|
+
fe1Expected: 1,
|
|
379
|
+
fe2Expected: 0
|
|
380
|
+
}
|
|
381
|
+
])(
|
|
382
|
+
'Doit utiliser tvStore pour les masques lointains non homogènes pour $label',
|
|
383
|
+
({
|
|
384
|
+
masqueLointainNonHomogene,
|
|
385
|
+
tvStoreMasqueLointainNonHomogene,
|
|
386
|
+
tvStoreGetOmbreValue = undefined,
|
|
387
|
+
fe1Expected,
|
|
388
|
+
fe2Expected
|
|
389
|
+
}) => {
|
|
390
|
+
vi.spyOn(tvStore, 'getMasqueProche').mockReturnValue(1.2);
|
|
391
|
+
vi.spyOn(tvStore, 'getMasqueLointainHomogene').mockReturnValue(3.4);
|
|
392
|
+
vi.spyOn(tvStore, 'getOmbre').mockReturnValue(tvStoreGetOmbreValue || 20);
|
|
393
|
+
|
|
394
|
+
let bvDE = {
|
|
395
|
+
masque_lointain_non_homogene_collection: masqueLointainNonHomogene
|
|
396
|
+
};
|
|
397
|
+
let [fe1, fe2] = service.fe(bvDE);
|
|
398
|
+
|
|
399
|
+
if (tvStoreMasqueLointainNonHomogene === undefined) {
|
|
400
|
+
expect(tvStore.getOmbre).not.toHaveBeenCalled();
|
|
401
|
+
} else {
|
|
402
|
+
expect(tvStore.getOmbre).toHaveBeenCalledWith(tvStoreMasqueLointainNonHomogene);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
expect(tvStore.getMasqueLointainHomogene).not.toHaveBeenCalled();
|
|
406
|
+
expect(tvStore.getMasqueProche).not.toHaveBeenCalled();
|
|
407
|
+
|
|
408
|
+
expect(fe1).toBeCloseTo(fe1Expected, 2);
|
|
409
|
+
expect(fe2).toBeCloseTo(fe2Expected, 2);
|
|
410
|
+
}
|
|
411
|
+
);
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
test('Récupération du coefficient ujn', () => {
|
|
415
|
+
vi.spyOn(tvStore, 'getUjn').mockReturnValue(18.8);
|
|
416
|
+
|
|
417
|
+
let ujn = service.ujn({ ujn_saisi: 16.4 }, 2.4);
|
|
418
|
+
|
|
419
|
+
expect(tvStore.getUjn).not.toHaveBeenCalled();
|
|
420
|
+
expect(ujn).toBe(16.4);
|
|
421
|
+
|
|
422
|
+
ujn = service.ujn({ enum_type_fermeture_id: 1 }, 2.4);
|
|
423
|
+
|
|
424
|
+
expect(tvStore.getUjn).toHaveBeenCalledWith(1, 2.4);
|
|
425
|
+
expect(ujn).toBe(18.8);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
test("Récupération de l'ombre apportée par un masque lointain", () => {
|
|
429
|
+
vi.spyOn(tvStore, 'getOmbre').mockReturnValue(12.4);
|
|
430
|
+
|
|
431
|
+
const ombre = service.calcOmbre({ tv_coef_masque_lointain_non_homogene_id: 16.4 });
|
|
432
|
+
|
|
433
|
+
expect(tvStore.getOmbre).toHaveBeenCalledWith(16.4);
|
|
434
|
+
expect(ombre).toBe(12.4);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
test('u_menuiserie est définit par ujn seulement pour les baie vitrée avec fermeture', () => {
|
|
438
|
+
let bvDI = service.execute(
|
|
439
|
+
{},
|
|
440
|
+
{ donnee_entree: { ujn_saisi: 5.6, enum_type_fermeture_id: 1 } }
|
|
441
|
+
);
|
|
442
|
+
expect(bvDI.u_menuiserie).toBeUndefined();
|
|
443
|
+
|
|
444
|
+
bvDI = service.execute({}, { donnee_entree: { ujn_saisi: 5.6, enum_type_fermeture_id: 2 } });
|
|
445
|
+
expect(bvDI.u_menuiserie).toBe(5.6);
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
describe("Test d'intégration des baies vitrées", () => {
|
|
449
|
+
test.each(corpus)('vérification des DI des baies vitrées pour dpe %s', (ademeId) => {
|
|
450
|
+
let dpeRequest = getAdemeFileJson(ademeId);
|
|
451
|
+
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
452
|
+
|
|
453
|
+
/** @type {Contexte} */
|
|
454
|
+
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
455
|
+
|
|
456
|
+
const bvs = dpeRequest.logement.enveloppe.baie_vitree_collection?.baie_vitree || [];
|
|
457
|
+
|
|
458
|
+
bvs.forEach((bv) => {
|
|
459
|
+
const di = service.execute(ctx, bv);
|
|
460
|
+
|
|
461
|
+
expect(di.b).toBeCloseTo(bv.donnee_intermediaire.b, 2);
|
|
462
|
+
|
|
463
|
+
if (bv.donnee_intermediaire.ug) {
|
|
464
|
+
expect(di.ug).toBeCloseTo(bv.donnee_intermediaire.ug, 2);
|
|
465
|
+
} else {
|
|
466
|
+
expect(di.ug).toBeUndefined();
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
expect(di.uw).toBeCloseTo(bv.donnee_intermediaire.uw, 2);
|
|
470
|
+
|
|
471
|
+
if (bv.donnee_intermediaire.ujn) {
|
|
472
|
+
expect(di.ujn).toBeCloseTo(bv.donnee_intermediaire.ujn, 2);
|
|
473
|
+
} else {
|
|
474
|
+
expect(di.ujn).toBeUndefined();
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
expect(di.u_menuiserie).toBeCloseTo(bv.donnee_intermediaire.u_menuiserie, 2);
|
|
478
|
+
expect(di.sw).toBeCloseTo(bv.donnee_intermediaire.sw, 2);
|
|
479
|
+
expect(di.fe1).toBeCloseTo(bv.donnee_intermediaire.fe1, 2);
|
|
480
|
+
expect(di.fe2).toBeCloseTo(bv.donnee_intermediaire.fe2, 2);
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
});
|
|
@@ -4,6 +4,8 @@ import { DeperditionPorteService } from './porte/deperdition-porte.service.js';
|
|
|
4
4
|
import { DeperditionPlancherBasService } from './plancher_bas/deperdition-plancher-bas.service.js';
|
|
5
5
|
import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plancher-haut.service.js';
|
|
6
6
|
import { DeperditionVentilationService } from './ventilation/deperdition-ventilation.service.js';
|
|
7
|
+
import { DeperditionBaieVitreeService } from './baie_vitree/deperdition-baie-vitree.service.js';
|
|
8
|
+
import { DeperditionPontThermiqueService } from './pont_thermique/deperdition-pont-thermique.service.js';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Calcul des déperditions de l’enveloppe
|
|
@@ -30,6 +32,16 @@ export class DeperditionEnveloppeService {
|
|
|
30
32
|
*/
|
|
31
33
|
#deperditionPlancherHautService;
|
|
32
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @type {DeperditionBaieVitreeService}
|
|
37
|
+
*/
|
|
38
|
+
#deperditionBaieVitreeService;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @type {DeperditionPontThermiqueService}
|
|
42
|
+
*/
|
|
43
|
+
#deperditionPontThermiqueService;
|
|
44
|
+
|
|
33
45
|
/**
|
|
34
46
|
* @type {DeperditionVentilationService}
|
|
35
47
|
*/
|
|
@@ -66,6 +78,8 @@ export class DeperditionEnveloppeService {
|
|
|
66
78
|
* @param deperditionPorteService {DeperditionPorteService}
|
|
67
79
|
* @param deperditionPlancherBasService {DeperditionPlancherBasService}
|
|
68
80
|
* @param deperditionPlancherHautService {DeperditionPlancherHautService}
|
|
81
|
+
* @param deperditionBaieVitreeService {DeperditionBaieVitreeService}
|
|
82
|
+
* @param deperditionPontThermiqueService {DeperditionPontThermiqueService}
|
|
69
83
|
* @param deperditionVentilationService {DeperditionVentilationService}
|
|
70
84
|
*/
|
|
71
85
|
constructor(
|
|
@@ -73,12 +87,16 @@ export class DeperditionEnveloppeService {
|
|
|
73
87
|
deperditionPorteService = inject(DeperditionPorteService),
|
|
74
88
|
deperditionPlancherBasService = inject(DeperditionPlancherBasService),
|
|
75
89
|
deperditionPlancherHautService = inject(DeperditionPlancherHautService),
|
|
90
|
+
deperditionBaieVitreeService = inject(DeperditionBaieVitreeService),
|
|
91
|
+
deperditionPontThermiqueService = inject(DeperditionPontThermiqueService),
|
|
76
92
|
deperditionVentilationService = inject(DeperditionVentilationService)
|
|
77
93
|
) {
|
|
78
94
|
this.#deperditionMurService = deperditionMurService;
|
|
79
95
|
this.#deperditionPorteService = deperditionPorteService;
|
|
80
96
|
this.#deperditionPlancherBasService = deperditionPlancherBasService;
|
|
81
97
|
this.#deperditionPlancherHautService = deperditionPlancherHautService;
|
|
98
|
+
this.#deperditionBaieVitreeService = deperditionBaieVitreeService;
|
|
99
|
+
this.#deperditionPontThermiqueService = deperditionPontThermiqueService;
|
|
82
100
|
this.#deperditionVentilationService = deperditionVentilationService;
|
|
83
101
|
this.#surfaceDeperditive = 0;
|
|
84
102
|
this.#surfaceIsolee = 0;
|
|
@@ -135,6 +153,8 @@ export class DeperditionEnveloppeService {
|
|
|
135
153
|
deperdition_mur: 0,
|
|
136
154
|
deperdition_plancher_bas: 0,
|
|
137
155
|
deperdition_plancher_haut: 0,
|
|
156
|
+
deperdition_baie_vitree: 0,
|
|
157
|
+
deperdition_pont_thermique: 0,
|
|
138
158
|
deperdition_porte: 0
|
|
139
159
|
};
|
|
140
160
|
|
|
@@ -211,6 +231,12 @@ export class DeperditionEnveloppeService {
|
|
|
211
231
|
});
|
|
212
232
|
|
|
213
233
|
enveloppe.baie_vitree_collection.baie_vitree?.forEach((bv) => {
|
|
234
|
+
bv.donnee_intermediaire = this.#deperditionBaieVitreeService.execute(ctx, bv);
|
|
235
|
+
deperditions.deperdition_baie_vitree +=
|
|
236
|
+
bv.donnee_intermediaire.b *
|
|
237
|
+
bv.donnee_entree.surface_totale_baie *
|
|
238
|
+
bv.donnee_intermediaire.u_menuiserie;
|
|
239
|
+
|
|
214
240
|
// Surface de baie vitrée déperditive si b != 0
|
|
215
241
|
if (bv.donnee_intermediaire.b > 0) {
|
|
216
242
|
this.#surfaceDeperditive += bv.donnee_entree.surface_totale_baie;
|
|
@@ -223,6 +249,18 @@ export class DeperditionEnveloppeService {
|
|
|
223
249
|
}
|
|
224
250
|
});
|
|
225
251
|
|
|
252
|
+
enveloppe.pont_thermique_collection.pont_thermique?.forEach((pt) => {
|
|
253
|
+
pt.donnee_intermediaire = this.#deperditionPontThermiqueService.execute(
|
|
254
|
+
ctx,
|
|
255
|
+
enveloppe,
|
|
256
|
+
pt.donnee_entree
|
|
257
|
+
);
|
|
258
|
+
deperditions.deperdition_pont_thermique +=
|
|
259
|
+
pt.donnee_entree.l *
|
|
260
|
+
pt.donnee_intermediaire.k *
|
|
261
|
+
(pt.donnee_entree.pourcentage_valeur_pont_thermique || 1);
|
|
262
|
+
});
|
|
263
|
+
|
|
226
264
|
return deperditions;
|
|
227
265
|
}
|
|
228
266
|
|
|
@@ -165,4 +165,32 @@ export class DeperditionMurService extends DeperditionService {
|
|
|
165
165
|
*/
|
|
166
166
|
return Math.min(2.5, Math.round(parseFloat(umur0) * PRECISION) / PRECISION);
|
|
167
167
|
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Retourner le type d'isolation du mur
|
|
171
|
+
* Si isolation inconnue, on considère isolation iti si la période d'isolation (à défaut année de construction) est > 1975
|
|
172
|
+
*
|
|
173
|
+
* @param ctx {Contexte}
|
|
174
|
+
* @param murDE {MurDE}
|
|
175
|
+
* @return {number}
|
|
176
|
+
*/
|
|
177
|
+
typeIsolation(ctx, murDE) {
|
|
178
|
+
const typeIsolation = parseInt(murDE.enum_type_isolation_id);
|
|
179
|
+
|
|
180
|
+
// Type d'isolation inconnu
|
|
181
|
+
if (typeIsolation === 1) {
|
|
182
|
+
const periodeIsolation = murDE.enum_periode_isolation_id || ctx.enumPeriodeConstructionId;
|
|
183
|
+
|
|
184
|
+
// Année isolation / construction > 1974
|
|
185
|
+
if (parseInt(periodeIsolation) >= 3) {
|
|
186
|
+
// Isolation ITI
|
|
187
|
+
return 3;
|
|
188
|
+
} else {
|
|
189
|
+
// Non isolé
|
|
190
|
+
return 2;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return typeIsolation;
|
|
195
|
+
}
|
|
168
196
|
}
|
|
@@ -315,6 +315,67 @@ describe('Calcul de déperdition des murs', () => {
|
|
|
315
315
|
});
|
|
316
316
|
});
|
|
317
317
|
|
|
318
|
+
test.each([
|
|
319
|
+
{
|
|
320
|
+
label: 'mur avec isolation inconnue et période isolation 1975',
|
|
321
|
+
enumTypeIsolationId: 1,
|
|
322
|
+
enumPeriodIsolationId: 3,
|
|
323
|
+
enumPeriodeConstructionId: undefined,
|
|
324
|
+
typeIsolationExpected: 3
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
label: 'mur avec isolation inconnue et période construction 1975',
|
|
328
|
+
enumTypeIsolationId: 1,
|
|
329
|
+
enumPeriodIsolationId: undefined,
|
|
330
|
+
enumPeriodeConstructionId: 6,
|
|
331
|
+
typeIsolationExpected: 3
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
label: 'mur avec isolation inconnue et période isolation 1974',
|
|
335
|
+
enumTypeIsolationId: 1,
|
|
336
|
+
enumPeriodIsolationId: 2,
|
|
337
|
+
enumPeriodeConstructionId: undefined,
|
|
338
|
+
typeIsolationExpected: 2
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
label: 'mur avec isolation inconnue et période construction 1974',
|
|
342
|
+
enumTypeIsolationId: 1,
|
|
343
|
+
enumPeriodIsolationId: undefined,
|
|
344
|
+
enumPeriodeConstructionId: 1,
|
|
345
|
+
typeIsolationExpected: 2
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
label: 'mur avec isolation iti+ite',
|
|
349
|
+
enumTypeIsolationId: 6,
|
|
350
|
+
enumPeriodIsolationId: 1,
|
|
351
|
+
enumPeriodeConstructionId: undefined,
|
|
352
|
+
typeIsolationExpected: 6
|
|
353
|
+
}
|
|
354
|
+
])(
|
|
355
|
+
"Récupération du type d'isolation pour $label",
|
|
356
|
+
({
|
|
357
|
+
enumTypeIsolationId,
|
|
358
|
+
enumPeriodIsolationId = undefined,
|
|
359
|
+
enumPeriodeConstructionId = undefined,
|
|
360
|
+
typeIsolationExpected
|
|
361
|
+
}) => {
|
|
362
|
+
/**
|
|
363
|
+
* @type {MurDE}
|
|
364
|
+
*/
|
|
365
|
+
let murDE = {
|
|
366
|
+
enum_type_isolation_id: enumTypeIsolationId,
|
|
367
|
+
enum_periode_isolation_id: enumPeriodIsolationId
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* @type {Contexte}
|
|
372
|
+
*/
|
|
373
|
+
const ctx = { enumPeriodeConstructionId };
|
|
374
|
+
|
|
375
|
+
expect(service.typeIsolation(ctx, murDE)).toBe(typeIsolationExpected);
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
|
|
318
379
|
describe("Test d'intégration de mur", () => {
|
|
319
380
|
test.each(corpus)('vérification des DI des murs pour dpe %s', (ademeId) => {
|
|
320
381
|
let dpeRequest = getAdemeFileJson(ademeId);
|