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

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