rez_core 2.1.47 → 2.1.49

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.
Files changed (26) hide show
  1. package/dist/module/filter/controller/filter.controller.d.ts +1 -1
  2. package/dist/module/filter/entity/saved-filter-detail.entity.d.ts +2 -1
  3. package/dist/module/filter/entity/saved-filter-detail.entity.js +4 -0
  4. package/dist/module/filter/entity/saved-filter-detail.entity.js.map +1 -1
  5. package/dist/module/filter/repository/saved-filter.repository.d.ts +1 -1
  6. package/dist/module/filter/repository/saved-filter.repository.js +6 -2
  7. package/dist/module/filter/repository/saved-filter.repository.js.map +1 -1
  8. package/dist/module/filter/service/filter.service.js +73 -8
  9. package/dist/module/filter/service/filter.service.js.map +1 -1
  10. package/dist/module/filter/service/saved-filter.service.d.ts +2 -1
  11. package/dist/module/filter/service/saved-filter.service.js +28 -5
  12. package/dist/module/filter/service/saved-filter.service.js.map +1 -1
  13. package/dist/module/meta/controller/entity.controller.d.ts +5 -0
  14. package/dist/module/meta/controller/entity.controller.js +29 -0
  15. package/dist/module/meta/controller/entity.controller.js.map +1 -1
  16. package/dist/module/meta/service/entity-service-impl.service.d.ts +1 -1
  17. package/dist/module/meta/service/entity-service-impl.service.js +12 -1
  18. package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
  19. package/dist/tsconfig.build.tsbuildinfo +1 -1
  20. package/package.json +1 -1
  21. package/src/module/filter/entity/saved-filter-detail.entity.ts +6 -3
  22. package/src/module/filter/repository/saved-filter.repository.ts +8 -3
  23. package/src/module/filter/service/filter.service.ts +88 -43
  24. package/src/module/filter/service/saved-filter.service.ts +42 -5
  25. package/src/module/meta/controller/entity.controller.ts +41 -0
  26. package/src/module/meta/service/entity-service-impl.service.ts +21 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.1.47",
3
+ "version": "2.1.49",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -1,6 +1,6 @@
1
- import { ENTITYTYPE_SAVEDFILTERDETAIL } from "src/constant/global.constant";
2
- import { BaseEntity } from "src/module/meta/entity/base-entity.entity";
3
- import { Column, Entity } from "typeorm";
1
+ import { ENTITYTYPE_SAVEDFILTERDETAIL } from 'src/constant/global.constant';
2
+ import { BaseEntity } from 'src/module/meta/entity/base-entity.entity';
3
+ import { Column, Entity } from 'typeorm';
4
4
 
5
5
  @Entity({ name: 'cr_saved_filter_detail' })
6
6
  export class SavedFilterDetail extends BaseEntity {
@@ -20,4 +20,7 @@ export class SavedFilterDetail extends BaseEntity {
20
20
 
21
21
  @Column()
22
22
  filter_value: string;
23
+
24
+ @Column({ nullable: true })
25
+ data_type: string;
23
26
  }
@@ -77,7 +77,7 @@ export class SavedFilterRepositoryService {
77
77
  status: 'ACTIVE',
78
78
  },
79
79
  order: {
80
- modified_date: 'DESC',
80
+ created_date: 'DESC',
81
81
  },
82
82
  });
83
83
 
