@acorex/connectivity 21.0.0-next.3 → 21.0.0-next.33
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/fesm2022/{acorex-connectivity-api-execute.command-SGNBLcOi.mjs → acorex-connectivity-api-execute.command-CiBl7z_H.mjs} +6 -6
- package/fesm2022/acorex-connectivity-api-execute.command-CiBl7z_H.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-api.mjs +101 -185
- package/fesm2022/acorex-connectivity-api.mjs.map +1 -1
- package/fesm2022/acorex-connectivity-mock-acorex-connectivity-mock-BpUUTZOi.mjs +65873 -0
- package/fesm2022/acorex-connectivity-mock-acorex-connectivity-mock-BpUUTZOi.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-assign-to-manager.activity-DTPM1eU1.mjs +79 -0
- package/fesm2022/acorex-connectivity-mock-assign-to-manager.activity-DTPM1eU1.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-category-metadata-inheritance.query-CWRL1dTa.mjs +198 -0
- package/fesm2022/acorex-connectivity-mock-category-metadata-inheritance.query-CWRL1dTa.mjs.map +1 -0
- package/fesm2022/{acorex-connectivity-mock-category-with-items.query-Dsxj98tX.mjs → acorex-connectivity-mock-category-with-items.query-Cj6FWu7S.mjs} +4 -4
- package/fesm2022/acorex-connectivity-mock-category-with-items.query-Cj6FWu7S.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-chat-generate-image.command-BA0r4IMn.mjs +114 -0
- package/fesm2022/acorex-connectivity-mock-chat-generate-image.command-BA0r4IMn.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-chat-synthesize-speech.command-B5-8a7SC.mjs +130 -0
- package/fesm2022/acorex-connectivity-mock-chat-synthesize-speech.command-B5-8a7SC.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-chat-transcribe-speech.command-BGzXvTnh.mjs +110 -0
- package/fesm2022/acorex-connectivity-mock-chat-transcribe-speech.command-BGzXvTnh.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-check-permission.activity-vr3OHtjC.mjs +45 -0
- package/fesm2022/acorex-connectivity-mock-check-permission.activity-vr3OHtjC.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-complete-signature-process.activity-BO-IFsHT.mjs +56 -0
- package/fesm2022/acorex-connectivity-mock-complete-signature-process.activity-BO-IFsHT.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-contact-core.module-5TLCGWOR.mjs +968 -0
- package/fesm2022/acorex-connectivity-mock-contact-core.module-5TLCGWOR.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-content-management.module-GQdqKsPB.mjs +16 -0
- package/fesm2022/acorex-connectivity-mock-content-management.module-GQdqKsPB.mjs.map +1 -0
- package/fesm2022/{acorex-connectivity-mock-distribution-record.command-DRiDwlqN.mjs → acorex-connectivity-mock-distribution-record.activity-DuNluOzA.mjs} +18 -6
- package/fesm2022/acorex-connectivity-mock-distribution-record.activity-DuNluOzA.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-entity-create.activity-Ca19tIj4.mjs +60 -0
- package/fesm2022/acorex-connectivity-mock-entity-create.activity-Ca19tIj4.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-entity-delete.activity-ErEN1c24.mjs +60 -0
- package/fesm2022/acorex-connectivity-mock-entity-delete.activity-ErEN1c24.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-entity-read.activity-1fJW8gVe.mjs +67 -0
- package/fesm2022/acorex-connectivity-mock-entity-read.activity-1fJW8gVe.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-entity-update.activity-D0hyBha-.mjs +70 -0
- package/fesm2022/acorex-connectivity-mock-entity-update.activity-D0hyBha-.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-extract-document-text.command-nGfUTSf6.mjs +64 -0
- package/fesm2022/acorex-connectivity-mock-extract-document-text.command-nGfUTSf6.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-application-versions-chart-data.query-DwVuYuKx.mjs +115 -0
- package/fesm2022/acorex-connectivity-mock-get-application-versions-chart-data.query-DwVuYuKx.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-application-versions-timeline.query-sFKYynZA.mjs +163 -0
- package/fesm2022/acorex-connectivity-mock-get-application-versions-timeline.query-sFKYynZA.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-current-session-user.activity-C6S4ZJgp.mjs +35 -0
- package/fesm2022/acorex-connectivity-mock-get-current-session-user.activity-C6S4ZJgp.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-current-user-manager.activity-C1mj2bgB.mjs +69 -0
- package/fesm2022/acorex-connectivity-mock-get-current-user-manager.activity-C1mj2bgB.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-employee-list.query-DifHwuqH.mjs +213 -0
- package/fesm2022/acorex-connectivity-mock-get-employee-list.query-DifHwuqH.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-location-list.query-bMjkZnzq.mjs +209 -0
- package/fesm2022/acorex-connectivity-mock-get-location-list.query-bMjkZnzq.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-product-chart-data.query-D7DBzLT-.mjs +186 -0
- package/fesm2022/acorex-connectivity-mock-get-product-chart-data.query-D7DBzLT-.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-product-list.query-B06aC73T.mjs +251 -0
- package/fesm2022/acorex-connectivity-mock-get-product-list.query-B06aC73T.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-product-pdf-data.query-CM7bsjl7.mjs +192 -0
- package/fesm2022/acorex-connectivity-mock-get-product-pdf-data.query-CM7bsjl7.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-subscriptions-chart-data.query-BQT5a_hn.mjs +56 -0
- package/fesm2022/acorex-connectivity-mock-get-subscriptions-chart-data.query-BQT5a_hn.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-subscriptions-timeline.query-D4qfDfeV.mjs +246 -0
- package/fesm2022/acorex-connectivity-mock-get-subscriptions-timeline.query-D4qfDfeV.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-application-access.query-n1_Azada.mjs +258 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-application-access.query-n1_Azada.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-registration-chart-data.query-Cg4ykZU2.mjs +56 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-registration-chart-data.query-Cg4ykZU2.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-registration-timeline.query-0sCBtdbp.mjs +294 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-registration-timeline.query-0sCBtdbp.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-user-distribution.query-rD811gtM.mjs +212 -0
- package/fesm2022/acorex-connectivity-mock-get-tenant-user-distribution.query-rD811gtM.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-if.activity-DvzuhItL.mjs +35 -0
- package/fesm2022/acorex-connectivity-mock-if.activity-DvzuhItL.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-notify-signers.activity-Dg0sKGip.mjs +49 -0
- package/fesm2022/acorex-connectivity-mock-notify-signers.activity-Dg0sKGip.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-request-signature.activity-CoRT_H2u.mjs +60 -0
- package/fesm2022/acorex-connectivity-mock-request-signature.activity-CoRT_H2u.mjs.map +1 -0
- package/fesm2022/{acorex-connectivity-mock-sample.command-CkH5bmEs.mjs → acorex-connectivity-mock-sample.command-CJmDL4pL.mjs} +4 -4
- package/fesm2022/acorex-connectivity-mock-sample.command-CJmDL4pL.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-structured-text-completion.command-l31pjl9-.mjs +38 -0
- package/fesm2022/acorex-connectivity-mock-structured-text-completion.command-l31pjl9-.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock-validate-all-signatures.activity-JuHjNFFS.mjs +61 -0
- package/fesm2022/acorex-connectivity-mock-validate-all-signatures.activity-JuHjNFFS.mjs.map +1 -0
- package/fesm2022/acorex-connectivity-mock.mjs +1 -51504
- package/fesm2022/acorex-connectivity-mock.mjs.map +1 -1
- package/fesm2022/acorex-connectivity-utils.mjs +7 -7
- package/fesm2022/acorex-connectivity-utils.mjs.map +1 -1
- package/fesm2022/acorex-connectivity.mjs.map +1 -1
- package/package.json +8 -7
- package/{api/index.d.ts → types/acorex-connectivity-api.d.ts} +1 -59
- package/types/acorex-connectivity-mock.d.ts +3951 -0
- package/fesm2022/acorex-connectivity-api-execute.command-SGNBLcOi.mjs.map +0 -1
- package/fesm2022/acorex-connectivity-mock-category-with-items.query-Dsxj98tX.mjs.map +0 -1
- package/fesm2022/acorex-connectivity-mock-distribution-record.command-DRiDwlqN.mjs.map +0 -1
- package/fesm2022/acorex-connectivity-mock-sample.command-CkH5bmEs.mjs.map +0 -1
- package/mock/index.d.ts +0 -2775
- /package/{utils/index.d.ts → types/acorex-connectivity-utils.d.ts} +0 -0
- /package/{index.d.ts → types/acorex-connectivity.d.ts} +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, Injectable } from '@angular/core';
|
|
3
|
+
import { AXPEntityService } from '@acorex/platform/layout/entity';
|
|
4
|
+
import { RootConfig } from '@acorex/modules/location-management';
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
class GetLocationListQuery {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.entityService = inject(AXPEntityService);
|
|
10
|
+
this.locationService = this.entityService
|
|
11
|
+
.withEntity(`${RootConfig.module.name}.${RootConfig.entities.location.name}`)
|
|
12
|
+
.data();
|
|
13
|
+
}
|
|
14
|
+
async fetch(input) {
|
|
15
|
+
// Extract location-specific filters from AXPFilterClause format
|
|
16
|
+
const extractedFilters = this.extractLocationFilters(input.filters);
|
|
17
|
+
// Separate custom filters from entity filters
|
|
18
|
+
const entityFilters = [];
|
|
19
|
+
if (extractedFilters && extractedFilters.length > 0) {
|
|
20
|
+
for (const filter of extractedFilters) {
|
|
21
|
+
entityFilters.push(filter);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Get all locations from storage with entity filters
|
|
25
|
+
const allLocationsResult = await this.locationService.query({
|
|
26
|
+
skip: 0,
|
|
27
|
+
take: 10000, // Get all locations for aggregation
|
|
28
|
+
filter: entityFilters.length > 0
|
|
29
|
+
? {
|
|
30
|
+
logic: input.logic || 'and',
|
|
31
|
+
filters: entityFilters,
|
|
32
|
+
}
|
|
33
|
+
: undefined,
|
|
34
|
+
});
|
|
35
|
+
const allLocations = allLocationsResult.items;
|
|
36
|
+
// Group locations by country, province, and city
|
|
37
|
+
const locationGroups = new Map();
|
|
38
|
+
for (const location of allLocations) {
|
|
39
|
+
// Get geographic information
|
|
40
|
+
const countryId = location.countryId || 'unknown';
|
|
41
|
+
const countryTitle = location.country?.title || 'Unknown Country';
|
|
42
|
+
const provinceId = location.stateId || 'unknown';
|
|
43
|
+
const provinceTitle = location.state?.title || 'Unknown Province';
|
|
44
|
+
const cityId = location.cityId || 'unknown';
|
|
45
|
+
const cityTitle = location.city?.title || 'Unknown City';
|
|
46
|
+
// Create nested map structure: country -> province -> city -> locations[]
|
|
47
|
+
if (!locationGroups.has(countryId)) {
|
|
48
|
+
locationGroups.set(countryId, new Map());
|
|
49
|
+
}
|
|
50
|
+
const provinceMap = locationGroups.get(countryId);
|
|
51
|
+
if (!provinceMap.has(provinceId)) {
|
|
52
|
+
provinceMap.set(provinceId, new Map());
|
|
53
|
+
}
|
|
54
|
+
const cityMap = provinceMap.get(provinceId);
|
|
55
|
+
if (!cityMap.has(cityId)) {
|
|
56
|
+
cityMap.set(cityId, []);
|
|
57
|
+
}
|
|
58
|
+
cityMap.get(cityId).push(location);
|
|
59
|
+
}
|
|
60
|
+
// Aggregate data by country, province, and city
|
|
61
|
+
const aggregatedResults = [];
|
|
62
|
+
for (const [countryId, provinceMap] of locationGroups.entries()) {
|
|
63
|
+
const firstLocation = Array.from(provinceMap.values())[0]?.values().next().value?.[0];
|
|
64
|
+
const countryTitle = firstLocation?.country?.title || 'Unknown Country';
|
|
65
|
+
for (const [provinceId, cityMap] of provinceMap.entries()) {
|
|
66
|
+
const firstLocationInProvince = cityMap.values().next().value?.[0];
|
|
67
|
+
const provinceTitle = firstLocationInProvince?.state?.title || 'Unknown Province';
|
|
68
|
+
for (const [cityId, locations] of cityMap.entries()) {
|
|
69
|
+
const cityTitle = locations[0]?.city?.title || 'Unknown City';
|
|
70
|
+
aggregatedResults.push({
|
|
71
|
+
countryId,
|
|
72
|
+
countryTitle,
|
|
73
|
+
provinceId,
|
|
74
|
+
provinceTitle,
|
|
75
|
+
cityId,
|
|
76
|
+
cityTitle,
|
|
77
|
+
locationCount: locations.length,
|
|
78
|
+
totalLocations: locations.length,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Apply sorting if provided
|
|
84
|
+
if (input.sort && input.sort.length > 0) {
|
|
85
|
+
aggregatedResults.sort((a, b) => {
|
|
86
|
+
for (const sortField of input.sort) {
|
|
87
|
+
const field = sortField.field;
|
|
88
|
+
const aValue = a[field];
|
|
89
|
+
const bValue = b[field];
|
|
90
|
+
const dir = sortField.dir === 'asc' ? 1 : -1;
|
|
91
|
+
// Handle undefined values
|
|
92
|
+
if (aValue === undefined && bValue === undefined)
|
|
93
|
+
continue;
|
|
94
|
+
if (aValue === undefined)
|
|
95
|
+
return 1 * dir;
|
|
96
|
+
if (bValue === undefined)
|
|
97
|
+
return -1 * dir;
|
|
98
|
+
if (aValue < bValue)
|
|
99
|
+
return -1 * dir;
|
|
100
|
+
if (aValue > bValue)
|
|
101
|
+
return 1 * dir;
|
|
102
|
+
}
|
|
103
|
+
return 0;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// Apply pagination
|
|
107
|
+
const skip = input.skip || 0;
|
|
108
|
+
const take = input.take || 10;
|
|
109
|
+
const total = aggregatedResults.length;
|
|
110
|
+
const items = aggregatedResults.slice(skip, skip + take);
|
|
111
|
+
return {
|
|
112
|
+
items,
|
|
113
|
+
total,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//#region ---- Filter Extraction ----
|
|
117
|
+
/**
|
|
118
|
+
* Extract location-specific filters from AXPFilterClause format
|
|
119
|
+
* Maps report parameter paths to location entity field names
|
|
120
|
+
*/
|
|
121
|
+
extractLocationFilters(parameters) {
|
|
122
|
+
const filters = [];
|
|
123
|
+
const paramsAny = parameters;
|
|
124
|
+
if (!paramsAny?.filters || !Array.isArray(paramsAny.filters)) {
|
|
125
|
+
console.log('⚠️ [extractLocationFilters] No filters array found or not an array');
|
|
126
|
+
return filters;
|
|
127
|
+
}
|
|
128
|
+
for (const filter of paramsAny.filters) {
|
|
129
|
+
if (!filter?.field || filter?.value === undefined || filter?.value === null) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const field = filter.field;
|
|
133
|
+
const value = filter.value;
|
|
134
|
+
const operator = filter.operator || { type: 'equal' };
|
|
135
|
+
// Handle location-specific field mappings
|
|
136
|
+
if (field === 'country') {
|
|
137
|
+
// Country filter
|
|
138
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
139
|
+
filters.push({
|
|
140
|
+
field: 'countryId',
|
|
141
|
+
operator: { type: 'in' },
|
|
142
|
+
value: value,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else if (value) {
|
|
146
|
+
filters.push({
|
|
147
|
+
field: 'countryId',
|
|
148
|
+
operator: { type: 'equal' },
|
|
149
|
+
value: value,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else if (field === 'province') {
|
|
154
|
+
// Province/State filter
|
|
155
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
156
|
+
filters.push({
|
|
157
|
+
field: 'stateId',
|
|
158
|
+
operator: { type: 'in' },
|
|
159
|
+
value: value,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
else if (value) {
|
|
163
|
+
filters.push({
|
|
164
|
+
field: 'stateId',
|
|
165
|
+
operator: { type: 'equal' },
|
|
166
|
+
value: value,
|
|
167
|
+
});
|
|
168
|
+
console.log('✅ [extractLocationFilters] Added province filter (equal):', value);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (field === 'city') {
|
|
172
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
173
|
+
filters.push({
|
|
174
|
+
field: 'cityId',
|
|
175
|
+
operator: { type: 'in' },
|
|
176
|
+
value: value,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else if (value) {
|
|
180
|
+
filters.push({
|
|
181
|
+
field: 'cityId',
|
|
182
|
+
operator: { type: 'equal' },
|
|
183
|
+
value: value,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
// Direct field mapping
|
|
189
|
+
filters.push({
|
|
190
|
+
field: field,
|
|
191
|
+
operator: operator,
|
|
192
|
+
value: value,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return filters;
|
|
197
|
+
}
|
|
198
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetLocationListQuery, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
199
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetLocationListQuery, providedIn: 'root' }); }
|
|
200
|
+
}
|
|
201
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetLocationListQuery, decorators: [{
|
|
202
|
+
type: Injectable,
|
|
203
|
+
args: [{
|
|
204
|
+
providedIn: 'root',
|
|
205
|
+
}]
|
|
206
|
+
}] });
|
|
207
|
+
|
|
208
|
+
export { GetLocationListQuery };
|
|
209
|
+
//# sourceMappingURL=acorex-connectivity-mock-get-location-list.query-bMjkZnzq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-connectivity-mock-get-location-list.query-bMjkZnzq.mjs","sources":["../../../../libs/connectivity/mock/src/lib/report-management/samples/get-location-list.query.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { AXPQuery } from '@acorex/platform/runtime';\nimport { AXPEntityService } from '@acorex/platform/layout/entity';\nimport { AXMLocationManagementLocationEntityModel } from '@acorex/modules/location-management';\nimport { RootConfig as LocationRootConfig } from '@acorex/modules/location-management';\n\n//#region ---- Query Input/Output Types ----\n\nexport interface GetLocationListQueryInput {\n skip?: number;\n take?: number;\n sort?: Array<{ field: string; dir: 'asc' | 'desc' }>;\n filters?: Array<{\n field: string;\n operator: { type: string };\n value: any;\n }>;\n logic?: 'and' | 'or';\n}\n\nexport interface LocationByCityResult {\n countryId?: string;\n countryTitle?: string;\n provinceId?: string;\n provinceTitle?: string;\n cityId?: string;\n cityTitle?: string;\n locationCount: number;\n totalLocations: number;\n}\n\nexport interface GetLocationListQueryResult {\n items: LocationByCityResult[];\n total: number;\n}\n\n//#endregion\n\n@Injectable({\n providedIn: 'root',\n})\nexport class GetLocationListQuery implements AXPQuery<GetLocationListQueryInput, GetLocationListQueryResult> {\n private readonly entityService = inject(AXPEntityService);\n private locationService = this.entityService\n .withEntity(`${LocationRootConfig.module.name}.${LocationRootConfig.entities.location.name}`)\n .data<string, AXMLocationManagementLocationEntityModel>();\n\n async fetch(input: GetLocationListQueryInput | any): Promise<GetLocationListQueryResult> {\n // Extract location-specific filters from AXPFilterClause format\n const extractedFilters = this.extractLocationFilters(input.filters);\n // Separate custom filters from entity filters\n const entityFilters: GetLocationListQueryInput['filters'] = [];\n\n if (extractedFilters && extractedFilters.length > 0) {\n for (const filter of extractedFilters) {\n entityFilters.push(filter);\n }\n }\n // Get all locations from storage with entity filters\n const allLocationsResult = await this.locationService.query({\n skip: 0,\n take: 10000, // Get all locations for aggregation\n filter:\n entityFilters.length > 0\n ? ({\n logic: input.logic || 'and',\n filters: entityFilters,\n } as any)\n : undefined,\n });\n\n const allLocations = allLocationsResult.items;\n\n // Group locations by country, province, and city\n const locationGroups = new Map<string, Map<string, Map<string, AXMLocationManagementLocationEntityModel[]>>>();\n\n for (const location of allLocations) {\n // Get geographic information\n const countryId = (location as any).countryId || 'unknown';\n const countryTitle = (location as any).country?.title || 'Unknown Country';\n\n const provinceId = (location as any).stateId || 'unknown';\n const provinceTitle = (location as any).state?.title || 'Unknown Province';\n\n const cityId = (location as any).cityId || 'unknown';\n const cityTitle = (location as any).city?.title || 'Unknown City';\n\n // Create nested map structure: country -> province -> city -> locations[]\n if (!locationGroups.has(countryId)) {\n locationGroups.set(countryId, new Map());\n }\n\n const provinceMap = locationGroups.get(countryId)!;\n if (!provinceMap.has(provinceId)) {\n provinceMap.set(provinceId, new Map());\n }\n\n const cityMap = provinceMap.get(provinceId)!;\n if (!cityMap.has(cityId)) {\n cityMap.set(cityId, []);\n }\n\n cityMap.get(cityId)!.push(location);\n }\n\n // Aggregate data by country, province, and city\n const aggregatedResults: LocationByCityResult[] = [];\n\n for (const [countryId, provinceMap] of locationGroups.entries()) {\n const firstLocation = Array.from(provinceMap.values())[0]?.values().next().value?.[0];\n const countryTitle = (firstLocation as any)?.country?.title || 'Unknown Country';\n\n for (const [provinceId, cityMap] of provinceMap.entries()) {\n const firstLocationInProvince = cityMap.values().next().value?.[0];\n const provinceTitle = (firstLocationInProvince as any)?.state?.title || 'Unknown Province';\n\n for (const [cityId, locations] of cityMap.entries()) {\n const cityTitle = (locations[0] as any)?.city?.title || 'Unknown City';\n\n aggregatedResults.push({\n countryId,\n countryTitle,\n provinceId,\n provinceTitle,\n cityId,\n cityTitle,\n locationCount: locations.length,\n totalLocations: locations.length,\n });\n }\n }\n }\n\n // Apply sorting if provided\n if (input.sort && input.sort.length > 0) {\n aggregatedResults.sort((a, b) => {\n for (const sortField of input.sort!) {\n const field = sortField.field as keyof LocationByCityResult;\n const aValue = a[field];\n const bValue = b[field];\n const dir = sortField.dir === 'asc' ? 1 : -1;\n\n // Handle undefined values\n if (aValue === undefined && bValue === undefined) continue;\n if (aValue === undefined) return 1 * dir;\n if (bValue === undefined) return -1 * dir;\n\n if (aValue < bValue) return -1 * dir;\n if (aValue > bValue) return 1 * dir;\n }\n return 0;\n });\n }\n\n // Apply pagination\n const skip = input.skip || 0;\n const take = input.take || 10;\n const total = aggregatedResults.length;\n const items = aggregatedResults.slice(skip, skip + take);\n\n return {\n items,\n total,\n };\n }\n\n //#region ---- Filter Extraction ----\n\n /**\n * Extract location-specific filters from AXPFilterClause format\n * Maps report parameter paths to location entity field names\n */\n private extractLocationFilters(parameters: any): GetLocationListQueryInput['filters'] {\n const filters: GetLocationListQueryInput['filters'] = [];\n const paramsAny = parameters as any;\n\n if (!paramsAny?.filters || !Array.isArray(paramsAny.filters)) {\n console.log('⚠️ [extractLocationFilters] No filters array found or not an array');\n return filters;\n }\n\n\n for (const filter of paramsAny.filters) {\n if (!filter?.field || filter?.value === undefined || filter?.value === null) {\n continue;\n }\n\n const field = filter.field;\n const value = filter.value;\n const operator = filter.operator || { type: 'equal' };\n\n // Handle location-specific field mappings\n if (field === 'country') {\n // Country filter\n if (Array.isArray(value) && value.length > 0) {\n filters.push({\n field: 'countryId',\n operator: { type: 'in' },\n value: value,\n });\n } else if (value) {\n filters.push({\n field: 'countryId',\n operator: { type: 'equal' },\n value: value,\n });\n }\n } else if (field === 'province') {\n // Province/State filter\n if (Array.isArray(value) && value.length > 0) {\n filters.push({\n field: 'stateId',\n operator: { type: 'in' },\n value: value,\n });\n } else if (value) {\n filters.push({\n field: 'stateId',\n operator: { type: 'equal' },\n value: value,\n });\n console.log('✅ [extractLocationFilters] Added province filter (equal):', value);\n }\n } else if (field === 'city') {\n if (Array.isArray(value) && value.length > 0) {\n filters.push({\n field: 'cityId',\n operator: { type: 'in' },\n value: value,\n });\n } else if (value) {\n filters.push({\n field: 'cityId',\n operator: { type: 'equal' },\n value: value,\n });\n }\n } else {\n // Direct field mapping\n filters.push({\n field: field,\n operator: operator,\n value: value,\n });\n }\n }\n\n return filters;\n }\n\n //#endregion\n}\n"],"names":["LocationRootConfig"],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, Injectable } from '@angular/core';
|
|
3
|
+
import { AXPEntityService } from '@acorex/platform/layout/entity';
|
|
4
|
+
import { RootConfig } from '@acorex/modules/product-catalog';
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
class GetProductChartDataQuery {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.entityService = inject(AXPEntityService);
|
|
10
|
+
this.productService = this.entityService.withEntity(`${RootConfig.module.name}.${RootConfig.entities.product.name}`).data();
|
|
11
|
+
}
|
|
12
|
+
async fetch(input) {
|
|
13
|
+
// Extract product-specific filters from AXPFilterClause format
|
|
14
|
+
const extractedFilters = this.extractProductFilters(input.filters);
|
|
15
|
+
// Separate custom filters from entity filters
|
|
16
|
+
const entityFilters = [];
|
|
17
|
+
let priceRangeFilter;
|
|
18
|
+
if (extractedFilters && extractedFilters.length > 0) {
|
|
19
|
+
for (const filter of extractedFilters) {
|
|
20
|
+
if (filter.field === 'priceRange') {
|
|
21
|
+
priceRangeFilter = filter.value;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
entityFilters.push(filter);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Get all products from storage with entity filters (no pagination for charts)
|
|
29
|
+
const allProductsResult = await this.productService.query({
|
|
30
|
+
skip: 0,
|
|
31
|
+
take: 10000, // Get all products for aggregation
|
|
32
|
+
filter: entityFilters.length > 0
|
|
33
|
+
? {
|
|
34
|
+
logic: input.logic || 'and',
|
|
35
|
+
filters: entityFilters,
|
|
36
|
+
}
|
|
37
|
+
: undefined,
|
|
38
|
+
});
|
|
39
|
+
let allProducts = allProductsResult.items;
|
|
40
|
+
// Apply custom price range filter after fetching
|
|
41
|
+
if (priceRangeFilter && priceRangeFilter !== 'all') {
|
|
42
|
+
allProducts = this.applyPriceRangeFilter(allProducts, priceRangeFilter);
|
|
43
|
+
}
|
|
44
|
+
// Group products by brand
|
|
45
|
+
const brandGroups = new Map();
|
|
46
|
+
for (const product of allProducts) {
|
|
47
|
+
const brandKey = product.brand?.title || product.brandId || 'Unknown';
|
|
48
|
+
if (!brandGroups.has(brandKey)) {
|
|
49
|
+
brandGroups.set(brandKey, []);
|
|
50
|
+
}
|
|
51
|
+
brandGroups.get(brandKey).push(product);
|
|
52
|
+
}
|
|
53
|
+
// Aggregate data by brand for chart
|
|
54
|
+
const chartResults = [];
|
|
55
|
+
for (const [brandName, products] of brandGroups.entries()) {
|
|
56
|
+
chartResults.push({
|
|
57
|
+
brand: brandName,
|
|
58
|
+
productCount: products.length,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
items: chartResults,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//#region ---- Filter Extraction ----
|
|
66
|
+
/**
|
|
67
|
+
* Extract product-specific filters from AXPFilterClause format
|
|
68
|
+
* Maps report parameter paths to product entity field names
|
|
69
|
+
*/
|
|
70
|
+
extractProductFilters(parameters) {
|
|
71
|
+
const filters = [];
|
|
72
|
+
const paramsAny = parameters;
|
|
73
|
+
if (!paramsAny?.filters || !Array.isArray(paramsAny.filters)) {
|
|
74
|
+
return filters;
|
|
75
|
+
}
|
|
76
|
+
for (const filter of paramsAny.filters) {
|
|
77
|
+
if (!filter?.field || filter?.value === undefined || filter?.value === null) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const field = filter.field;
|
|
81
|
+
const value = filter.value;
|
|
82
|
+
const operator = filter.operator || { type: 'equal' };
|
|
83
|
+
// Handle product-specific field mappings
|
|
84
|
+
if (field === 'brand') {
|
|
85
|
+
// Brand filter - can be array of IDs or single ID
|
|
86
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
87
|
+
filters.push({
|
|
88
|
+
field: 'brandId',
|
|
89
|
+
operator: { type: 'in' },
|
|
90
|
+
value: value,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else if (value) {
|
|
94
|
+
filters.push({
|
|
95
|
+
field: 'brandId',
|
|
96
|
+
operator: { type: 'equal' },
|
|
97
|
+
value: value,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (field === 'category') {
|
|
102
|
+
// Category filter - can be array of IDs or single ID
|
|
103
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
104
|
+
filters.push({
|
|
105
|
+
field: 'categoryIds',
|
|
106
|
+
operator: { type: 'contains' },
|
|
107
|
+
value: value[0], // Use first category for contains check
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else if (value) {
|
|
111
|
+
filters.push({
|
|
112
|
+
field: 'categoryIds',
|
|
113
|
+
operator: { type: 'contains' },
|
|
114
|
+
value: value,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (field === 'status') {
|
|
119
|
+
// Status filter - skip 'all' value
|
|
120
|
+
if (value && value !== 'all') {
|
|
121
|
+
filters.push({
|
|
122
|
+
field: 'statusId',
|
|
123
|
+
operator: { type: 'equal' },
|
|
124
|
+
value: value,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (field === 'priceRange') {
|
|
129
|
+
// Price range filter - custom logic handled in query
|
|
130
|
+
filters.push({
|
|
131
|
+
field: 'priceRange',
|
|
132
|
+
operator: { type: 'equal' },
|
|
133
|
+
value: value,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else if (field === 'startDate' || field === 'endDate') {
|
|
137
|
+
// Date filters - can be handled if needed
|
|
138
|
+
// For now, skip as they might not be directly on product entity
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// Direct field mapping
|
|
142
|
+
filters.push({
|
|
143
|
+
field: field,
|
|
144
|
+
operator: operator,
|
|
145
|
+
value: value,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return filters;
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region ---- Custom Filter Handlers ----
|
|
153
|
+
/**
|
|
154
|
+
* Apply custom price range filter to products
|
|
155
|
+
*/
|
|
156
|
+
applyPriceRangeFilter(products, priceRange) {
|
|
157
|
+
return products.filter((product) => {
|
|
158
|
+
const price = product.basePrice || 0;
|
|
159
|
+
switch (priceRange) {
|
|
160
|
+
case 'under-50':
|
|
161
|
+
return price < 50;
|
|
162
|
+
case '50-100':
|
|
163
|
+
return price >= 50 && price < 100;
|
|
164
|
+
case '100-500':
|
|
165
|
+
return price >= 100 && price < 500;
|
|
166
|
+
case '500-1000':
|
|
167
|
+
return price >= 500 && price < 1000;
|
|
168
|
+
case 'over-1000':
|
|
169
|
+
return price >= 1000;
|
|
170
|
+
default:
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetProductChartDataQuery, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
176
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetProductChartDataQuery, providedIn: 'root' }); }
|
|
177
|
+
}
|
|
178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetProductChartDataQuery, decorators: [{
|
|
179
|
+
type: Injectable,
|
|
180
|
+
args: [{
|
|
181
|
+
providedIn: 'root',
|
|
182
|
+
}]
|
|
183
|
+
}] });
|
|
184
|
+
|
|
185
|
+
export { GetProductChartDataQuery };
|
|
186
|
+
//# sourceMappingURL=acorex-connectivity-mock-get-product-chart-data.query-D7DBzLT-.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-connectivity-mock-get-product-chart-data.query-D7DBzLT-.mjs","sources":["../../../../libs/connectivity/mock/src/lib/product-catalog/reports/get-product-chart-data.query.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { AXPQuery } from '@acorex/platform/runtime';\nimport { AXPEntityService } from '@acorex/platform/layout/entity';\nimport { AXMProductCatalogProductEntityModel } from '@acorex/modules/product-catalog';\nimport { RootConfig } from '@acorex/modules/product-catalog';\n\n//#region ---- Query Input/Output Types ----\n\nexport interface GetProductChartDataQueryInput {\n filters?: Array<{\n field: string;\n operator: { type: string };\n value: any;\n }>;\n logic?: 'and' | 'or';\n}\n\nexport interface ProductChartDataResult {\n brand: string;\n productCount: number;\n}\n\nexport interface GetProductChartDataQueryResult {\n items: ProductChartDataResult[];\n}\n\n//#endregion\n\n@Injectable({\n providedIn: 'root',\n})\nexport class GetProductChartDataQuery implements AXPQuery<GetProductChartDataQueryInput, GetProductChartDataQueryResult> {\n private readonly entityService = inject(AXPEntityService);\n private productService = this.entityService.withEntity(`${RootConfig.module.name}.${RootConfig.entities.product.name}`).data<string, AXMProductCatalogProductEntityModel>();\n\n async fetch(input: GetProductChartDataQueryInput | any): Promise<GetProductChartDataQueryResult> {\n // Extract product-specific filters from AXPFilterClause format\n const extractedFilters = this.extractProductFilters(input.filters);\n\n // Separate custom filters from entity filters\n const entityFilters: GetProductChartDataQueryInput['filters'] = [];\n let priceRangeFilter: string | undefined;\n\n if (extractedFilters && extractedFilters.length > 0) {\n for (const filter of extractedFilters) {\n if (filter.field === 'priceRange') {\n priceRangeFilter = filter.value;\n } else {\n entityFilters.push(filter);\n }\n }\n }\n\n // Get all products from storage with entity filters (no pagination for charts)\n const allProductsResult = await this.productService.query({\n skip: 0,\n take: 10000, // Get all products for aggregation\n filter:\n entityFilters.length > 0\n ? ({\n logic: input.logic || 'and',\n filters: entityFilters,\n } as any)\n : undefined,\n });\n\n let allProducts = allProductsResult.items;\n\n // Apply custom price range filter after fetching\n if (priceRangeFilter && priceRangeFilter !== 'all') {\n allProducts = this.applyPriceRangeFilter(allProducts, priceRangeFilter);\n }\n\n // Group products by brand\n const brandGroups = new Map<string, AXMProductCatalogProductEntityModel[]>();\n\n for (const product of allProducts) {\n const brandKey = product.brand?.title || product.brandId || 'Unknown';\n\n if (!brandGroups.has(brandKey)) {\n brandGroups.set(brandKey, []);\n }\n\n brandGroups.get(brandKey)!.push(product);\n }\n\n // Aggregate data by brand for chart\n const chartResults: ProductChartDataResult[] = [];\n\n for (const [brandName, products] of brandGroups.entries()) {\n chartResults.push({\n brand: brandName,\n productCount: products.length,\n });\n }\n\n return {\n items: chartResults,\n };\n }\n\n //#region ---- Filter Extraction ----\n\n /**\n * Extract product-specific filters from AXPFilterClause format\n * Maps report parameter paths to product entity field names\n */\n private extractProductFilters(parameters: any): GetProductChartDataQueryInput['filters'] {\n const filters: GetProductChartDataQueryInput['filters'] = [];\n const paramsAny = parameters as any;\n\n if (!paramsAny?.filters || !Array.isArray(paramsAny.filters)) {\n return filters;\n }\n\n for (const filter of paramsAny.filters) {\n if (!filter?.field || filter?.value === undefined || filter?.value === null) {\n continue;\n }\n\n const field = filter.field;\n const value = filter.value;\n const operator = filter.operator || { type: 'equal' };\n\n // Handle product-specific field mappings\n if (field === 'brand') {\n // Brand filter - can be array of IDs or single ID\n if (Array.isArray(value) && value.length > 0) {\n filters.push({\n field: 'brandId',\n operator: { type: 'in' },\n value: value,\n });\n } else if (value) {\n filters.push({\n field: 'brandId',\n operator: { type: 'equal' },\n value: value,\n });\n }\n } else if (field === 'category') {\n // Category filter - can be array of IDs or single ID\n if (Array.isArray(value) && value.length > 0) {\n filters.push({\n field: 'categoryIds',\n operator: { type: 'contains' },\n value: value[0], // Use first category for contains check\n });\n } else if (value) {\n filters.push({\n field: 'categoryIds',\n operator: { type: 'contains' },\n value: value,\n });\n }\n } else if (field === 'status') {\n // Status filter - skip 'all' value\n if (value && value !== 'all') {\n filters.push({\n field: 'statusId',\n operator: { type: 'equal' },\n value: value,\n });\n }\n } else if (field === 'priceRange') {\n // Price range filter - custom logic handled in query\n filters.push({\n field: 'priceRange',\n operator: { type: 'equal' },\n value: value,\n });\n } else if (field === 'startDate' || field === 'endDate') {\n // Date filters - can be handled if needed\n // For now, skip as they might not be directly on product entity\n } else {\n // Direct field mapping\n filters.push({\n field: field,\n operator: operator,\n value: value,\n });\n }\n }\n\n return filters;\n }\n\n //#endregion\n\n //#region ---- Custom Filter Handlers ----\n\n /**\n * Apply custom price range filter to products\n */\n private applyPriceRangeFilter(\n products: AXMProductCatalogProductEntityModel[],\n priceRange: string\n ): AXMProductCatalogProductEntityModel[] {\n return products.filter((product) => {\n const price = product.basePrice || 0;\n\n switch (priceRange) {\n case 'under-50':\n return price < 50;\n case '50-100':\n return price >= 50 && price < 100;\n case '100-500':\n return price >= 100 && price < 500;\n case '500-1000':\n return price >= 500 && price < 1000;\n case 'over-1000':\n return price >= 1000;\n default:\n return true;\n }\n });\n }\n\n //#endregion\n}\n\n"],"names":[],"mappings":"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"}
|