@izara_project/izara-shared-search-and-sort 1.0.1 → 1.0.3

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.
@@ -0,0 +1,1038 @@
1
+ /*
2
+ Copyright (C) 2025 Sven Mason <http://izara.io>
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as
6
+ published by the Free Software Foundation, either version 3 of the
7
+ License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ "use strict";
19
+
20
+
21
+ // import { validatorSchema } from "@izara_project/izara-middleware";
22
+ // let { pattern } = validatorSchema.stringNotEmpty();
23
+ // export default [...]
24
+
25
+ import { objectHash as hash } from '@izara_project/izara-shared-core'; //const hash = require('@izara_project/izara-shared-core').objectHash;
26
+ import lodash from 'lodash';
27
+ const { isEmpty } = lodash;
28
+ import filtersSharedLib from './FiltersSharedLib.js'; //const filtersSharedLib = require('./FiltersSharedLib');
29
+
30
+ async function createRequiredData(
31
+ _izContext,
32
+ objType,
33
+ requiredDataFields,
34
+ complexFilterCombinations,
35
+ perParentCombinations,
36
+ requiredDataLinkStepObjects,
37
+ requiredDataLinkSteps,
38
+ values,
39
+ ) {
40
+ _izContext.logger.debug('createRequiredData: ', {
41
+ objType,
42
+ requiredDataFields,
43
+ complexFilterCombinations,
44
+ perParentCombinations,
45
+ requiredDataLinkStepObjects,
46
+ values,
47
+ });
48
+
49
+ let errorsObject = {};
50
+ let errorsFound = [];
51
+
52
+ let requiredDataHash = null;
53
+ let requiredDataObject = {};
54
+ let linkPathObjects = {};
55
+ let linkPathSteps = {};
56
+ let setPerParentCombinations = {};
57
+ let setComplexFilterCombinations = {};
58
+ let setFilterElementsLink = {}
59
+
60
+ _izContext.logger.debug('--------------- start requiredData fields ---------------')
61
+ for (const requiredDataFieldId of requiredDataFields) {
62
+ _izContext.logger.debug('extract requiredDataFields: ', requiredDataFieldId);
63
+
64
+ let requiredDataLinkObject = requiredDataLinkStepObjects[requiredDataFieldId];
65
+ _izContext.logger.debug('requiredDataLinkObject: ', requiredDataLinkObject);
66
+
67
+ let linkSteps = requiredDataLinkObject.linkSteps;
68
+ _izContext.logger.debug('initial data: ', { linkSteps });
69
+
70
+ let [fieldName, returnValue, linkPathErrorObject, linkPathErrorsFound] = await createLinkPath(
71
+ _izContext,
72
+ linkSteps,
73
+ requiredDataLinkStepObjects,
74
+ requiredDataLinkSteps,
75
+ perParentCombinations,
76
+ complexFilterCombinations,
77
+ values,
78
+ errorsObject,
79
+ errorsFound
80
+ );
81
+ _izContext.logger.debug('return createLinkPath: ', {
82
+ fieldName,
83
+ returnValue,
84
+ linkPathErrorObject,
85
+ linkPathErrorsFound
86
+ });
87
+
88
+ if (linkPathErrorsFound.length > 0) {
89
+ Object.assign(errorsObject, linkPathErrorObject);
90
+ errorsFound = errorsFound.concat(linkPathErrorsFound);
91
+ };
92
+
93
+ if (fieldName === null) {
94
+ return {
95
+ requiredDataHash: null,
96
+ requiredDataObject: requiredDataObject,
97
+ linkPathObjects: linkPathObjects,
98
+ linkPathSteps: linkPathSteps,
99
+ complexFilterCombinations: setComplexFilterCombinations,
100
+ perParentCombinations: setPerParentCombinations,
101
+ filterElements: setFilterElementsLink,
102
+ status: 'invalid',
103
+ errorsObject: errorsObject,
104
+ errorsFound: errorsFound
105
+ };
106
+ };
107
+
108
+ if (returnValue.hasOwnProperty('linkSteps')) {
109
+ if (returnValue.hasOwnProperty('linkStepObjects')) {
110
+ Object.assign(linkPathSteps, returnValue.linkStepObjects)
111
+ }
112
+
113
+ if (returnValue.hasOwnProperty('sortFieldLinkPathObjects') && !isEmpty(returnValue.sortFieldLinkPathObjects)) {
114
+ //* maybe will combine in all that top
115
+ Object.assign(linkPathSteps, returnValue.sortFieldLinkPathObjects.linkStepObjects);
116
+ Object.assign(linkPathObjects, returnValue.sortFieldLinkPathObjects.linkPathObjects);
117
+ }
118
+
119
+ let pathObject = {
120
+ initialObjType: objType,
121
+ linkSteps: returnValue.linkSteps
122
+ };
123
+ _izContext.logger.debug('pathObject: ', pathObject);
124
+
125
+ let pathId = hash(pathObject);
126
+ _izContext.logger.debug('pathId: ', pathId);
127
+
128
+ let setObject = {
129
+ fieldName: fieldName,
130
+ linkPathObjectId: pathId
131
+ };
132
+
133
+ Object.assign(linkPathObjects, { [pathId]: pathObject });
134
+
135
+ let requiredFieldNameObject = {
136
+ fieldName: fieldName,
137
+ linkPathObjects: linkPathObjects,
138
+ linkPathSteps: linkPathSteps
139
+ };
140
+
141
+ if (returnValue.hasOwnProperty('complexFilterCombinations')) {
142
+ requiredFieldNameObject.complexFilterCombinations = returnValue.complexFilterCombinations;
143
+ Object.assign(setComplexFilterCombinations, returnValue.complexFilterCombinations);
144
+
145
+ setObject.complexFilterCombinationIds = []
146
+ for (const filterMainId of Object.keys(returnValue.complexFilterCombinations)) {
147
+ if (!setObject.complexFilterCombinationIds.includes(filterMainId)) {
148
+ setObject.complexFilterCombinationIds.push(filterMainId);
149
+ }
150
+ };
151
+ };
152
+
153
+ if (returnValue.hasOwnProperty('perParentCombinations')) {
154
+ requiredFieldNameObject.perParentCombinations = returnValue.perParentCombinations;
155
+ Object.assign(setPerParentCombinations, returnValue.perParentCombinations);
156
+ };
157
+
158
+ if (returnValue.hasOwnProperty('filterElements')) {
159
+ requiredFieldNameObject.filterElements = returnValue.filterElements;
160
+ Object.assign(setFilterElementsLink, returnValue.filterElements);
161
+ };
162
+ _izContext.logger.debug('requiredFieldNameObject: ', requiredFieldNameObject);
163
+
164
+ let requiredDataFieldNameId = hash(requiredFieldNameObject);
165
+ _izContext.logger.debug('requiredDataFieldNameId: ', requiredDataFieldNameId);
166
+
167
+ if (isEmpty(requiredDataObject)) {
168
+ requiredDataObject = {
169
+ [requiredDataFieldNameId]: setObject
170
+ };
171
+
172
+ } else {
173
+ requiredDataObject[requiredDataFieldNameId] = setObject;
174
+ };
175
+
176
+ } else {
177
+ _izContext.logger.debug("------- requiredData has only fieldName ---------");
178
+
179
+ let requiredFieldNameObject = {
180
+ fieldName: fieldName
181
+ };
182
+ _izContext.logger.debug("requiredFieldNameObject: ", requiredFieldNameObject);
183
+
184
+ let requiredDataFieldNameId = hash(requiredFieldNameObject);
185
+ _izContext.logger.debug("requiredDataFieldNameId: ", requiredDataFieldNameId);
186
+
187
+ if (isEmpty(requiredDataObject)) {
188
+
189
+ requiredDataObject = {
190
+ [requiredDataFieldNameId]: requiredFieldNameObject
191
+ };
192
+
193
+ } else {
194
+ requiredDataObject[requiredDataFieldNameId] = requiredFieldNameObject;
195
+ };
196
+ }
197
+ _izContext.logger.debug("before return linkPath: ", { requiredDataObject, linkPathObjects, linkPathSteps });
198
+ }
199
+
200
+ let requiredObject = {};
201
+
202
+ if (!isEmpty(requiredDataObject)) {
203
+ requiredObject.requiredDataObjects = requiredDataObject;
204
+ if (!isEmpty(linkPathObjects)) {
205
+ requiredObject.linkPathObjects = linkPathObjects;
206
+ };
207
+ if (!isEmpty(linkPathSteps)) {
208
+ requiredObject.linkPathSteps = linkPathSteps
209
+ };
210
+ };
211
+
212
+ if (!isEmpty(setComplexFilterCombinations)) {
213
+ requiredObject.complexFilterCombinations = setComplexFilterCombinations;
214
+ };
215
+
216
+ if (!isEmpty(setPerParentCombinations)) {
217
+ requiredObject.perParentCombinations = setPerParentCombinations;
218
+ };
219
+
220
+ if (!isEmpty(setFilterElementsLink)) {
221
+ requiredObject.filterElements = setFilterElementsLink;
222
+ };
223
+ _izContext.logger.debug('requiredObject: ', requiredObject);
224
+
225
+ if (!isEmpty(requiredObject)) {
226
+ requiredDataHash = hash(requiredObject);
227
+ _izContext.logger.debug('requiredDataHash: ', requiredDataHash);
228
+ }
229
+
230
+ let status = 'valid"';
231
+ if (errorsFound.length > 0) {
232
+ status = 'invalid';
233
+ };
234
+
235
+ _izContext.logger.debug('return : ', {
236
+ requiredDataHash: requiredDataHash,
237
+ requiredDataObjects: requiredDataObject,
238
+ linkPathObjects: linkPathObjects,
239
+ linkPathSteps: linkPathSteps,
240
+ complexFilterCombinations: setComplexFilterCombinations,
241
+ perParentCombinations: setPerParentCombinations,
242
+ filterElements: setFilterElementsLink,
243
+ status: status,
244
+ errorsObject: errorsObject,
245
+ errorsFound: errorsFound
246
+ });
247
+
248
+ return {
249
+ requiredDataHash: requiredDataHash,
250
+ requiredDataObjects: requiredDataObject,
251
+ linkPathObjects: linkPathObjects,
252
+ linkPathSteps: linkPathSteps,
253
+ complexFilterCombinations: setComplexFilterCombinations,
254
+ perParentCombinations: setPerParentCombinations,
255
+ filterElements: setFilterElementsLink,
256
+ status: status,
257
+ errorsObject: errorsObject,
258
+ errorsFound: errorsFound
259
+ };
260
+
261
+ }
262
+
263
+
264
+ async function createLinkPath(
265
+ _izContext,
266
+ linkSteps,
267
+ requiredDataLinkStepObjects,
268
+ requiredDataLinkSteps,
269
+ perParentCombinations,
270
+ complexFilterCombinations,
271
+ values,
272
+ errorsObject,
273
+ errorsFound,
274
+ index = 0,
275
+ previousLinkId = null,
276
+ previousLink = null
277
+ ) {
278
+ _izContext.logger.debug('create LinkPath: ', {
279
+ linkSteps,
280
+ requiredDataLinkStepObjects,
281
+ requiredDataLinkSteps,
282
+ perParentCombinations,
283
+ complexFilterCombinations,
284
+ values,
285
+ errorsObject,
286
+ errorsFound,
287
+ index,
288
+ previousLinkId,
289
+ previousLink
290
+ });
291
+ let fieldName = null;
292
+ let returnValue = {}; //* must return only linkPath params
293
+ // let linkPathSteps = [];
294
+ // let linkPathStepObjects = {};
295
+ // let filterElementsLink = {};
296
+ // let perParentCombination = {};
297
+
298
+ // let errorsObject = {}
299
+ // let errorsFound = [];
300
+
301
+ // let childLinkStep = null
302
+ // let childLinkErrorObject = {};
303
+ // let childLinkErrors = []
304
+
305
+ let linkStepId = linkSteps[index];
306
+ _izContext.logger.debug('linkStepId: ', linkStepId);
307
+
308
+ let linkStep = requiredDataLinkSteps[linkStepId];
309
+ _izContext.logger.debug('linkStep: ', linkStep);
310
+
311
+ if (index + 1 === linkSteps.length) {
312
+ // last link that has only fieldName
313
+ _izContext.logger.debug('---------- is final link ----------', { index, linkStep });
314
+
315
+ return [linkStep.fieldName, returnValue, errorsObject, errorsFound]
316
+
317
+ } else {
318
+ // has nextLink
319
+ _izContext.logger.debug('---------- is next link ----------', { index, linkStep });
320
+
321
+ let conditionsPromise = checkConditionsLink(
322
+ // let [conditions, conditionErrObject, conditionErrFound] = await this.checkConditionsLink(
323
+ _izContext,
324
+ linkStep.pathLinkType.objType,
325
+ linkStep,
326
+ perParentCombinations,
327
+ complexFilterCombinations,
328
+ values,
329
+ linkSteps,
330
+ requiredDataLinkStepObjects,
331
+ requiredDataLinkSteps,
332
+ errorsObject,
333
+ errorsFound
334
+ );
335
+
336
+ [fieldName, returnValue, errorsObject, errorsFound] = await createLinkPath(
337
+ _izContext,
338
+ linkSteps,
339
+ requiredDataLinkStepObjects,
340
+ requiredDataLinkSteps,
341
+ perParentCombinations,
342
+ complexFilterCombinations,
343
+ values,
344
+ errorsObject,
345
+ errorsFound,
346
+ index + 1
347
+ )
348
+ _izContext.logger.debug('createLinkPath in link', {
349
+ fieldName,
350
+ returnValue,
351
+ errorsObject,
352
+ errorsFound,
353
+ index
354
+ });
355
+
356
+ _izContext.logger.debug('linkStep', linkStep);
357
+
358
+ let [conditions, conditionErrObject, conditionErrFound] = await conditionsPromise;
359
+
360
+ if (conditionErrFound.length > 0) {
361
+ Object.assign(errorsObject, conditionErrObject);
362
+ errorsFound = errorsFound.concat(conditionErrFound);
363
+ };
364
+
365
+ if (!isEmpty(returnValue)) {
366
+ _izContext.logger.debug('----------------- has returnValue ---------------------', { index, fieldName, returnValue, conditions })
367
+
368
+ let linkStepObject = {
369
+ pathLinkType: linkStep.pathLinkType
370
+ }
371
+
372
+ if (conditions.hasOwnProperty('filterElements')) {
373
+ for (const filterElementId of Object.keys(conditions.filterElements)) {
374
+ linkStepObject.filterElementId = filterElementId;
375
+
376
+ if (returnValue.hasOwnProperty('filterElements')) {
377
+ Object.assign(returnValue['filterElements'], conditions.filterElements);
378
+ } else {
379
+ returnValue.filterElements = conditions.filterElements;
380
+ }
381
+ }
382
+ }
383
+
384
+ if (conditions.hasOwnProperty('requestProperties')) {
385
+ linkStepObject.requestProperties = conditions.requestProperties;
386
+ };
387
+
388
+ if (conditions.hasOwnProperty('aggregate')) {
389
+ if (conditions.hasOwnProperty('sortFields')) {
390
+ linkStepObject.aggregate = conditions.aggregate;
391
+ linkStepObject.sortFields = conditions.sortFields;
392
+ };
393
+ };
394
+
395
+ if (conditions.hasOwnProperty('linkPathObjects')) {
396
+ if (conditions.hasOwnProperty('linkStepObjects')) {
397
+
398
+ linkStepObject.requiredDataFields = conditions.requiredDataFields;
399
+
400
+ if (returnValue.hasOwnProperty("sortFieldLinkPathObjects")) {
401
+ Object.assign(returnValue.sortFieldLinkPathObjects["linkPathObjects"], conditions.linkPathObjects);
402
+ Object.assign(returnValue.sortFieldLinkPathObjects["linkStepObjects"], conditions.linkStepObjects);
403
+ } else {
404
+ returnValue.sortFieldLinkPathObjects = {
405
+ linkPathObjects: conditions.linkPathObjects,
406
+ linkStepObjects: conditions.linkStepObjects
407
+ }
408
+ }
409
+
410
+ if (conditions.hasOwnProperty("setFilterCombinations") && !isEmpty(conditions.setFilterCombinations)) {
411
+
412
+ if (conditions.setFilterCombinations.hasOwnProperty('filterElements')) {
413
+ Object.assign(returnValue["filterElements"], conditions.setFilterCombinations.filterElements.filterElements);
414
+ }
415
+
416
+ if (conditions.setFilterCombinations.hasOwnProperty('perParentCombinations')) {
417
+ Object.assign(returnValue["perParentCombinations"], conditions.setFilterCombinations.perParentCombinations);
418
+ };
419
+
420
+ if (conditions.setFilterCombinations.hasOwnProperty('complexFilterCombinations')) {
421
+ Object.assign(returnValue['complexFilterCombinations'], conditions.setFilterCombinations.complexFilterCombinations);
422
+ };
423
+ }
424
+
425
+ _izContext.logger.debug('returnValue', returnValue);
426
+
427
+ } else {
428
+ //* error
429
+ errorsObject[linkStepId] = `has linkPathObject but no data`;
430
+ errorsFound.push(`${linkStepId} no data in linkPathObject`)
431
+ }
432
+ }
433
+
434
+ if (conditions.hasOwnProperty('combine')) {
435
+ linkStepObject.combine = conditions.combine;
436
+ };
437
+
438
+ if (conditions.hasOwnProperty('perParentCombinationIds')) {
439
+ if (conditions.hasOwnProperty('perParentCombinationObjects')) {
440
+ linkStepObject.perParentCombinationIds = conditions.perParentCombinationIds;
441
+ if (returnValue.hasOwnProperty("perParentCombinations")) {
442
+ Object.assign(returnValue["perParentCombinations"], conditions.perParentCombinationObjects);
443
+ } else {
444
+ returnValue.perParentCombinations = conditions.perParentCombinationObjects;
445
+ }
446
+ };
447
+ };
448
+
449
+ if (conditions.hasOwnProperty('applyCombinations')) {
450
+ if (conditions.hasOwnProperty('complexFilterCombinationObjects')) {
451
+ linkStepObject.applyCombinations = conditions.applyCombinations;
452
+ if (returnValue.hasOwnProperty("complexFilterCombinations")) {
453
+ Object.assign(returnValue["complexFilterCombinations"], conditions.complexFilterCombinationObjects);
454
+ } else {
455
+ returnValue.complexFilterCombinations = conditions.complexFilterCombinationObjects;
456
+ }
457
+ };
458
+ };
459
+
460
+ _izContext.logger.debug('linkStepObject', linkStepObject);
461
+ let linkStepId = hash(linkStepObject);
462
+ _izContext.logger.debug('linkStepId', linkStepId);
463
+
464
+ returnValue['linkSteps'].unshift(linkStepId);
465
+ returnValue['linkStepObjects'] = Object.assign({ [linkStepId]: linkStepObject }, returnValue['linkStepObjects']);
466
+ _izContext.logger.debug('returnValue', returnValue);
467
+
468
+ } else {
469
+ _izContext.logger.debug('----------------- no returnValue ---------------------', { index, fieldName, conditions })
470
+ //returnValue: { linkSteps, linkStepsObjects, perParent, combinations, sortFieldLinkStepObjects }
471
+ //sortFieldLinkStepObjects from in sortField in link
472
+
473
+ let linkStepObject = {
474
+ pathLinkType: linkStep.pathLinkType
475
+ };
476
+
477
+ if (conditions.hasOwnProperty('filterElements')) {
478
+ for (const filterElementId of Object.keys(conditions.filterElements)) {
479
+ linkStepObject.filterElementId = filterElementId;
480
+ returnValue.filterElements = conditions.filterElements;
481
+ };
482
+ };
483
+
484
+ if (conditions.hasOwnProperty('requestProperties')) {
485
+ linkStepObject.requestProperties = conditions.requestProperties;
486
+ };
487
+
488
+ if (conditions.hasOwnProperty('aggregate')) {
489
+ if (conditions.hasOwnProperty('sortFields')) {
490
+ linkStepObject.aggregate = conditions.aggregate;
491
+ linkStepObject.sortFields = conditions.sortFields;
492
+ };
493
+ };
494
+
495
+ if (conditions.hasOwnProperty('linkPathObjects')) {
496
+ if (conditions.hasOwnProperty('linkStepObjects')) {
497
+
498
+ linkStepObject.requiredDataFields = conditions.requiredDataFields;
499
+
500
+ if (returnValue.hasOwnProperty("sortFieldLinkPathObjects")) {
501
+ Object.assign(returnValue.sortFieldLinkPathObjects["linkPathObjects"], conditions.linkPathObjects);
502
+ Object.assign(returnValue.sortFieldLinkPathObjects["linkStepObjects"], conditions.linkStepObjects);
503
+ } else {
504
+ returnValue.sortFieldLinkPathObjects = {
505
+ linkPathObjects: conditions.linkPathObjects,
506
+ linkStepObjects: conditions.linkStepObjects
507
+ }
508
+ }
509
+
510
+ if (returnValue.hasOwnProperty("sortFieldLinkPathObjects")) {
511
+ Object.assign(returnValue.sortFieldLinkPathObjects["linkPathObjects"], conditions.linkPathObjects);
512
+ Object.assign(returnValue.sortFieldLinkPathObjects["linkStepObjects"], conditions.linkStepObjects);
513
+ } else {
514
+ returnValue.sortFieldLinkPathObjects = {
515
+ linkPathObjects: conditions.linkPathObjects,
516
+ linkStepObjects: conditions.linkStepObjects
517
+ }
518
+ }
519
+
520
+ if (conditions.hasOwnProperty("setFilterCombinations") && !isEmpty(conditions.setFilterCombinations)) {
521
+
522
+ if (conditions.setFilterCombinations.hasOwnProperty('filterElements')) {
523
+ Object.assign(returnValue["filterElements"], conditions.setFilterCombinations.filterElements);
524
+ }
525
+
526
+ if (conditions.setFilterCombinations.hasOwnProperty('perParentCombinations')) {
527
+ Object.assign(returnValue["perParentCombinations"], conditions.perParentCombinations);
528
+ };
529
+
530
+ if (conditions.setFilterCombinations.hasOwnProperty('complexFilterCombinations')) {
531
+ Object.assign(returnValue['complexFilterCombinations'], conditions.complexFilterCombinations);
532
+ };
533
+ }
534
+
535
+ } else {
536
+ //* error
537
+ errorsObject[linkStepId] = `has linkPathObject but no data`;
538
+ errorsFound.push(`${linkStepId} no data in linkPathObject`)
539
+ }
540
+ }
541
+
542
+ if (conditions.hasOwnProperty('combine')) {
543
+ linkStepObject.combine = conditions.combine;
544
+ };
545
+
546
+ if (conditions.hasOwnProperty('perParentCombinationIds')) {
547
+ if (conditions.hasOwnProperty('perParentCombinationObjects')) {
548
+ linkStepObject.perParentCombinationIds = conditions.perParentCombinationIds;
549
+ returnValue.perParentCombinations = conditions.perParentCombinationObjects;
550
+ };
551
+ };
552
+
553
+ if (conditions.hasOwnProperty('applyCombinations')) {
554
+ if (conditions.hasOwnProperty('complexFilterCombinationObjects')) {
555
+ linkStepObject.applyCombinations = conditions.applyCombinations;
556
+ returnValue.complexFilterCombinations = conditions.complexFilterCombinationObjects;
557
+ };
558
+ };
559
+
560
+ _izContext.logger.debug('linkStepObject', linkStepObject);
561
+ let linkStepId = hash(linkStepObject);
562
+ _izContext.logger.debug('linkStepId', linkStepId);
563
+
564
+ returnValue.linkSteps = [linkStepId];
565
+ returnValue.linkStepObjects = {
566
+ [linkStepId]: linkStepObject
567
+ };
568
+ _izContext.logger.debug('returnValue', returnValue);
569
+ }
570
+ }
571
+ return [fieldName, returnValue, errorsObject, errorsFound]
572
+ }
573
+
574
+
575
+ async function checkConditionsLink(
576
+ _izContext,
577
+ objType,
578
+ linkStepObject,
579
+ perParentCombinations,
580
+ complexFilterCombinations,
581
+ values,
582
+ linkSteps,
583
+ requiredDataLinkStepObjects,
584
+ requiredDataLinkSteps,
585
+ errorsObject,
586
+ errorsFound
587
+ ) {
588
+ _izContext.logger.debug('checkConditionsLink:', {
589
+ objType,
590
+ linkStepObject,
591
+ perParentCombinations,
592
+ complexFilterCombinations,
593
+ values,
594
+ linkSteps,
595
+ requiredDataLinkStepObjects,
596
+ requiredDataLinkSteps,
597
+ errorsObject,
598
+ errorsFound
599
+ });
600
+
601
+
602
+ let conditionLinkObject = {}
603
+
604
+ if (linkStepObject.hasOwnProperty('filterElements')) {
605
+ _izContext.logger.debug('------------ has filterElements ------------');
606
+
607
+ let [complexFilterRequest, status, filterErrorsObject, filterErrorsFound] = filtersSharedLib.createComplexFilter(
608
+ _izContext,
609
+ linkStepObject.filterElements.objType,
610
+ linkStepObject.filterElements.initialLogicalElementId,
611
+ linkStepObject.filterElements.logicalElements,
612
+ values
613
+ );
614
+ _izContext.logger.debug('return complexFilter for filterElements: ', {
615
+ complexFilterRequest,
616
+ status,
617
+ filterErrorsObject,
618
+ filterErrorsFound
619
+ });
620
+
621
+ if (filterErrorsFound.length > 0) {
622
+ Object.assign(errorsObject, filterErrorsObject)
623
+ errorsFound = errorsFound.concat(filterErrorsFound)
624
+ };
625
+ conditionLinkObject.filterElements = complexFilterRequest.filterElements;
626
+ _izContext.logger.debug('conditionLinkObject in condition link: ', conditionLinkObject);
627
+ }
628
+
629
+ if (linkStepObject.hasOwnProperty('aggregate')) {
630
+ _izContext.logger.debug('------------ has aggregate ------------');
631
+ if (!linkStepObject.hasOwnProperty('sortFields')) {
632
+ errorsFound.push('if has aggregate need to has sortFields, too');
633
+ };
634
+ conditionLinkObject.aggregate = linkStepObject.aggregate;
635
+ conditionLinkObject.sortFields = [];
636
+
637
+ if (linkStepObject.hasOwnProperty('combine')) {
638
+ conditionLinkObject.combine = linkStepObject.combine;
639
+ }
640
+
641
+ let linkPathObjects = {};
642
+ let sortFieldObjects = [];
643
+
644
+ let requiredDataObjects = {}
645
+ let requiredDataFields = [];
646
+ let requiredDataStepObjects = {};
647
+
648
+ let setComplexFilterCombinations = {};
649
+ let setPerParentCombinations = {};
650
+ let setFilterElements = {};
651
+
652
+ _izContext.logger.debug('linkStepObject.sortFields', linkStepObject.sortFields);
653
+
654
+ for (const sortField of linkStepObject.sortFields) {
655
+ _izContext.logger.debug('sortField: ', sortField);
656
+ _izContext.logger.debug('requiredDataLinkSteps: ', requiredDataLinkSteps);
657
+ let requiredDataLinkStepSortField = requiredDataLinkStepObjects[sortField.requiredDataLinkStepObjectId];
658
+ _izContext.logger.debug('requiredDataLinkStepSortField: ', requiredDataLinkStepSortField);
659
+
660
+ _izContext.logger.debug(' requiredDataLinkStepSortField.linkSteps: ', requiredDataLinkStepSortField.linkSteps);
661
+
662
+ //* make all linkPath in here and send out to combine allLinkPath
663
+ let [fieldName, childLinkStep, linkErrorsObject, linkErrorsFound] = await createLinkPath(
664
+ _izContext,
665
+ requiredDataLinkStepSortField.linkSteps,
666
+ requiredDataLinkStepObjects,
667
+ requiredDataLinkSteps,
668
+ perParentCombinations,
669
+ complexFilterCombinations,
670
+ values,
671
+ errorsObject,
672
+ errorsFound
673
+ );
674
+ _izContext.logger.debug(' cratelinkPath in checkCondition for sortField: ', {
675
+ fieldName,
676
+ childLinkStep,
677
+ linkErrorsObject,
678
+ linkErrorsFound
679
+ });
680
+
681
+ if (!isEmpty(childLinkStep)) {
682
+
683
+ //* create linkPathObject from child
684
+ let pathObject = {
685
+ initialObjType: objType,
686
+ linkSteps: childLinkStep.linkSteps
687
+ };
688
+ _izContext.logger.debug('pathObject: ', pathObject);
689
+
690
+ let pathId = hash(pathObject);
691
+ _izContext.logger.debug('pathId: ', pathId);
692
+
693
+ _izContext.logger.debug('linkPathObjects xxxxxx: ', linkPathObjects);
694
+
695
+ Object.assign(linkPathObjects, { [pathId]: pathObject });
696
+
697
+ if (childLinkStep.hasOwnProperty('complexFilterCombinations')) {
698
+ Object.assign(setComplexFilterCombinations, childLinkStep.complexFilterCombinations);
699
+ };
700
+
701
+ if (childLinkStep.hasOwnProperty('perParentCombinations')) {
702
+ Object.assign(setPerParentCombinations, childLinkStep.perParentCombinations);
703
+ };
704
+
705
+ if (childLinkStep.hasOwnProperty('filterElements')) {
706
+ Object.assign(setFilterElements, childLinkStep.filterElements);
707
+ };
708
+
709
+ if (isEmpty(requiredDataObjects)) {
710
+ requiredDataObjects = {
711
+ [pathId]: pathObject
712
+ };
713
+ } else {
714
+ Object.assign(requiredDataObjects, { [pathId]: pathObject })
715
+ };
716
+
717
+ if (isEmpty(requiredDataStepObjects)) {
718
+ requiredDataStepObjects = childLinkStep.linkStepObjects;
719
+ } else {
720
+ Object.assign(requiredDataStepObjects, childLinkStep.linkStepObjects);
721
+ };
722
+
723
+ requiredDataFields.push({
724
+ fieldName: fieldName,
725
+ linkPathObjectId: pathId,
726
+ // dataType: sortField.dataType
727
+ });
728
+
729
+ } else {
730
+ requiredDataFields.push({
731
+ fieldName: fieldName
732
+ });
733
+ };
734
+
735
+ sortFieldObjects.push({
736
+ fieldName: fieldName,
737
+ dataType: sortField.dataType
738
+ });
739
+ _izContext.logger.debug('sortFieldObjects: ', sortFieldObjects);
740
+
741
+ };
742
+
743
+ conditionLinkObject.sortFields = sortFieldObjects;
744
+
745
+ if (!isEmpty(requiredDataStepObjects)) {
746
+ conditionLinkObject.linkPathObjects = requiredDataObjects;
747
+ conditionLinkObject.linkStepObjects = requiredDataStepObjects;
748
+ conditionLinkObject.requiredDataFields = requiredDataFields;
749
+ conditionLinkObject.setFilterCombinations = {};
750
+
751
+ if (!isEmpty(setComplexFilterCombinations)) {
752
+ conditionLinkObject.setFilterCombinations.complexFilterCombinations = setComplexFilterCombinations;
753
+ };
754
+ if (!isEmpty(setPerParentCombinations)) {
755
+ conditionLinkObject.setFilterCombinations.perParentCombinations = setPerParentCombinations;
756
+ };
757
+ if (!isEmpty(setFilterElements)) {
758
+ conditionLinkObject.setFilterCombinations.filterElements = setFilterElements;
759
+ };
760
+ };
761
+
762
+ _izContext.logger.debug('conditionLinkObject: ', conditionLinkObject);
763
+
764
+ } else {
765
+ if (linkStepObject.hasOwnProperty('combine')) {
766
+ errorsFound.push('this link set combine must set aggregate and sortFields, too');
767
+ }
768
+ };
769
+
770
+ if (linkStepObject.hasOwnProperty('requestProperties')) {
771
+ _izContext.logger.debug('------------ link has requestProperties ------------');
772
+
773
+ let perParentCombinationIds = [];
774
+ let perParentCombinationObjects = {}
775
+ let complexFilterCombinationObjects = {};
776
+ let applyCombinations = [];
777
+
778
+ for (const [tag, requestPropertyId] of Object.entries(linkStepObject.requestProperties)) {
779
+ _izContext.logger.debug('extract requestProperties', { tag, requestPropertyId });
780
+ let requestPropertyObject = values[requestPropertyId];
781
+ _izContext.logger.debug('extract requestProperties', requestPropertyObject);
782
+
783
+
784
+ if (requestPropertyObject.hasOwnProperty('valueSource')) {
785
+
786
+ if (requestPropertyObject.valueSource === 'perParentCombination') {
787
+ _izContext.logger.debug('------------- perParentCombinations -------------');
788
+
789
+ let perParentCombinationObject = perParentCombinations[requestPropertyObject.perParentCombinationId];
790
+ _izContext.logger.debug('perParentCombinationObject', perParentCombinationObject);
791
+
792
+ let [complexFilterRequest, status, perParentErrorsObject, perParentErrorsFound] = filtersSharedLib.createComplexFilter(
793
+ _izContext,
794
+ perParentCombinationObject.objType,
795
+ perParentCombinationObject.initialLogicalElementId,
796
+ perParentCombinationObject.logicalElements,
797
+ values,
798
+ );
799
+ _izContext.logger.debug('return complexFilter for perParentCombinations: ', {
800
+ complexFilterRequest,
801
+ status,
802
+ perParentErrorsObject,
803
+ perParentErrorsFound
804
+ });
805
+
806
+ if (perParentErrorsFound.length > 0) {
807
+ errorsObject[requestPropertyObject.perParentCombinationId] = 'perParentCombination has error in complexFilter';
808
+ Object.assign(errorsObject, perParentErrorsObject);
809
+ errorsFound = errorsFound.concat(perParentErrorsFound);
810
+ };
811
+
812
+ perParentCombinationIds.push({
813
+ tag: tag,
814
+ filterMainId: complexFilterRequest.filterMainId,
815
+ });
816
+ Object.assign(perParentCombinationObjects, {
817
+ [complexFilterRequest.filterMainId]: {
818
+ objType: complexFilterRequest.objType,
819
+ filterMainId: complexFilterRequest.filterMainId,
820
+ filterElements: complexFilterRequest.filterElements
821
+ }
822
+ });
823
+ _izContext.logger.debug('set perParentCombinations: ', { perParentCombinationIds, perParentCombinationObjects });
824
+
825
+ } else if (requestPropertyObject.valueSource === 'complexFilterCombination') {
826
+ _izContext.logger.debug('------------- complexFilterCombination will set applyCombinations -------------', complexFilterCombinations);
827
+
828
+ let complexFilterCombinationId = requestPropertyObject.complexFilterCombinationId;
829
+ _izContext.logger.debug('complexFilterCombinationId: ', complexFilterCombinationId);
830
+
831
+ let complexFilterCombinationObject = complexFilterCombinations[complexFilterCombinationId];
832
+ _izContext.logger.debug('complexFilterCombinationObject: ', complexFilterCombinationObject);
833
+
834
+ let [complexFilterRequest, status, complexFilterErrorsObject, complexFilterErrorsFound] = filtersSharedLib.createComplexFilter(
835
+ _izContext,
836
+ complexFilterCombinationObject.objType,
837
+ complexFilterCombinationObject.initialLogicalElementId,
838
+ complexFilterCombinationObject.logicalElements,
839
+ values
840
+ );
841
+ _izContext.logger.debug('return complexFilter for complexFilterCombinations: ', {
842
+ complexFilterRequest,
843
+ status,
844
+ complexFilterErrorsObject,
845
+ complexFilterErrorsFound
846
+ });
847
+
848
+ if (status === 'invalid' || complexFilterErrorsFound.length > 0) {
849
+ errorsObject[complexFilterCombinationId] = 'complexFilterCombination has error in complexFilter';
850
+ Object.assign(errorsObject, complexFilterErrorsObject)
851
+ errorsFound.push('complexFilterCombinations has errorsFound');
852
+ errorsFound = errorsFound.concat(complexFilterErrorsFound);
853
+ break;
854
+ };
855
+
856
+ applyCombinations.push({
857
+ tag: tag,
858
+ filterMainId: complexFilterRequest.filterMainId,
859
+ // identifiersFieldName: requestPropertyObject.identifierFieldName
860
+ });
861
+ _izContext.logger.debug('applyCombinations: ', applyCombinations);
862
+
863
+ Object.assign(complexFilterCombinationObjects, {
864
+ [complexFilterRequest.filterMainId]: {
865
+ objType: complexFilterRequest.objType,
866
+ filterMainId: complexFilterRequest.filterMainId,
867
+ filterElements: complexFilterRequest.filterElements
868
+ }
869
+ });
870
+ // Object.assign(perParentCombinationObjects, complexFilterRequest.filterElements);
871
+ };
872
+
873
+ } else {
874
+
875
+ if (isEmpty(conditionLinkObject)) {
876
+ conditionLinkObject = {
877
+ requestProperties: {
878
+ [tag]: values[requestPropertyId].value
879
+ }
880
+ };
881
+ } else {
882
+ if (conditionLinkObject.hasOwnProperty('requestProperties')) {
883
+ conditionLinkObject.requestProperties[tag] = values[requestPropertyId].value;
884
+ } else {
885
+ conditionLinkObject['requestProperties'] = {
886
+ [tag]: values[requestPropertyId].value
887
+ };
888
+ };
889
+ };
890
+ };
891
+ };
892
+
893
+ _izContext.logger.debug('perParentCombinations: ', {
894
+ perParentCombinationIds,
895
+ perParentCombinationObjects,
896
+ applyCombinations
897
+ });
898
+
899
+ if (!isEmpty(perParentCombinationIds)) {
900
+ conditionLinkObject.perParentCombinationIds = perParentCombinationIds;
901
+ conditionLinkObject.perParentCombinationObjects = perParentCombinationObjects;
902
+ };
903
+
904
+ if (!isEmpty(applyCombinations)) {
905
+ conditionLinkObject.applyCombinations = applyCombinations
906
+ conditionLinkObject.complexFilterCombinationObjects = complexFilterCombinationObjects;
907
+ };
908
+ _izContext.logger.debug('conditionLinkObject: ', conditionLinkObject);
909
+ }
910
+ _izContext.logger.debug('conditionLinkObject', conditionLinkObject);
911
+ return [conditionLinkObject, errorsObject, errorsFound];
912
+ }
913
+
914
+
915
+ function checkConditionsLinkStep(
916
+ _izContext,
917
+ multipleIdentifiers,
918
+ linkConfig,
919
+ combine
920
+ ) {
921
+ // let returnValue = {
922
+ // canAggregateCompare: true | false | required, // toMany=true(optional)|(multipleIds=true&combine=true(required)*if toMany=false require must agg/comp*)
923
+ // canCombine: true | false, // multipleIds=true*if set must set agg/comp*(or only show when aggregate is added)
924
+ // canPerParent: true | false, // current relationship has request properties
925
+ // canFilters: true | false
926
+ // }
927
+ let canAggregateCompare = false;
928
+ let canCombine = false;
929
+ let canPerParent = false;
930
+ let canFilters = false;
931
+
932
+ let toMany = false;
933
+ if (linkConfig.other.linkType === 'many') {
934
+ toMany = true;
935
+ }
936
+
937
+ let requestProperties = false;
938
+ if (linkConfig.hasOwnProperty('requestProperties')) {
939
+ requestProperties = true;
940
+ }
941
+ if (multipleIdentifiers) {
942
+ if (toMany) {
943
+ if (combine) {
944
+ canAggregateCompare = 'required';
945
+ canFilters = true;
946
+ canCombine = true;
947
+ if (requestProperties) {
948
+ canPerParent = true;
949
+ }
950
+ } else {
951
+ canAggregateCompare = true;
952
+ canCombine = true;
953
+ canFilters = true;
954
+ if (requestProperties) {
955
+ canPerParent = true;
956
+ }
957
+ }
958
+ } else {
959
+ canAggregateCompare = true;
960
+ canCombine = true;
961
+ if (requestProperties) {
962
+ canPerParent = true;
963
+ }
964
+ }
965
+ } else {
966
+ if (toMany) {
967
+ canAggregateCompare = true;
968
+ canFilters = true;
969
+
970
+ // if (requestProperties) { //* no case yet.
971
+ // canPerParent = true;
972
+ // canCombine = true;
973
+ // }
974
+ }
975
+ }
976
+ return {
977
+ canAggregateCompare: canAggregateCompare,
978
+ canCombine: canCombine,
979
+ canPerParent: canPerParent,
980
+ canFilters: canFilters,
981
+ requestProperties: requestProperties //use when linkConfig has request but set no set perParent : false, use requestPropertyType: value
982
+ }
983
+ }
984
+
985
+
986
+ function checkMultipleIdentifers(
987
+ _izContext,
988
+ linkConfig = {},
989
+ aggregate = false,
990
+ comparison = false,
991
+ combine = false,
992
+ applyCombinations = false,
993
+ multipleIdentifiers = false,
994
+ ) {
995
+ let manyIdentifiers = null;
996
+ if (!isEmpty(linkConfig)) {
997
+ let toMany = false;
998
+ if (linkConfig.other.linkType === 'many') {
999
+ toMany = true;
1000
+ };
1001
+
1002
+ if (multipleIdentifiers) {
1003
+ if (toMany || !toMany) {
1004
+ if (!combine) {
1005
+ manyIdentifiers = true;
1006
+ } else {
1007
+ if (aggregate) {
1008
+ manyIdentifiers = false;
1009
+ }
1010
+ }
1011
+ }
1012
+ } else {
1013
+ if (toMany) {
1014
+ if (aggregate) {
1015
+ manyIdentifiers = false;
1016
+ } else {
1017
+ manyIdentifiers = true;
1018
+ }
1019
+ } else {
1020
+ if (!aggregate && !combine && !applyCombinations && !comparison) {
1021
+ manyIdentifiers = false;
1022
+ }
1023
+ }
1024
+ }
1025
+ }
1026
+ return manyIdentifiers
1027
+ }
1028
+
1029
+ export default {
1030
+ //* create reqioredData normalize structure to backend
1031
+ createRequiredData,
1032
+ createLinkPath,
1033
+ checkConditionsLink,
1034
+
1035
+ //* check settings of linkStep
1036
+ checkConditionsLinkStep,
1037
+ checkMultipleIdentifers
1038
+ }