rez_core 7.0.7 → 7.0.8
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/dist/config/database.config.js +1 -1
- package/dist/config/database.config.js.map +1 -1
- package/dist/module/filter/controller/filter.controller.d.ts +9 -0
- package/dist/module/filter/controller/filter.controller.js +45 -0
- package/dist/module/filter/controller/filter.controller.js.map +1 -1
- package/dist/module/filter/service/filter.service.d.ts +16 -1
- package/dist/module/filter/service/filter.service.js +163 -1
- package/dist/module/filter/service/filter.service.js.map +1 -1
- package/dist/module/linked_attributes/service/linked_attributes.service.d.ts +3 -1
- package/dist/module/linked_attributes/service/linked_attributes.service.js +7 -3
- package/dist/module/linked_attributes/service/linked_attributes.service.js.map +1 -1
- package/dist/module/listmaster/repository/list-master-items.repository.d.ts +1 -1
- package/dist/module/listmaster/repository/list-master-items.repository.js +36 -5
- package/dist/module/listmaster/repository/list-master-items.repository.js.map +1 -1
- package/dist/module/meta/service/entity-dynamic.service.js +18 -14
- package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
- package/dist/module/workflow/controller/workflow.controller.d.ts +0 -1
- package/dist/module/workflow/controller/workflow.controller.js.map +1 -1
- package/dist/module/workflow/service/workflow-meta.service.js +20 -20
- package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config/database.config.ts +1 -1
- package/src/module/filter/controller/filter.controller.ts +125 -0
- package/src/module/filter/service/filter.service.ts +339 -6
- package/src/module/linked_attributes/service/linked_attributes.service.ts +2 -0
- package/src/module/listmaster/repository/list-master-items.repository.ts +45 -9
- package/src/module/meta/service/entity-dynamic.service.ts +82 -38
- package/src/module/workflow/controller/workflow.controller.ts +0 -1
- package/src/module/workflow/service/workflow-meta.service.ts +31 -28
- package/src/resources/dev.properties.yaml +2 -2
package/package.json
CHANGED
|
@@ -36,7 +36,7 @@ export class PostgresConfiguration implements TypeOrmOptionsFactory {
|
|
|
36
36
|
database: this.configService.get('DB_NAME') || 'core',
|
|
37
37
|
schema: this.configService.get('DB_SCHEMA') || 'package',
|
|
38
38
|
entities: [__dirname + '/../module/**/*.entity.{ts,js}'],
|
|
39
|
-
synchronize:
|
|
39
|
+
synchronize: false,
|
|
40
40
|
autoLoadEntities: true,
|
|
41
41
|
// Configure pg pool size via `extra.max` (pg uses node-postgres pool)
|
|
42
42
|
extra: {
|
|
@@ -86,4 +86,129 @@ export class FilterController {
|
|
|
86
86
|
const loggedInUser = req.user.userData;
|
|
87
87
|
return this.savedFilterService.getSavedFilterByCode(code, loggedInUser);
|
|
88
88
|
}
|
|
89
|
+
|
|
90
|
+
// ========== NEW HIERARCHICAL FILTER ENDPOINTS ==========
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Test endpoint for GetFilterData (Core query builder)
|
|
94
|
+
* POST /filter/get-filter-data
|
|
95
|
+
* Body: {
|
|
96
|
+
* entity_type: string,
|
|
97
|
+
* filterConditions?: FilterCondition[],
|
|
98
|
+
* sortColumns?: { column: string, order: 'ASC' | 'DESC' }[],
|
|
99
|
+
* columns?: string[],
|
|
100
|
+
* flatJson?: boolean,
|
|
101
|
+
* ids?: number[],
|
|
102
|
+
* pagination?: { page: number, size: number }
|
|
103
|
+
* }
|
|
104
|
+
*/
|
|
105
|
+
@Post('get-filter-data')
|
|
106
|
+
@UseGuards(JwtAuthGuard)
|
|
107
|
+
@HttpCode(HttpStatus.OK)
|
|
108
|
+
async getFilterData(
|
|
109
|
+
@Body() body: any,
|
|
110
|
+
@Req() req: Request & { user: any },
|
|
111
|
+
) {
|
|
112
|
+
const loggedInUser = req.user.userData;
|
|
113
|
+
const {
|
|
114
|
+
entity_type,
|
|
115
|
+
filterConditions = [],
|
|
116
|
+
sortColumns = [],
|
|
117
|
+
columns = [],
|
|
118
|
+
flatJson = false,
|
|
119
|
+
ids = [],
|
|
120
|
+
pagination,
|
|
121
|
+
} = body;
|
|
122
|
+
|
|
123
|
+
return this.filterService.GetFilterData(
|
|
124
|
+
entity_type,
|
|
125
|
+
filterConditions,
|
|
126
|
+
sortColumns,
|
|
127
|
+
columns,
|
|
128
|
+
flatJson,
|
|
129
|
+
ids,
|
|
130
|
+
pagination,
|
|
131
|
+
loggedInUser,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Test endpoint for GetFilterDataInternal (Filter aggregation)
|
|
137
|
+
* POST /filter/get-filter-data-internal
|
|
138
|
+
* Body: {
|
|
139
|
+
* entity_type: string,
|
|
140
|
+
* filterCode?: string,
|
|
141
|
+
* quickFilter?: FilterCondition[],
|
|
142
|
+
* columns?: string[],
|
|
143
|
+
* flatJson?: boolean,
|
|
144
|
+
* ids?: number[]
|
|
145
|
+
* }
|
|
146
|
+
*/
|
|
147
|
+
@Post('get-filter-data-internal')
|
|
148
|
+
@UseGuards(JwtAuthGuard)
|
|
149
|
+
@HttpCode(HttpStatus.OK)
|
|
150
|
+
async getFilterDataInternal(
|
|
151
|
+
@Body() body: any,
|
|
152
|
+
@Req() req: Request & { user: any },
|
|
153
|
+
) {
|
|
154
|
+
const loggedInUser = req.user.userData;
|
|
155
|
+
const {
|
|
156
|
+
entity_type,
|
|
157
|
+
filterCode,
|
|
158
|
+
quickFilter = [],
|
|
159
|
+
columns = [],
|
|
160
|
+
flatJson = false,
|
|
161
|
+
ids = [],
|
|
162
|
+
} = body;
|
|
163
|
+
|
|
164
|
+
return this.filterService.GetFilterDataInternal(
|
|
165
|
+
entity_type,
|
|
166
|
+
filterCode,
|
|
167
|
+
quickFilter,
|
|
168
|
+
columns,
|
|
169
|
+
flatJson,
|
|
170
|
+
ids,
|
|
171
|
+
loggedInUser,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Test endpoint for GetFilterDataForListing (UI layer with layout preferences)
|
|
177
|
+
* POST /filter/get-filter-data-for-listing
|
|
178
|
+
* Body: {
|
|
179
|
+
* entity_type: string,
|
|
180
|
+
* quickFilter?: FilterCondition[],
|
|
181
|
+
* filterCode?: string,
|
|
182
|
+
* attributeFilter?: FilterCondition[],
|
|
183
|
+
* sortColumn?: { column: string, order: 'ASC' | 'DESC' },
|
|
184
|
+
* pagination?: { page: number, size: number }
|
|
185
|
+
* }
|
|
186
|
+
*/
|
|
187
|
+
@Post('get-filter-data-for-listing')
|
|
188
|
+
@UseGuards(JwtAuthGuard)
|
|
189
|
+
@HttpCode(HttpStatus.OK)
|
|
190
|
+
async getFilterDataForListing(
|
|
191
|
+
@Body() body: any,
|
|
192
|
+
@Req() req: Request & { user: any },
|
|
193
|
+
) {
|
|
194
|
+
const loggedInUser = req.user.userData;
|
|
195
|
+
const {
|
|
196
|
+
entity_type,
|
|
197
|
+
quickFilter = [],
|
|
198
|
+
filterCode,
|
|
199
|
+
attributeFilter = [],
|
|
200
|
+
sortColumn,
|
|
201
|
+
pagination,
|
|
202
|
+
} = body;
|
|
203
|
+
|
|
204
|
+
return this.filterService.GetFilterDataForListing(
|
|
205
|
+
entity_type,
|
|
206
|
+
quickFilter,
|
|
207
|
+
filterCode,
|
|
208
|
+
attributeFilter,
|
|
209
|
+
sortColumn,
|
|
210
|
+
pagination,
|
|
211
|
+
loggedInUser,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
89
214
|
}
|
|
@@ -536,11 +536,11 @@ export class FilterService {
|
|
|
536
536
|
);
|
|
537
537
|
}
|
|
538
538
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
539
|
+
const resolvedEntityList = await Promise.all(
|
|
540
|
+
formattedEntityList.map((row) =>
|
|
541
|
+
this.resolverService.getResolvedData(loggedInUser, row, entity_type),
|
|
542
|
+
),
|
|
543
|
+
);
|
|
544
544
|
|
|
545
545
|
let resolvedTabs = await Promise.all(
|
|
546
546
|
filteredTabs.map(async (tab) => {
|
|
@@ -591,7 +591,7 @@ export class FilterService {
|
|
|
591
591
|
success: true,
|
|
592
592
|
data: {
|
|
593
593
|
entity_tabs: resolvedTabs,
|
|
594
|
-
entity_list:
|
|
594
|
+
entity_list: resolvedEntityList,
|
|
595
595
|
is_hierarchical: isHierarchical,
|
|
596
596
|
pagination: {
|
|
597
597
|
total,
|
|
@@ -1379,6 +1379,339 @@ if (op === 'not_equal') {
|
|
|
1379
1379
|
}
|
|
1380
1380
|
}
|
|
1381
1381
|
|
|
1382
|
+
/**
|
|
1383
|
+
* Core filter data retrieval method
|
|
1384
|
+
* @param entityType - Entity type to query
|
|
1385
|
+
* @param filterConditions - Array of filter conditions
|
|
1386
|
+
* @param sortColumns - Array of sort columns with order
|
|
1387
|
+
* @param columns - Array of attribute keys to select (if empty, returns id and name)
|
|
1388
|
+
* @param flatJson - Whether to use flat JSON structure
|
|
1389
|
+
* @param ids - Optional array of IDs to filter by
|
|
1390
|
+
* @param pagination - Pagination parameters (page, size)
|
|
1391
|
+
* @param userData - Logged in user data
|
|
1392
|
+
* @returns Object with entity_list and pagination info
|
|
1393
|
+
*/
|
|
1394
|
+
async GetFilterData(
|
|
1395
|
+
entityType: string,
|
|
1396
|
+
filterConditions: FilterCondition[] = [],
|
|
1397
|
+
sortColumns: { column: string; order: 'ASC' | 'DESC' }[] = [],
|
|
1398
|
+
columns: string[] = [],
|
|
1399
|
+
flatJson: boolean = false,
|
|
1400
|
+
ids: number[] = [],
|
|
1401
|
+
pagination?: { page: number; size: number },
|
|
1402
|
+
userData?: any,
|
|
1403
|
+
) {
|
|
1404
|
+
console.log('🔹 [GetFilterData] Starting with params:', {
|
|
1405
|
+
entityType,
|
|
1406
|
+
filterConditions,
|
|
1407
|
+
sortColumns,
|
|
1408
|
+
columns,
|
|
1409
|
+
flatJson,
|
|
1410
|
+
ids,
|
|
1411
|
+
pagination,
|
|
1412
|
+
});
|
|
1413
|
+
|
|
1414
|
+
// Get EntityMaster by EntityType
|
|
1415
|
+
const entityMeta = await this.entityMasterService.getEntityData(
|
|
1416
|
+
entityType,
|
|
1417
|
+
userData,
|
|
1418
|
+
);
|
|
1419
|
+
const tableName = entityMeta?.data_source;
|
|
1420
|
+
|
|
1421
|
+
if (!tableName) {
|
|
1422
|
+
throw new BadRequestException(`Invalid entity_type: ${entityType}`);
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// Get AttributeMaster by EntityType
|
|
1426
|
+
const getAttributeColumnMeta =
|
|
1427
|
+
await this.attributeMasterService.findAttributesByMappedEntityType(
|
|
1428
|
+
entityType,
|
|
1429
|
+
userData,
|
|
1430
|
+
);
|
|
1431
|
+
|
|
1432
|
+
const attributeMetaMap = getAttributeColumnMeta.reduce(
|
|
1433
|
+
(acc, attr) => {
|
|
1434
|
+
acc[attr.attribute_key] = attr;
|
|
1435
|
+
return acc;
|
|
1436
|
+
},
|
|
1437
|
+
{} as Record<string, any>,
|
|
1438
|
+
);
|
|
1439
|
+
|
|
1440
|
+
// Build WHERE clauses using existing function
|
|
1441
|
+
const whereClauses = this.buildWhereClauses(
|
|
1442
|
+
filterConditions,
|
|
1443
|
+
attributeMetaMap,
|
|
1444
|
+
);
|
|
1445
|
+
|
|
1446
|
+
// Add IDs condition if provided
|
|
1447
|
+
if (ids && ids.length > 0) {
|
|
1448
|
+
const idsStr = ids.map((id) => String(id));
|
|
1449
|
+
whereClauses.push({
|
|
1450
|
+
query: 'e.id::text = ANY(:ids)',
|
|
1451
|
+
params: { ids: `{${idsStr.join(',')}}` },
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
// Build SELECT clause
|
|
1456
|
+
let selectClause = 'e.*'; // Default to all columns
|
|
1457
|
+
if (columns && columns.length > 0) {
|
|
1458
|
+
// Select specific columns
|
|
1459
|
+
const validColumns = columns
|
|
1460
|
+
.filter((col) => attributeMetaMap[col])
|
|
1461
|
+
.map((col) => `e.${col}`)
|
|
1462
|
+
.join(', ');
|
|
1463
|
+
selectClause = validColumns || 'e.id, e.name';
|
|
1464
|
+
} else {
|
|
1465
|
+
// If columns is empty, return id and name
|
|
1466
|
+
selectClause = 'e.id, e.name';
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// Build query
|
|
1470
|
+
let qb = this.entityManager
|
|
1471
|
+
.createQueryBuilder()
|
|
1472
|
+
.select(selectClause)
|
|
1473
|
+
.from(`${this.schema}.${tableName}`, 'e');
|
|
1474
|
+
|
|
1475
|
+
// Apply WHERE clauses
|
|
1476
|
+
whereClauses.forEach((clause) => qb.andWhere(clause.query, clause.params));
|
|
1477
|
+
|
|
1478
|
+
// Build SORT clauses
|
|
1479
|
+
if (sortColumns && sortColumns.length > 0) {
|
|
1480
|
+
sortColumns.forEach(({ column, order }) => {
|
|
1481
|
+
if (attributeMetaMap[column]) {
|
|
1482
|
+
qb.addOrderBy(`e.${column}`, order);
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
// Apply pagination if provided
|
|
1488
|
+
let page = 1;
|
|
1489
|
+
let size = 10;
|
|
1490
|
+
if (pagination && pagination.page > 0 && pagination.size > 0) {
|
|
1491
|
+
page = pagination.page;
|
|
1492
|
+
size = pagination.size;
|
|
1493
|
+
qb.skip((page - 1) * size).take(size);
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// Execute query
|
|
1497
|
+
const query = qb.getQuery();
|
|
1498
|
+
console.log('🔹 [GetFilterData] Executing query:', query);
|
|
1499
|
+
|
|
1500
|
+
const entity_list = await qb.getRawMany();
|
|
1501
|
+
|
|
1502
|
+
// Get total count
|
|
1503
|
+
const countQb = this.entityManager
|
|
1504
|
+
.createQueryBuilder()
|
|
1505
|
+
.select('COUNT(*)', 'count')
|
|
1506
|
+
.from(`${this.schema}.${tableName}`, 'e');
|
|
1507
|
+
whereClauses.forEach((clause) =>
|
|
1508
|
+
countQb.andWhere(clause.query, clause.params),
|
|
1509
|
+
);
|
|
1510
|
+
const countResult = await countQb.getRawOne();
|
|
1511
|
+
const total = parseInt(countResult.count, 10);
|
|
1512
|
+
|
|
1513
|
+
console.log(
|
|
1514
|
+
`🔹 [GetFilterData] Fetched ${entity_list.length} records, total: ${total}`,
|
|
1515
|
+
);
|
|
1516
|
+
|
|
1517
|
+
const result: any = {
|
|
1518
|
+
entity_list,
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1521
|
+
// Add pagination info if pagination was requested
|
|
1522
|
+
if (pagination) {
|
|
1523
|
+
result.pagination = {
|
|
1524
|
+
total,
|
|
1525
|
+
page,
|
|
1526
|
+
size,
|
|
1527
|
+
totalPages: Math.ceil(total / size),
|
|
1528
|
+
hasNextPage: page * size < total,
|
|
1529
|
+
hasPreviousPage: page > 1,
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
return result;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* Internal filter data retrieval with filter code resolution
|
|
1538
|
+
* @param entityType - Entity type to query
|
|
1539
|
+
* @param filterCode - Saved filter code to resolve
|
|
1540
|
+
* @param quickFilter - Quick filter conditions
|
|
1541
|
+
* @param columns - Array of attribute keys to select
|
|
1542
|
+
* @param flatJson - Whether to use flat JSON structure
|
|
1543
|
+
* @param ids - Optional array of IDs to filter by
|
|
1544
|
+
* @param userData - Logged in user data
|
|
1545
|
+
* @returns Object with entity_list and pagination info
|
|
1546
|
+
*/
|
|
1547
|
+
async GetFilterDataInternal(
|
|
1548
|
+
entityType: string,
|
|
1549
|
+
filterCode?: string,
|
|
1550
|
+
quickFilter: FilterCondition[] = [],
|
|
1551
|
+
columns: string[] = [],
|
|
1552
|
+
flatJson: boolean = false,
|
|
1553
|
+
ids: number[] = [],
|
|
1554
|
+
userData?: any,
|
|
1555
|
+
) {
|
|
1556
|
+
console.log('🔸 [GetFilterDataInternal] Starting with params:', {
|
|
1557
|
+
entityType,
|
|
1558
|
+
filterCode,
|
|
1559
|
+
quickFilter,
|
|
1560
|
+
columns,
|
|
1561
|
+
flatJson,
|
|
1562
|
+
ids,
|
|
1563
|
+
});
|
|
1564
|
+
|
|
1565
|
+
// Aggregate filterCode + quickfilter
|
|
1566
|
+
const savedFilters = await this.getSavedFilters(filterCode);
|
|
1567
|
+
|
|
1568
|
+
// Normalize saved filters to FilterCondition format
|
|
1569
|
+
const savedFiltersNormalized = savedFilters.map((f) => ({
|
|
1570
|
+
filter_attribute: f.filter_attribute,
|
|
1571
|
+
filter_operator: f.filter_operator,
|
|
1572
|
+
filter_value: f.filter_value,
|
|
1573
|
+
filter_entity_type: entityType,
|
|
1574
|
+
}));
|
|
1575
|
+
|
|
1576
|
+
// Merge all filters
|
|
1577
|
+
const allFilters = [...quickFilter, ...savedFiltersNormalized].filter(
|
|
1578
|
+
(f) => f.filter_value !== '' && f.filter_value != null,
|
|
1579
|
+
);
|
|
1580
|
+
|
|
1581
|
+
console.log('🔸 [GetFilterDataInternal] Aggregated filters:', allFilters);
|
|
1582
|
+
|
|
1583
|
+
// Call GetFilterData
|
|
1584
|
+
return await this.GetFilterData(
|
|
1585
|
+
entityType,
|
|
1586
|
+
allFilters,
|
|
1587
|
+
[], // No sort columns at this level
|
|
1588
|
+
columns,
|
|
1589
|
+
flatJson,
|
|
1590
|
+
ids,
|
|
1591
|
+
undefined, // No pagination at this level
|
|
1592
|
+
userData,
|
|
1593
|
+
);
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
/**
|
|
1597
|
+
* Filter data retrieval for listing with layout preferences
|
|
1598
|
+
* @param entityType - Entity type to query
|
|
1599
|
+
* @param quickFilter - Quick filter conditions
|
|
1600
|
+
* @param filterCode - Saved filter code to resolve
|
|
1601
|
+
* @param attributeFilter - Attribute filter conditions
|
|
1602
|
+
* @param sortColumn - Sort column with order (will be overridden by layout preference)
|
|
1603
|
+
* @param pagination - Pagination parameters
|
|
1604
|
+
* @param userData - Logged in user data
|
|
1605
|
+
* @returns Object with entity_list and pagination info
|
|
1606
|
+
*/
|
|
1607
|
+
async GetFilterDataForListing(
|
|
1608
|
+
entityType: string,
|
|
1609
|
+
quickFilter: FilterCondition[] = [],
|
|
1610
|
+
filterCode?: string,
|
|
1611
|
+
attributeFilter: FilterCondition[] = [],
|
|
1612
|
+
sortColumn?: { column: string; order: 'ASC' | 'DESC' },
|
|
1613
|
+
pagination?: { page: number; size: number },
|
|
1614
|
+
userData?: any,
|
|
1615
|
+
) {
|
|
1616
|
+
console.log('🔷 [GetFilterDataForListing] Starting with params:', {
|
|
1617
|
+
entityType,
|
|
1618
|
+
quickFilter,
|
|
1619
|
+
filterCode,
|
|
1620
|
+
attributeFilter,
|
|
1621
|
+
sortColumn,
|
|
1622
|
+
pagination,
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
const { level_type, level_id, id: user_id } = userData || {};
|
|
1626
|
+
|
|
1627
|
+
// Check flat_json by EntityMaster
|
|
1628
|
+
const entityMeta = await this.entityMasterService.getEntityData(
|
|
1629
|
+
entityType,
|
|
1630
|
+
userData,
|
|
1631
|
+
);
|
|
1632
|
+
const flatJson = (entityMeta as any)?.flat_json || false;
|
|
1633
|
+
|
|
1634
|
+
// Aggregate quickfilter[], attributeFilter[] and filterCode
|
|
1635
|
+
const savedFilters = await this.getSavedFilters(filterCode);
|
|
1636
|
+
const savedFiltersNormalized = savedFilters.map((f) => ({
|
|
1637
|
+
filter_attribute: f.filter_attribute,
|
|
1638
|
+
filter_operator: f.filter_operator,
|
|
1639
|
+
filter_value: f.filter_value,
|
|
1640
|
+
filter_entity_type: entityType,
|
|
1641
|
+
}));
|
|
1642
|
+
|
|
1643
|
+
const allFilters = [
|
|
1644
|
+
...quickFilter,
|
|
1645
|
+
...attributeFilter,
|
|
1646
|
+
...savedFiltersNormalized,
|
|
1647
|
+
].filter((f) => f.filter_value !== '' && f.filter_value != null);
|
|
1648
|
+
|
|
1649
|
+
console.log('🔷 [GetFilterDataForListing] Aggregated filters:', allFilters);
|
|
1650
|
+
|
|
1651
|
+
// Get LayoutPreference by (EntityType, user_id, type:layout)
|
|
1652
|
+
let layoutPreferenceRepo =
|
|
1653
|
+
this.reflectionHelper.getRepoService('LayoutPreference');
|
|
1654
|
+
|
|
1655
|
+
const layoutPreference = await layoutPreferenceRepo.findOne({
|
|
1656
|
+
where: {
|
|
1657
|
+
user_id: user_id,
|
|
1658
|
+
mapped_entity_type: entityType,
|
|
1659
|
+
mapped_level_id: level_id,
|
|
1660
|
+
mapped_level_type: level_type,
|
|
1661
|
+
type: 'layout',
|
|
1662
|
+
},
|
|
1663
|
+
});
|
|
1664
|
+
|
|
1665
|
+
// Get col[] from LayoutPreference
|
|
1666
|
+
let columns: string[] = [];
|
|
1667
|
+
if (layoutPreference?.mapped_json?.columns) {
|
|
1668
|
+
columns = layoutPreference.mapped_json.columns.map(
|
|
1669
|
+
(col: any) => col.attribute_key || col,
|
|
1670
|
+
);
|
|
1671
|
+
} else {
|
|
1672
|
+
// Default columns when no layout preference exists
|
|
1673
|
+
columns = ['id', 'name', 'code', 'status', 'description'];
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
console.log('🔷 [GetFilterDataForListing] Layout columns:', columns);
|
|
1677
|
+
|
|
1678
|
+
// Get sortColumns[] from LayoutPreference (override sortColumn if exists)
|
|
1679
|
+
let sortColumns: { column: string; order: 'ASC' | 'DESC' }[] = [];
|
|
1680
|
+
|
|
1681
|
+
if (layoutPreference?.mapped_json?.sorting?.sortby) {
|
|
1682
|
+
// Layout preference sorting exists - override sortColumn
|
|
1683
|
+
sortColumns = layoutPreference.mapped_json.sorting.sortby.map(
|
|
1684
|
+
(sort: any) => ({
|
|
1685
|
+
column: sort.column,
|
|
1686
|
+
order: sort.order?.toUpperCase() === 'DSC' ? 'DESC' : 'ASC',
|
|
1687
|
+
}),
|
|
1688
|
+
);
|
|
1689
|
+
console.log(
|
|
1690
|
+
'🔷 [GetFilterDataForListing] Using layout preference sorting:',
|
|
1691
|
+
sortColumns,
|
|
1692
|
+
);
|
|
1693
|
+
} else if (sortColumn) {
|
|
1694
|
+
// No layout preference - use provided sortColumn
|
|
1695
|
+
sortColumns = [sortColumn];
|
|
1696
|
+
console.log(
|
|
1697
|
+
'🔷 [GetFilterDataForListing] Using provided sortColumn:',
|
|
1698
|
+
sortColumns,
|
|
1699
|
+
);
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
// Call GetFilterData
|
|
1703
|
+
return await this.GetFilterData(
|
|
1704
|
+
entityType,
|
|
1705
|
+
allFilters,
|
|
1706
|
+
sortColumns,
|
|
1707
|
+
columns,
|
|
1708
|
+
flatJson,
|
|
1709
|
+
[],
|
|
1710
|
+
pagination,
|
|
1711
|
+
userData,
|
|
1712
|
+
);
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1382
1715
|
async queryWithSchema(sql: string, params: any[] = []) {
|
|
1383
1716
|
await this.entityManager.query('BEGIN');
|
|
1384
1717
|
await this.entityManager.query(`SET LOCAL search_path TO ${this.schema}`);
|
|
@@ -15,6 +15,8 @@ import { FilterService } from 'src/module/filter/service/filter.service';
|
|
|
15
15
|
export class LinkedAttributesService extends EntityServiceImpl {
|
|
16
16
|
constructor(
|
|
17
17
|
private readonly dataSource: DataSource,
|
|
18
|
+
@Inject('EntityMasterService')
|
|
19
|
+
protected readonly entityMasterService: EntityMasterService,
|
|
18
20
|
@Inject('AttributeMasterService')
|
|
19
21
|
private readonly attributeMasterService: AttributeMasterService,
|
|
20
22
|
@Inject('SavedFilterService')
|
|
@@ -8,7 +8,8 @@ export class ListMasterItemsRepository {
|
|
|
8
8
|
constructor(
|
|
9
9
|
@InjectRepository(ListMasterItems)
|
|
10
10
|
private repo: Repository<ListMasterItems>,
|
|
11
|
-
) {
|
|
11
|
+
) {
|
|
12
|
+
}
|
|
12
13
|
|
|
13
14
|
async create(item: Partial<ListMasterItems>) {
|
|
14
15
|
const newItem = this.repo.create(item);
|
|
@@ -26,19 +27,53 @@ export class ListMasterItemsRepository {
|
|
|
26
27
|
storage_type?,
|
|
27
28
|
enterprise_id?: number,
|
|
28
29
|
params?: Record<string, string>,
|
|
29
|
-
values?: any[]
|
|
30
|
+
values?: any[],
|
|
31
|
+
inactiveIds?: number[],
|
|
30
32
|
) {
|
|
31
33
|
let orderBy: Record<string, 'ASC' | 'DESC'> = {};
|
|
32
34
|
|
|
35
|
+
if (values?.length) {
|
|
36
|
+
if (storage_type === 'code') {
|
|
37
|
+
const itemValues = await this.repo.find({
|
|
38
|
+
where: {
|
|
39
|
+
listtype: type,
|
|
40
|
+
code: In(values),
|
|
41
|
+
},
|
|
42
|
+
order: orderBy,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const itemsMapped = itemValues.map((i) => ({
|
|
46
|
+
label: `${i.name} [INACTIVE]`,
|
|
47
|
+
value: String(i.code),
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
return [...itemsMapped];
|
|
51
|
+
} else {
|
|
52
|
+
const itemValues = await this.repo.find({
|
|
53
|
+
where: {
|
|
54
|
+
listtype: type,
|
|
55
|
+
id: In(values),
|
|
56
|
+
},
|
|
57
|
+
order: orderBy,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const itemsMapped = itemValues.map((i) => ({
|
|
61
|
+
label: `${i.name}`,
|
|
62
|
+
value: String(i.id),
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
return [...itemsMapped];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
33
70
|
// Initial where clause
|
|
34
71
|
const whereClause: any = {
|
|
35
72
|
listtype: type,
|
|
36
|
-
|
|
73
|
+
enterprise_id: enterprise_id,
|
|
37
74
|
status: 'ACTIVE',
|
|
38
75
|
};
|
|
39
76
|
|
|
40
|
-
|
|
41
|
-
|
|
42
77
|
// Helper to check numeric
|
|
43
78
|
const isNumeric = (value: any) => !isNaN(Number(value));
|
|
44
79
|
|
|
@@ -88,21 +123,22 @@ export class ListMasterItemsRepository {
|
|
|
88
123
|
value: storage_type === 'code' ? i.code : String(i.id),
|
|
89
124
|
}));
|
|
90
125
|
|
|
126
|
+
|
|
91
127
|
// Handle inactive items if specified
|
|
92
|
-
if (
|
|
128
|
+
if (inactiveIds?.length) {
|
|
93
129
|
if (storage_type === 'code') {
|
|
94
130
|
const inactiveItems = await this.repo.find({
|
|
95
131
|
where: {
|
|
96
132
|
listtype: type,
|
|
97
133
|
enterprise_id: enterprise_id,
|
|
98
|
-
code: In(
|
|
134
|
+
code: In(inactiveIds),
|
|
99
135
|
},
|
|
100
136
|
order: orderBy,
|
|
101
137
|
});
|
|
102
138
|
|
|
103
139
|
const inactiveMapped = inactiveItems.map((i) => ({
|
|
104
140
|
label: `${i.name} [INACTIVE]`,
|
|
105
|
-
value: String(i.
|
|
141
|
+
value: String(i.code),
|
|
106
142
|
}));
|
|
107
143
|
|
|
108
144
|
result = [...result, ...inactiveMapped];
|
|
@@ -111,7 +147,7 @@ export class ListMasterItemsRepository {
|
|
|
111
147
|
where: {
|
|
112
148
|
listtype: type,
|
|
113
149
|
// enterprise_id: enterprise_id,
|
|
114
|
-
id: In(
|
|
150
|
+
id: In(inactiveIds),
|
|
115
151
|
},
|
|
116
152
|
order: orderBy,
|
|
117
153
|
});
|