rez_core 5.0.28 → 5.0.30

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 (85) hide show
  1. package/dist/module/entity_json/controller/entity_json.controller.d.ts +11 -1
  2. package/dist/module/entity_json/controller/entity_json.controller.js +14 -0
  3. package/dist/module/entity_json/controller/entity_json.controller.js.map +1 -1
  4. package/dist/module/entity_json/entity/entityJson.entity.d.ts +10 -0
  5. package/dist/module/entity_json/entity/entityJson.entity.js +55 -0
  6. package/dist/module/entity_json/entity/entityJson.entity.js.map +1 -0
  7. package/dist/module/entity_json/entity_json.module.js +4 -2
  8. package/dist/module/entity_json/entity_json.module.js.map +1 -1
  9. package/dist/module/entity_json/service/entityJson.repository.d.ts +7 -0
  10. package/dist/module/entity_json/service/entityJson.repository.js +45 -0
  11. package/dist/module/entity_json/service/entityJson.repository.js.map +1 -0
  12. package/dist/module/entity_json/service/entity_json.service.d.ts +14 -4
  13. package/dist/module/entity_json/service/entity_json.service.js +84 -57
  14. package/dist/module/entity_json/service/entity_json.service.js.map +1 -1
  15. package/dist/module/filter/service/filter.service.js +84 -14
  16. package/dist/module/filter/service/filter.service.js.map +1 -1
  17. package/dist/module/linked_attributes/controller/linked_attributes.controller.d.ts +2 -0
  18. package/dist/module/linked_attributes/controller/linked_attributes.controller.js +26 -0
  19. package/dist/module/linked_attributes/controller/linked_attributes.controller.js.map +1 -1
  20. package/dist/module/linked_attributes/entity/linked_attribute.entity.d.ts +1 -0
  21. package/dist/module/linked_attributes/entity/linked_attribute.entity.js +4 -0
  22. package/dist/module/linked_attributes/entity/linked_attribute.entity.js.map +1 -1
  23. package/dist/module/linked_attributes/service/linked_attributes.service.d.ts +6 -1
  24. package/dist/module/linked_attributes/service/linked_attributes.service.js +61 -2
  25. package/dist/module/linked_attributes/service/linked_attributes.service.js.map +1 -1
  26. package/dist/module/listmaster/service/list-master.service.js +4 -2
  27. package/dist/module/listmaster/service/list-master.service.js.map +1 -1
  28. package/dist/module/meta/controller/attribute-master.controller.d.ts +2 -3
  29. package/dist/module/meta/controller/attribute-master.controller.js +2 -12
  30. package/dist/module/meta/controller/attribute-master.controller.js.map +1 -1
  31. package/dist/module/meta/entity/attribute-master.entity.d.ts +1 -0
  32. package/dist/module/meta/entity/attribute-master.entity.js +4 -0
  33. package/dist/module/meta/entity/attribute-master.entity.js.map +1 -1
  34. package/dist/module/notification/controller/otp.controller.d.ts +1 -31
  35. package/dist/module/notification/service/otp.service.d.ts +1 -31
  36. package/dist/module/notification/service/otp.service.js +1 -0
  37. package/dist/module/notification/service/otp.service.js.map +1 -1
  38. package/dist/module/user/controller/login.controller.js +2 -1
  39. package/dist/module/user/controller/login.controller.js.map +1 -1
  40. package/dist/module/user/service/login.service.d.ts +3 -57
  41. package/dist/module/user/service/login.service.js +12 -2
  42. package/dist/module/user/service/login.service.js.map +1 -1
  43. package/dist/module/user/service/user.service.js +1 -1
  44. package/dist/module/user/service/user.service.js.map +1 -1
  45. package/dist/module/workflow/repository/action.repository.js +1 -0
  46. package/dist/module/workflow/repository/action.repository.js.map +1 -1
  47. package/dist/module/workflow/service/workflow-meta.service.js +1 -1
  48. package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
  49. package/dist/module/workflow-automation/service/schedule-handler.service.d.ts +11 -5
  50. package/dist/module/workflow-automation/service/schedule-handler.service.js +50 -18
  51. package/dist/module/workflow-automation/service/schedule-handler.service.js.map +1 -1
  52. package/dist/module/workflow-automation/service/workflow-automation-engine.service.d.ts +4 -3
  53. package/dist/module/workflow-automation/service/workflow-automation-engine.service.js +12 -4
  54. package/dist/module/workflow-automation/service/workflow-automation-engine.service.js.map +1 -1
  55. package/dist/module/workflow-automation/service/workflow-automation.service.js +4 -2
  56. package/dist/module/workflow-automation/service/workflow-automation.service.js.map +1 -1
  57. package/dist/module/workflow-automation/workflow-automation.module.js +6 -0
  58. package/dist/module/workflow-automation/workflow-automation.module.js.map +1 -1
  59. package/dist/module/workflow-schedule/service/workflow-schedule.service.js +1 -1
  60. package/dist/module/workflow-schedule/service/workflow-schedule.service.js.map +1 -1
  61. package/dist/tsconfig.build.tsbuildinfo +1 -1
  62. package/package.json +1 -1
  63. package/src/module/entity_json/controller/entity_json.controller.ts +14 -14
  64. package/src/module/entity_json/entity/entityJson.entity.ts +39 -0
  65. package/src/module/entity_json/entity_json.module.ts +5 -2
  66. package/src/module/entity_json/service/entityJson.repository.ts +37 -0
  67. package/src/module/entity_json/service/entity_json.service.ts +109 -140
  68. package/src/module/filter/service/filter.service.ts +109 -16
  69. package/src/module/linked_attributes/controller/linked_attributes.controller.ts +25 -1
  70. package/src/module/linked_attributes/entity/linked_attribute.entity.ts +3 -0
  71. package/src/module/linked_attributes/service/linked_attributes.service.ts +81 -1
  72. package/src/module/listmaster/service/list-master.service.ts +27 -18
  73. package/src/module/meta/controller/attribute-master.controller.ts +11 -13
  74. package/src/module/meta/entity/attribute-master.entity.ts +3 -0
  75. package/src/module/notification/service/otp.service.ts +1 -0
  76. package/src/module/user/controller/login.controller.ts +2 -1
  77. package/src/module/user/service/login.service.ts +25 -3
  78. package/src/module/user/service/user.service.ts +4 -1
  79. package/src/module/workflow/repository/action.repository.ts +1 -0
  80. package/src/module/workflow/service/workflow-meta.service.ts +1 -1
  81. package/src/module/workflow-automation/service/schedule-handler.service.ts +45 -26
  82. package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +16 -6
  83. package/src/module/workflow-automation/service/workflow-automation.service.ts +10 -3
  84. package/src/module/workflow-automation/workflow-automation.module.ts +7 -0
  85. package/src/module/workflow-schedule/service/workflow-schedule.service.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "5.0.28",