@@ -91,7 +91,7 @@ export class SavedFilterRepositoryService {
91
91
  {
92
92
  filter_attribute: string;
93
93
  filter_operator: string;
94
- filter_value: string;
94
+ filter_value: any;
95
95
  }[]
96
96
  > {
97
97
  const saveFilterMasterData = await this.savedFilterMasterRepo.findOne({
@@ -107,7 +107,12 @@ export class SavedFilterRepositoryService {
107
107
  return filterDetails.map((detail) => ({
108
108
  filter_attribute: detail.filter_attribute,
109
109
  filter_operator: detail.filter_operator,
110
- filter_value: detail.filter_value,
110
+ filter_value:
111
+ detail.data_type === 'multiselect'
112
+ ? detail.filter_value?.trim() === ''
113
+ ? []
114
+ : detail.filter_value.split(',')
115
+ : detail.filter_value,
111
116
  }));
112
117
  }
113
118
  }
@@ -121,7 +121,7 @@ export class FilterService {
121
121
  {} as Record<string, any>,
122
122
  );
123
123
 
124
- // Get and parse filters
124
+ // Get and parse saved filters
125
125
  const savedFilters = await this.getSavedFilters(savedFilterCode);
126
126
  const baseFilters = [
127
127
  ...(quickFilter || []).filter((f) => f.filter_value !== ''),
@@ -129,8 +129,10 @@ export class FilterService {
129
129
  ...(attributeFilter || []).filter((f) => f.filter_value !== ''),
130
130
  ];
131
131
 
132
+ // Build where clauses
132
133
  const baseWhere = this.buildWhereClauses(baseFilters, attributeMetaMap);
133
134
 
135
+ // check level_id and level_type
134
136
  if (level_type && level_id) {
135
137
  baseWhere.push({
136
138
  query: 'e.level_type = :level_type AND e.level_id = :level_id',
@@ -148,10 +150,11 @@ export class FilterService {
148
150
  });
149
151
  }
150
152
 
153
+ // layout preference query
151
154
  const layoutPreference = await this.dataSource.query(
152
155
  `SELECT layout_json
153
- FROM cr_layout_preference
154
- WHERE user_id = ? AND mapped_entity_type = ?`,
156
+ FROM cr_layout_preference
157
+ WHERE user_id = ? AND mapped_entity_type = ?`,
155
158
  [user_id, entity_type],
156
159
  );
157
160
 
@@ -191,13 +194,13 @@ export class FilterService {
191
194
 
192
195
  // Separate out 'all' tab before sorting
193
196
  const allTab = filteredTabs.find(
194
- (tab) => tab.tab_value.toLowerCase() === 'all',
197
+ (tab) => tab.tab_value?.toLowerCase() === 'all',
195
198
  );
196
199
  filteredTabs = filteredTabs.filter(
197
- (tab) => tab.tab_value.toLowerCase() !== 'all',
200
+ (tab) => tab.tab_value?.toLowerCase() !== 'all',
198
201
  );
199
202
 
200
- // 🔽 SORTING LOGIC
203
+ // SORTING LOGIC
201
204
  if (layout.sorting === 'asc') {
202
205
  filteredTabs.sort((a, b) =>
203
206
  a.tab_value.toLowerCase().localeCompare(b.tab_value.toLowerCase()),
@@ -270,7 +273,8 @@ export class FilterService {
270
273
  {
271
274
  filter_attribute: tabs.columnName,
272
275
  filter_operator: 'not_equal',
273
- filter_value: value,
276
+ filter_value: [value],
277
+ skip_id: true,
274
278
  },
275
279
  tabAttrMeta,
276
280
  );
@@ -285,7 +289,8 @@ export class FilterService {
285
289
  {
286
290
  filter_attribute: tabs.columnName,
287
291
  filter_operator: 'equal',
288
- filter_value: tabs.value,
292
+ filter_value: [tabs.value],
293
+ skip_id: true,
289
294
  },
290
295
  tabAttrMeta,
291
296
  );
@@ -356,40 +361,31 @@ export class FilterService {
356
361
  // Get paginated data
357
362
  const entity_list = await qb.getRawMany();
358
363
 
359
- // const formatDatesInRow = (row: any) => {
360
- // const formattedRow = { ...row };
361
- // for (const key of Object.keys(row)) {
362
- // if (key.endsWith('_date') && row[key]) {
363
- // formattedRow[key] = moment(row[key]).format('MMM DD, YYYY');
364
- // }
365
- // }
366
- // return formattedRow;
367
- // };
368
-
369
364
  // 1. Extract all date-type attribute keys
370
- // const dateAttributes = Object.entries(attributeMetaMap)
371
- // .filter(([_, attr]) => attr.data_type === 'date')
372
- // .map(([key]) => key); // only the keys (e.g., 'created_date', 'modified_date')
373
-
374
- // // 2. Format function using moment
375
- // const formatDate = (dateStr: string | null): string | null => {
376
- // if (!dateStr) return null;
377
- // return moment(dateStr).format('MMM DD, YYYY'); // e.g., "Jun 25, 2025"
378
- // };
379
-
380
- // // 3. Function to format only those keys in each entity row
381
- // const formatDatesInRow = (row: any): any => {
382
- // const formattedRow = { ...row };
383
- // for (const key of dateAttributes) {
384
- // if (formattedRow[key]) {
385
- // formattedRow[key] = formatDate(formattedRow[key]);
386
- // }
387
- // }
388
- // return formattedRow;
389
- // };
390
-
391
- // // 4. Final transformation
392
- // const formattedEntityList = entity_list.map(formatDatesInRow);
365
+ const dateAttributes = Object.entries(attributeMetaMap)
366
+ .filter(([_, attr]) => attr.data_type === 'date')
367
+ .map(([key]) => key);
368
+
369
+ // 2. Format function using moment
370
+ const formatDate = (dateStr: string | null): string | null => {
371
+ if (!dateStr) return '';
372
+ const date = moment(dateStr).format('DD-MM-YYYY'); // converted
373
+ return date;
374
+ };
375
+
376
+ // 3. Function to format only those keys in each entity row
377
+ const formatDatesInRow = (row: any): any => {
378
+ const formattedRow = { ...row };
379
+ for (const key of dateAttributes) {
380
+ if (formattedRow[key]) {
381
+ formattedRow[key] = formatDate(formattedRow[key]);
382
+ }
383
+ }
384
+ return formattedRow;
385
+ };
386
+
387
+ // 4. Final transformation
388
+ const formattedEntityList = entity_list.map(formatDatesInRow);
393
389
 
394
390
  // Count query (without pagination)
395
391
  const countQb = this.dataSource
@@ -406,7 +402,7 @@ export class FilterService {
406
402
  success: true,
407
403
  data: {
408
404
  entity_tabs: filteredTabs,
409
- entity_list,
405
+ entity_list: formattedEntityList,
410
406
  pagination: {
411
407
  total,
412
408
  page,
@@ -466,7 +462,8 @@ export class FilterService {
466
462
  const op = filter.filter_operator;
467
463
  const key = `param_${attr}_${Math.random().toString(36).substring(2, 8)}`;
468
464
 
469
- if (meta.data_source_type === 'entity') attr = `${attr}_id`;
465
+ if (meta.data_source_type === 'entity' && !filter.skip_id)
466
+ attr = `${attr}_id`;
470
467
 
471
468
  switch (meta.data_type) {
472
469
  case 'text':
@@ -479,6 +476,10 @@ export class FilterService {
479
476
  return this.buildMultiSelectCondition(attr, op, val, key);
480
477
  case 'multiselect':
481
478
  return this.buildMultiSelectCondition(attr, op, val, key);
479
+ case 'checkbox':
480
+ return this.buildMultiSelectCondition(attr, op, val, key);
481
+ case 'radio':
482
+ return this.buildMultiSelectCondition(attr, op, val, key);
482
483
  case 'year':
483
484
  return this.buildYearCondition(attr, op, val, key);
484
485
  default:
@@ -533,6 +534,15 @@ export class FilterService {
533
534
  return { query: `e.${attr} > :${key}`, params: { [key]: val } };
534
535
  case 'less_than':
535
536
  return { query: `e.${attr} < :${key}`, params: { [key]: val } };
537
+ case 'less_than_qual_to':
538
+ return { query: `e.${attr} <= :${key}`, params: { [key]: val } };
539
+ case 'greater_than_qual_to':
540
+ return { query: `e.${attr} >= :${key}`, params: { [key]: val } };
541
+ case 'empty':
542
+ return { query: `e.${attr} IS NULL`, params: {} };
543
+ case 'not_empty':
544
+ return { query: `e.${attr} IS NOT NULL`, params: {} };
545
+
536
546
  default:
537
547
  throw new BadRequestException(`Unsupported operator for number: ${op}`);
538
548
  }
@@ -561,6 +571,31 @@ export class FilterService {
561
571
  },
562
572
  };
563
573
  }
574
+
575
+ case 'today': {
576
+ const today = new Date().toISOString().split('T')[0]; // 'YYYY-MM-DD'
577
+
578
+ return {
579
+ query: `DATE(e.${attr}) = :today`,
580
+ params: {
581
+ today,
582
+ },
583
+ };
584
+ }
585
+
586
+ case 'empty': {
587
+ return {
588
+ query: `e.${attr} IS NULL`,
589
+ params: {},
590
+ };
591
+ }
592
+
593
+ case 'not_empty': {
594
+ return {
595
+ query: `e.${attr} IS NOT NULL`,
596
+ params: {},
597
+ };
598
+ }
564
599
  default:
565
600
  throw new BadRequestException(`Unsupported operator for date: ${op}`);
566
601
  }
@@ -613,6 +648,16 @@ export class FilterService {
613
648
  query: `e.${attr} NOT IN (:${key})`,
614
649
  params: { [key]: val },
615
650
  };
651
+ case 'contains':
652
+ return {
653
+ query: `e.${attr} LIKE :${key}`,
654
+ params: { [key]: `%${val}%` },
655
+ };
656
+ case 'not_contains':
657
+ return {
658
+ query: `e.${attr} NOT LIKE :${key}`,
659
+ params: { [key]: `%${val}%` },
660
+ };
616
661
  case 'empty':
617
662
  return { query: `e.${attr} IS NULL`, params: {} };
618
663
  case 'not_empty':
@@ -32,6 +32,7 @@ export class SavedFilterService extends EntityServiceImpl {
32
32
  }
33
33
 
34
34
  entityData.user_id = loggedInUser?.id ?? null;
35
+
35
36
  // Save the master record without code
36
37
  const savedMaster = await super.createEntity(master, loggedInUser);
37
38
 
@@ -45,10 +46,22 @@ export class SavedFilterService extends EntityServiceImpl {
45
46
  // Save filter details using generated code
46
47
  const details = (entityData as any).filterDetails ?? [];
47
48
  if (details.length) {
48
- const prepared = details.map((detail: any) => ({
49
- ...detail,
50
- mapped_filter_code: savedMaster.code,
51
- }));
49
+ const prepared = details.map((detail: any) => {
50
+ // If detail.filter_value is an array, join it with comma
51
+ if (Array.isArray(detail.filter_value)) {
52
+ return {
53
+ ...detail,
54
+ mapped_filter_code: savedMaster.code,
55
+ filter_value: detail.filter_value.join(','),
56
+ data_type: 'multiselect',
57
+ };
58
+ }
59
+ // Otherwise, just add mapped_filter_code
60
+ return {
61
+ ...detail,
62
+ mapped_filter_code: savedMaster.code,
63
+ };
64
+ });
52
65
 
53
66
  await this.savedFilterRepo.saveDetails(prepared);
54
67
  }
@@ -98,11 +111,35 @@ export class SavedFilterService extends EntityServiceImpl {
98
111
  return updated;
99
112
  }
100
113
 
114
+ async deleteEntity(entityType: string, entityId: number) {
115
+ const entityMaster =
116
+ await this.entityMasterService.getEntityData(entityType);
117
+
118
+ const repoService = this.reflectionHelper.getRepoService(
119
+ entityMaster.entity_data_class,
120
+ );
121
+ if (!repoService) {
122
+ throw new Error(
123
+ `Repository service not found for entityType: ${entityType}`,
124
+ );
125
+ }
126
+
127
+ const entityData = await repoService.findOne({ where: { id: entityId } });
128
+
129
+ if (!entityData) {
130
+ throw new Error(`Entity not found for entityType: ${entityType}`);
131
+ }
132
+
133
+ await this.savedFilterRepo.deleteDetailsByCode(entityData.code);
134
+
135
+ await repoService.delete(entityId);
136
+ }
137
+
101
138
  async getDetailsByCode(code: string): Promise<SavedFilterDetail[]> {
102
139
  return this.savedFilterRepo.getDetailsByCode(code);
103
140
  }
104
141
 
105
142
  async getFilterById(id: number) {
106
- return this.savedFilterRepo.getFilterById(id);
143
+ return await this.savedFilterRepo.getFilterById(id);
107
144
  }
108
145
  }
@@ -144,6 +144,47 @@ export class EntityController {
144
144
  };
145
145
  }
146
146
 
147
+ @Post('delete/:id')
148
+ @HttpCode(200)
149
+ async delete(
150
+ @Param('id') id: number,
151
+ @Query('entity_type') entityType: string,
152
+ @Req() req: Request & { user: any },
153
+ ) {
154
+ const loggedInUser = req.user.userData;
155
+
156
+ if (!entityType) {
157
+ throw new BadRequestException(
158
+ 'Query parameter "entity_type" is required',
159
+ );
160
+ }
161
+
162
+ const entityMaster =
163
+ await this.entityMasterService.getEntityData(entityType);
164
+
165
+ const entityService =
166
+ await this.reflectionHelper.getBean<EntityServiceImpl>(
167
+ entityMaster.entity_service,
168
+ );
169
+
170
+ if (!entityService) {
171
+ throw new InternalServerErrorException(
172
+ `No service found for entity_type "${entityType}"`,
173
+ );
174
+ }
175
+
176
+ const existingEntity = await entityService.getEntityData(entityType, id);
177
+ if (!existingEntity) {
178
+ throw new NotFoundException(`No entity found for id "${id}"`);
179
+ }
180
+
181
+ await entityService.deleteEntity(entityType, id);
182
+
183
+ return {
184
+ success: true,
185
+ };
186
+ }
187
+
147
188
  @Post('getFilteredDataWithTabs/:entity_type')
148
189
  async getFilterDataWithTabs(
149
190
  @Param('entity_type') entityType: string,
@@ -94,11 +94,27 @@ export class EntityServiceImpl implements EntityService<BaseEntity> {
94
94
  return repo.save(entityData);
95
95
  }
96
96
 
97
- deleteEntity(
98
- entityType: string,
99
- entityId: number,
100
- loggedInUserData: UserData,
101
- ) {}
97
+ async deleteEntity(entityType: string, entityId: number) {
98
+ const entityMaster =
99
+ await this.entityMasterService.getEntityData(entityType);
100
+
101
+ const repoService = this.reflectionHelper.getRepoService(
102
+ entityMaster.entity_data_class,
103
+ );
104
+ if (!repoService) {
105
+ throw new Error(
106
+ `Repository service not found for entityType: ${entityType}`,
107
+ );
108
+ }
109
+
110
+ const entityData = await repoService.findOne({ where: { id: entityId } });
111
+
112
+ if (!entityData) {
113
+ throw new Error(`Entity not found for entityType: ${entityType}`);
114
+ }
115
+
116
+ await repoService.delete(entityId);
117
+ }
102
118
 
103
119
  async findByCode(entityType: string, code: string): Promise<BaseEntity> {
104
120
  const entityData = await this.entityMasterService.getEntityData(entityType);