3
+ "version": "5.0.30",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -29,19 +29,19 @@ export class EntityJSONController {
29
29
  );
30
30
  }
31
31
 
32
- // @Post('/update-json/:entityId')
33
- // @UseGuards(JwtAuthGuard)
34
- // async updateEntityJson(
35
- // @Param('entityId') entityId: string,
36
- // @Query('entityType') entityType: string,
37
- // @Req() req: Request & { user: any },
38
- // ) {
39
- // const loggedInUser = req.user?.userData;
32
+ @Post('/update-json/:entityId')
33
+ @UseGuards(JwtAuthGuard)
34
+ async updateEntityJson(
35
+ @Param('entityId') entityId: string,
36
+ @Query('entityType') entityType: string,
37
+ @Req() req: Request & { user: any },
38
+ ) {
39
+ const loggedInUser = req.user?.userData;
40
40
 
41
- // return this.entityJSONService.updateEntityJSON(
42
- // entityType,
43
- // Number(entityId),
44
- // loggedInUser,
45
- // );
46
- // }
41
+ return this.entityJSONService.updateEntityJSON(
42
+ entityType,
43
+ Number(entityId),
44
+ loggedInUser,
45
+ );
46
+ }
47
47
  }
@@ -0,0 +1,39 @@
1
+ import {
2
+ Entity,
3
+ PrimaryGeneratedColumn,
4
+ Column,
5
+ CreateDateColumn,
6
+ UpdateDateColumn,
7
+ Unique,
8
+ Index,
9
+ } from 'typeorm';
10
+
11
+ @Entity('frm_entity_json')
12
+ @Unique(['entity_type', 'entity_id'])
13
+ export class EntityJson {
14
+ @PrimaryGeneratedColumn()
15
+ id: number;
16
+
17
+ @Index()
18
+ @Column({ type: 'varchar', length: 100 })
19
+ entity_type: string;
20
+
21
+ @Index()
22
+ @Column({ type: 'int' })
23
+ entity_id: number;
24
+
25
+ @Column({ type: 'json', nullable: false })
26
+ json_data: Record<string, any>;
27
+
28
+ @Column({ type: 'int', nullable: true })
29
+ created_by: number;
30
+
31
+ @Column({ type: 'int', nullable: true })
32
+ updated_by: number;
33
+
34
+ @CreateDateColumn({ type: 'timestamp', nullable: true })
35
+ created_at: Date;
36
+
37
+ @UpdateDateColumn({ type: 'timestamp', nullable: true })
38
+ updated_at: Date;
39
+ }
@@ -5,11 +5,14 @@ import { EntityJSONService } from './service/entity_json.service';
5
5
  import { EntityJSONController } from './controller/entity_json.controller';
6
6
  import { FilterModule } from '../filter/filter.module';
7
7
  import { UtilsModule } from 'src/utils/utils.module';
8
+ import { EntityJson } from './entity/entityJson.entity';
9
+ import { EntityJSONRepository } from './service/entityJson.repository';
10
+
8
11
 
9
12
  @Module({
10
- imports: [EntityModule, TypeOrmModule.forFeature([]),FilterModule,UtilsModule],
13
+ imports: [EntityModule, TypeOrmModule.forFeature([EntityJson]),FilterModule,UtilsModule],
11
14
  controllers: [EntityJSONController],
12
- providers: [EntityJSONService],
15
+ providers: [EntityJSONService,EntityJSONRepository],
13
16
  exports: [],
14
17
  })
15
18
  export class EntityJSONModule {}
@@ -0,0 +1,37 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { InjectRepository } from "@nestjs/typeorm";
3
+ import { Repository } from "typeorm";
4
+ import { EntityJson } from "../entity/entityJson.entity";
5
+ import { create } from "domain";
6
+
7
+
8
+ @Injectable()
9
+ export class EntityJSONRepository {
10
+ constructor(
11
+ @InjectRepository(EntityJson)
12
+ private readonly entityJSONRepository: Repository<EntityJson>,
13
+ ) {}
14
+
15
+ async create(flatJson: Partial<EntityJson>) {
16
+ const { entity_type, entity_id } = flatJson;
17
+
18
+ // Step 1 — check if exists by unique keys
19
+ const existing = await this.entityJSONRepository.findOne({
20
+ where: { entity_type, entity_id },
21
+ });
22
+
23
+ if (existing) {
24
+ // Step 2 — normal update (no merge)
25
+ await this.entityJSONRepository.update(existing.id, flatJson);
26
+
27
+ // Optionally return updated row (common practice)
28
+ return this.entityJSONRepository.findOne({
29
+ where: { id: existing.id },
30
+ });
31
+ }
32
+
33
+ // Step 3 — insert new
34
+ const created = this.entityJSONRepository.create(flatJson);
35
+ return this.entityJSONRepository.save(created);
36
+ }
37
+ }
@@ -1,17 +1,20 @@
1
1
  import { Injectable } from '@nestjs/common';
2
2
  import { FilterService } from 'src/module/filter/service/filter.service';
3
+ import { LinkedAttributes } from 'src/module/linked_attributes/entity/linked_attribute.entity';
3
4
  import { AttributeMaster } from 'src/module/meta/entity/attribute-master.entity';
4
5
  import { EntityRelation } from 'src/module/meta/entity/entity-relation.entity';
5
6
  import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service';
6
7
  import { LoggingService } from 'src/utils/service/loggingUtil.service';
7
8
  import { DataSource } from 'typeorm';
9
+ import { EntityJSONRepository } from './entityJson.repository';
8
10
 
9
11
  @Injectable()
10
12
  export class EntityJSONService extends EntityServiceImpl {
11
13
  constructor(
12
14
  private readonly dataSource: DataSource,
13
15
  private readonly filterService: FilterService,
14
- private readonly loggerService: LoggingService, // <-- inject logging service
16
+ private readonly loggerService: LoggingService,
17
+ private readonly EntityJSONRepository:EntityJSONRepository
15
18
  ) {
16
19
  super();
17
20
  }
@@ -19,30 +22,21 @@ export class EntityJSONService extends EntityServiceImpl {
19
22
  async getAttributeForFlatJSON(
20
23
  entityType: string,
21
24
  loggedInUser: any,
22
- flag?: 'flat_json' | 'dropdown',
25
+ flag?: 'flat_json' | 'dropdown' | 'all',
23
26
  ) {
24
27
  const orgId = loggedInUser.organization_id;
25
- await this.loggerService.log(
26
- 'info',
27
- 'EntityJSONService',
28
- 'getAttributeForFlatJSON',
29
- `Loading attributes for entity: ${entityType}, org: ${orgId}`,
30
- );
28
+
29
+ await this.loggerService.log('info', 'EntityJSONService', 'getAttributeForFlatJSON', `Loading attributes for entity: ${entityType}, org: ${orgId}`);
31
30
 
32
31
  const mainAttributes = await this.dataSource
33
32
  .getRepository(AttributeMaster)
34
33
  .createQueryBuilder('attr')
35
- .select(['attr.id', 'attr.name', 'attr.attribute_key'])
34
+ .select(['attr.id', 'attr.name', 'attr.flat_json_key', 'attr.attribute_key'])
36
35
  .where('attr.mapped_entity_type = :entityType', { entityType })
37
36
  .andWhere('attr.organization_id = :orgId', { orgId })
38
37
  .getMany();
39
38
 
40
- await this.loggerService.log(
41
- 'debug',
42
- 'EntityJSONService',
43
- 'getAttributeForFlatJSON',
44
- `Loaded ${mainAttributes.length} main attributes`,
45
- );
39
+ await this.loggerService.log('debug', 'EntityJSONService', 'getAttributeForFlatJSON', `Loaded ${mainAttributes.length} main attributes`);
46
40
 
47
41
  const relatedEntityTypes = await this.dataSource
48
42
  .getRepository(EntityRelation)
@@ -54,31 +48,23 @@ export class EntityJSONService extends EntityServiceImpl {
54
48
  .getRawMany();
55
49
 
56
50
  const relatedTypesList = relatedEntityTypes.map(x => x.rel_target_entity_type);
57
- await this.loggerService.log(
58
- 'debug',
59
- 'EntityJSONService',
60
- 'getAttributeForFlatJSON',
61
- `Found ${relatedTypesList.length} ONE-TO-ONE related entity types`,
62
- );
51
+
52
+ await this.loggerService.log('debug', 'EntityJSONService', 'getAttributeForFlatJSON', `Found ${relatedTypesList.length} ONE-TO-ONE related entity types`);
63
53
 
64
54
  const relatedAttributes = relatedTypesList.length
65
55
  ? await this.dataSource
66
56
  .getRepository(AttributeMaster)
67
57
  .createQueryBuilder('attr')
68
- .select(['attr.id', 'attr.name', 'attr.attribute_key', 'attr.mapped_entity_type'])
58
+ .select(['attr.id', 'attr.name', 'attr.flat_json_key', 'attr.mapped_entity_type', 'attr.attribute_key'])
69
59
  .where('attr.mapped_entity_type IN (:...types)', { types: relatedTypesList })
70
60
  .andWhere('attr.organization_id = :orgId', { orgId })
71
61
  .getMany()
72
62
  : [];
73
- await this.loggerService.log(
74
- 'debug',
75
- 'EntityJSONService',
76
- 'getAttributeForFlatJSON',
77
- `Loaded ${relatedAttributes.length} related attributes`,
78
- );
63
+
64
+ await this.loggerService.log('debug', 'EntityJSONService', 'getAttributeForFlatJSON', `Loaded ${relatedAttributes.length} related attributes`);
79
65
 
80
66
  const linkedAttributes = await this.dataSource
81
- .getRepository('frm_linked_attribute')
67
+ .getRepository(LinkedAttributes)
82
68
  .createQueryBuilder('fla')
83
69
  .innerJoin(
84
70
  AttributeMaster,
@@ -86,68 +72,66 @@ export class EntityJSONService extends EntityServiceImpl {
86
72
  'fla.applicable_entity_type = attr.mapped_entity_type AND fla.applicable_attribute_key = attr.attribute_key',
87
73
  )
88
74
  .select([
89
- 'fla.applicable_entity_type',
90
- 'attr.id',
91
- 'attr.name',
92
- 'attr.attribute_key',
75
+ 'fla.applicable_entity_type AS applicable_entity_type',
76
+ 'fla.applicable_attribute_key AS applicable_attribute_key',
77
+ 'fla.attribute_key AS target_attribute_key',
78
+ 'fla.saved_filter_code AS saved_filter_code',
79
+ 'attr.name AS name',
80
+ 'attr.id AS id',
93
81
  ])
94
82
  .where('attr.organization_id = :orgId', { orgId })
95
83
  .getRawMany();
96
- await this.loggerService.log(
97
- 'debug',
98
- 'EntityJSONService',
99
- 'getAttributeForFlatJSON',
100
- `Loaded ${linkedAttributes.length} linked attributes`,
101
- );
102
-
103
- if (flag === 'flat_json') {
84
+
85
+ await this.loggerService.log('debug', 'EntityJSONService', 'getAttributeForFlatJSON', `Loaded ${linkedAttributes.length} linked attributes`);
86
+
87
+ if (flag === 'flat_json' || flag === 'all') {
104
88
  const result: Record<string, null> = {};
105
- mainAttributes.forEach(attr => { if (attr.attribute_key) result[attr.attribute_key] = null; });
106
- relatedAttributes.forEach(attr => { if (attr.attribute_key) result[attr.attribute_key] = null; });
107
- linkedAttributes.forEach(link => { if (link.applicable_attribute_key) result[link.applicable_attribute_key] = null; });
89
+ mainAttributes.forEach(attr => { if (attr.flat_json_key) result[attr.flat_json_key] = null; });
90
+ relatedAttributes.forEach(attr => { if (attr.flat_json_key) result[attr.flat_json_key] = null; });
91
+ linkedAttributes.forEach(link => { if (link.target_attribute_key) result[link.target_attribute_key] = null; });
92
+
93
+ if (flag === 'all') {
94
+ return { flat_json: result, attributes: { mainAttributes, relatedAttributes, linkedAttributes } };
95
+ }
96
+
108
97
  return result;
109
98
  }
110
99
 
111
100
  const dropdown: any[] = [];
112
- dropdown.push(...mainAttributes.map(a => ({ label: a.name, value: a.attribute_key })));
113
- dropdown.push(...relatedAttributes.map(a => ({ label: a.name, value: a.attribute_key })));
114
- dropdown.push({
115
- linked_attributes: linkedAttributes.map(a => ({ label: a.attr_name, value: a.attr_attribute_key })),
116
- });
101
+ dropdown.push(...mainAttributes.map(a => ({ label: a.name, value: a.flat_json_key })));
102
+ dropdown.push(...relatedAttributes.map(a => ({ label: a.name, value: a.flat_json_key })));
103
+ if (linkedAttributes.length > 0) {
104
+ dropdown.push(...linkedAttributes.map(a => ({ label: a.name, value: a.attribute_key })));
105
+ }
106
+
117
107
  return dropdown;
118
108
  }
119
109
 
120
- async updateEntityJSON(
121
- entityType: string,
122
- entityId: number,
123
- loggedInUser,
124
- ) {
125
- await this.loggerService.log(
126
- 'info',
127
- 'EntityJSONService',
128
- 'updateEntityJSON',
129
- `Building flat JSON for entity: ${entityType}#${entityId}`,
130
- );
131
-
132
- const flatJson = await this.getAttributeForFlatJSON(entityType, loggedInUser, 'flat_json');
133
- if (!flatJson) {
134
- await this.loggerService.log(
135
- 'error',
136
- 'EntityJSONService',
137
- 'updateEntityJSON',
138
- `Flat JSON template not found for entity: ${entityType}`,
139
- );
140
- throw new Error(`Flat JSON template not found for ${entityType}`);
110
+ async updateEntityJSON(entityType: string, entityId: number, loggedInUser) {
111
+ await this.loggerService.log('info', 'EntityJSONService', 'updateEntityJSON', `Building flat JSON for entity: ${entityType}#${entityId}`);
112
+
113
+ const response = await this.getAttributeForFlatJSON(entityType, loggedInUser, 'all');
114
+
115
+ if (!response || !('flat_json' in response) || !('attributes' in response) || !response.attributes) {
116
+ await this.loggerService.log('error', 'EntityJSONService', 'updateEntityJSON', `getAttributeForFlatJSON() did not return expected structure`);
117
+ return null;
141
118
  }
142
119
 
120
+ const { flat_json: flatJson, attributes } = response;
121
+ if (!flatJson) return null;
122
+
123
+ const safeAttributes = {
124
+ mainAttributes: attributes.mainAttributes || [],
125
+ relatedAttributes: attributes.relatedAttributes || [],
126
+ linkedAttributes: attributes.linkedAttributes || [],
127
+ };
128
+
129
+ const attrMap: Record<string, string> = {};
130
+ const allAttrs = [...safeAttributes.mainAttributes, ...safeAttributes.relatedAttributes];
131
+ allAttrs.forEach(attr => { if (attr.attribute_key) attrMap[attr.attribute_key] = attr.flat_json_key || attr.attribute_key; });
132
+
143
133
  const mainData = await this.getResolvedEntityData(entityType, entityId, loggedInUser);
144
- this.mergeIntoFlatJson(flatJson, mainData);
145
- await this.loggerService.log(
146
- 'debug',
147
- 'EntityJSONService',
148
- 'updateEntityJSON',
149
- 'Merged main entity data into flat JSON',
150
- );
134
+ this.mergeEntityDataIntoFlatJson(flatJson, mainData, attrMap);
151
135
 
152
136
  const relations = await this.dataSource
153
137
  .getRepository('frm_entity_relation_data')
@@ -157,75 +141,59 @@ export class EntityJSONService extends EntityServiceImpl {
157
141
  .andWhere('erd.source_entity_id = :entityId', { entityId })
158
142
  .andWhere('erd.relation_type = :rt', { rt: 'ONE_TO_ONE' })
159
143
  .getRawMany();
160
- await this.loggerService.log(
161
- 'debug',
162
- 'EntityJSONService',
163
- 'updateEntityJSON',
164
- `Found ${relations.length} ONE-TO-ONE relations`,
165
- );
166
144
 
167
145
  for (const rel of relations) {
168
- const related = await this.getResolvedEntityData(rel.target_entity_type, rel.target_entity_id, loggedInUser);
169
- this.mergeIntoFlatJson(flatJson, related);
170
- await this.loggerService.log(
171
- 'debug',
172
- 'EntityJSONService',
173
- 'updateEntityJSON',
174
- `Merged related entity ${rel.target_entity_type}#${rel.target_entity_id}`,
175
- );
146
+ const relatedData = await this.getResolvedEntityData(rel.target_entity_type, rel.target_entity_id, loggedInUser);
147
+ this.mergeEntityDataIntoFlatJson(flatJson, relatedData, attrMap);
176
148
  }
177
149
 
178
- const linkedAttrs = await this.dataSource
179
- .getRepository('frm_linked_attributes_table')
180
- .createQueryBuilder('la')
181
- .where('la.entity_type = :entityType', { entityType })
182
- .getMany();
183
- await this.loggerService.log(
184
- 'debug',
185
- 'EntityJSONService',
186
- 'updateEntityJSON',
187
- `Found ${linkedAttrs.length} linked attributes`,
188
- );
189
-
190
- for (const la of linkedAttrs) {
191
- const mappingValue = flatJson[la.mapping_attribute];
192
- const result = await this.applyLinkedFilterUsingSavedFilter(
193
- la.child_entity_type,
194
- la.saved_filter_code,
195
- la.filter_attribute,
150
+ for (const linkAttr of safeAttributes.linkedAttributes) {
151
+ const childEntityType = linkAttr.applicable_entity_type;
152
+ const sourceKey = linkAttr.applicable_attribute_key;
153
+ const targetKey = linkAttr.target_attribute_key;
154
+
155
+ if (!childEntityType || !sourceKey || !targetKey) continue;
156
+
157
+ const mappingValue = mainData?.[sourceKey] ?? null;
158
+
159
+ const value = await this.applyLinkedFilterUsingSavedFilter(
160
+ childEntityType,
161
+ linkAttr.saved_filter_code,
162
+ sourceKey,
196
163
  mappingValue,
197
- la.target_attribute,
198
- loggedInUser
199
- );
200
- flatJson[la.target_attribute] = result;
201
- await this.loggerService.log(
202
- 'debug',
203
- 'EntityJSONService',
204
- 'updateEntityJSON',
205
- `Linked attribute ${la.target_attribute} set from child entity ${la.child_entity_type}`,
164
+ targetKey,
165
+ loggedInUser,
166
+ entityId,
206
167
  );
168
+
169
+ if (value !== null && value !== undefined) {
170
+ flatJson[targetKey] = value;
171
+ }
207
172
  }
208
173
 
209
- await this.dataSource.query(
210
- `INSERT INTO frm_entity_json (entity_type, entity_id, json_data, created_by)
211
- VALUES (?, ?, ?, ?)
212
- ON DUPLICATE KEY UPDATE json_data = VALUES(json_data), updated_by = VALUES(created_by)`,
213
- [entityType, entityId, JSON.stringify(flatJson), loggedInUser.id]
214
- );
215
- await this.loggerService.log(
216
- 'info',
217
- 'EntityJSONService',
218
- 'updateEntityJSON',
219
- `Flat JSON saved for entity: ${entityType}#${entityId}`,
220
- );
174
+ await this.loggerService.log('info', 'EntityJSONService', 'updateEntityJSON', `Saving flat JSON for entity: ${entityType}#${entityId}`);
175
+ let JsonData = {
176
+ entity_type: entityType,
177
+ entity_id: entityId,
178
+ json_data: flatJson,
179
+ created_by: loggedInUser.id,
180
+ }
181
+
182
+ await this.EntityJSONRepository.create(JsonData);
221
183
 
222
184
  return flatJson;
223
185
  }
224
186
 
225
- private mergeIntoFlatJson(flatJson, entityData) {
226
- for (const key of Object.keys(entityData)) {
227
- if (flatJson.hasOwnProperty(key)) {
228
- flatJson[key] = entityData[key];
187
+ private mergeEntityDataIntoFlatJson(flatJson: Record<string, any>, entityData: any | any[], attrMap: Record<string, string>) {
188
+ const records = Array.isArray(entityData) ? entityData : [entityData];
189
+
190
+ for (const record of records) {
191
+ if (!record || typeof record !== 'object') continue;
192
+ for (const key of Object.keys(record)) {
193
+ const flatKey = attrMap[key] || key;
194
+ if (flatJson.hasOwnProperty(flatKey)) {
195
+ flatJson[flatKey] = record[key];
196
+ }
229
197
  }
230
198
  }
231
199
  }
@@ -237,6 +205,7 @@ export class EntityJSONService extends EntityServiceImpl {
237
205
  mappingValue: any,
238
206
  targetAttribute: string,
239
207
  loggedInUser,
208
+ entity_id
240
209
  ) {
241
210
  if (!savedFilterCode && (mappingValue === null || mappingValue === undefined)) return null;
242
211
 
@@ -250,16 +219,16 @@ export class EntityJSONService extends EntityServiceImpl {
250
219
 
251
220
  if (mappingValue !== null && mappingValue !== undefined && mappingValue !== '') {
252
221
  dto.quickFilter = [
253
- {
254
- filter_attribute: childFilterAttribute,
255
- filter_operator: 'equal',
256
- filter_value: mappingValue,
257
- }
222
+ { filter_attribute: childFilterAttribute, filter_operator: 'equal', filter_value: mappingValue },
258
223
  ];
259
224
  }
260
225
 
226
+ dto.quickFilter = [
227
+ { filter_attribute: 'parent_id', filter_operator: 'equal', filter_value: [entity_id] },
228
+ ];
229
+
261
230
  const result = await this.filterService.applyFilter(dto);
262
231
  const rows = result?.data?.entity_list || [];
263
- return rows.length ? rows[0][targetAttribute] ?? null : null;
232
+ return rows.length ? (rows[0][childFilterAttribute] ?? null) : null;
264
233
  }
265
234
  }
@@ -885,13 +885,107 @@ export class FilterService {
885
885
  }
886
886
 
887
887
  private buildDateCondition(attr: string, op: string, val: any, key: string) {
888
+ const dateColumn = `DATE(e.${attr})`;
889
+ const monthColumn = `DATE_FORMAT(e.${attr}, '%Y-%m-01')`; // MySQL equivalent
890
+
891
+ const numVal = Number(val);
892
+
888
893
  switch (op) {
894
+ // ===== BASIC COMPARISONS =====
889
895
  case 'equal':
890
- return { query: `e.${attr} = :${key}`, params: { [key]: val } };
896
+ case 'is':
897
+ return {
898
+ query: `${dateColumn} = :${key}`,
899
+ params: { [key]: val },
900
+ };
901
+
891
902
  case 'before':
892
- return { query: `e.${attr} < :${key}`, params: { [key]: val } };
903
+ case 'is_before':
904
+ return {
905
+ query: `${dateColumn} < :${key}`,
906
+ params: { [key]: val },
907
+ };
908
+
893
909
  case 'after':
894
- return { query: `e.${attr} > :${key}`, params: { [key]: val } };
910
+ case 'is_after':
911
+ return {
912
+ query: `${dateColumn} > :${key}`,
913
+ params: { [key]: val },
914
+ };
915
+
916
+ case 'is_on_or_before':
917
+ return {
918
+ query: `${dateColumn} <= :${key}`,
919
+ params: { [key]: val },
920
+ };
921
+
922
+ case 'is_on_or_after':
923
+ return {
924
+ query: `${dateColumn} >= :${key}`,
925
+ params: { [key]: val },
926
+ };
927
+
928
+ // ===== MONTH COMPARISONS =====
929
+ case 'is_month_before':
930
+ if (!isNaN(numVal)) {
931
+ const target = moment()
932
+ .subtract(numVal, 'months')
933
+ .startOf('month')
934
+ .format('YYYY-MM-DD');
935
+ return {
936
+ query: `${monthColumn} < DATE_FORMAT(:${key}, '%Y-%m-01')`,
937
+ params: { [key]: target },
938
+ };
939
+ }
940
+ return {
941
+ query: `${monthColumn} < DATE_FORMAT(:${key}, '%Y-%m-01')`,
942
+ params: { [key]: val },
943
+ };
944
+
945
+ case 'is_month_after':
946
+ if (!isNaN(numVal)) {
947
+ const target = moment()
948
+ .add(numVal, 'months')
949
+ .startOf('month')
950
+ .format('YYYY-MM-DD');
951
+ return {
952
+ query: `${monthColumn} > DATE_FORMAT(:${key}, '%Y-%m-01')`,
953
+ params: { [key]: target },
954
+ };
955
+ }
956
+ return {
957
+ query: `${monthColumn} > DATE_FORMAT(:${key}, '%Y-%m-01')`,
958
+ params: { [key]: val },
959
+ };
960
+
961
+ // ===== DAY BEFORE / AFTER =====
962
+ case 'is_day_before':
963
+ if (isNaN(numVal))
964
+ throw new BadRequestException(
965
+ 'Value must be a number for is_day_before',
966
+ );
967
+
968
+ const beforeDate = moment()
969
+ .subtract(numVal, 'days')
970
+ .format('YYYY-MM-DD');
971
+ return {
972
+ query: `${dateColumn} < :${key}`,
973
+ params: { [key]: beforeDate },
974
+ };
975
+
976
+ case 'is_day_after':
977
+ if (isNaN(numVal))
978
+ throw new BadRequestException(
979
+ 'Value must be a number for is_day_after',
980
+ );
981
+
982
+ const afterDate = moment().add(numVal, 'days').format('YYYY-MM-DD');
983
+ return {
984
+ query: `${dateColumn} > :${key}`,
985
+ params: { [key]: afterDate },
986
+ };
987
+
988
+ // ===== BETWEEN =====
895
989
  case 'between': {
896
990
  if (typeof val === 'string') {
897
991
  val = val.split(',').map((v) => v.trim());
@@ -903,12 +997,12 @@ export class FilterService {
903
997
  val[0] === '' ||
904
998
  val[1] === ''
905
999
  ) {
906
- // throw new BadRequestException(`Invalid value for in_between: ${val}`);
907
- console.log(`Invalid value for in_between: ${val}`);
1000
+ console.log(`Invalid value for between: ${val}`);
908
1001
  return null;
909
1002
  }
1003
+
910
1004
  return {
911
- query: `e.${attr} BETWEEN :${key}_start AND :${key}_end`,
1005
+ query: `${dateColumn} BETWEEN :${key}_start AND :${key}_end`,
912
1006
  params: {
913
1007
  [`${key}_start`]: val[0],
914
1008
  [`${key}_end`]: val[1],
@@ -916,30 +1010,29 @@ export class FilterService {
916
1010
  };
917
1011
  }
918
1012
 
1013
+ // ===== TODAY =====
919
1014
  case 'today': {
920
- const today = new Date().toISOString().split('T')[0]; // 'YYYY-MM-DD'
921
-
1015
+ const today = moment().format('YYYY-MM-DD');
922
1016
  return {
923
- query: `DATE(e.${attr}) = :today`,
924
- params: {
925
- today,
926
- },
1017
+ query: `${dateColumn} = :today`,
1018
+ params: { today },
927
1019
  };
928
1020
  }
929
1021
 
930
- case 'empty': {
1022
+ // ===== EMPTY =====
1023
+ case 'empty':
1024
+ case 'is_empty':
931
1025
  return {
932
1026
  query: `e.${attr} IS NULL`,
933
1027
  params: {},
934
1028
  };
935
- }
936
1029
 
937
- case 'not_empty': {
1030
+ case 'not_empty':
938
1031
  return {
939
1032
  query: `e.${attr} IS NOT NULL`,
940
1033
  params: {},
941
1034
  };
942
- }
1035
+
943
1036
  default:
944
1037
  throw new BadRequestException(`Unsupported operator for date: ${op}`);
945
1038
  }