rez_core 4.0.188 → 4.0.190
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/module/entity_json/entity_json.module.js +3 -1
- package/dist/module/entity_json/entity_json.module.js.map +1 -1
- package/dist/module/entity_json/service/entity_json.service.d.ts +8 -1
- package/dist/module/entity_json/service/entity_json.service.js +98 -45
- package/dist/module/entity_json/service/entity_json.service.js.map +1 -1
- package/dist/module/workflow-automation/workflow-automation.module.js +1 -1
- package/dist/module/workflow-automation/workflow-automation.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/entity_json/entity_json.module.ts +3 -1
- package/src/module/entity_json/service/entity_json.service.ts +188 -85
- package/src/module/workflow-automation/workflow-automation.module.ts +2 -2
package/package.json
CHANGED
|
@@ -3,9 +3,11 @@ import { EntityModule } from '../meta/entity.module';
|
|
|
3
3
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
4
4
|
import { EntityJSONService } from './service/entity_json.service';
|
|
5
5
|
import { EntityJSONController } from './controller/entity_json.controller';
|
|
6
|
+
import { FilterModule } from '../filter/filter.module';
|
|
7
|
+
import { UtilsModule } from 'src/utils/utils.module';
|
|
6
8
|
|
|
7
9
|
@Module({
|
|
8
|
-
imports: [EntityModule, TypeOrmModule.forFeature([])],
|
|
10
|
+
imports: [EntityModule, TypeOrmModule.forFeature([]),FilterModule,UtilsModule],
|
|
9
11
|
controllers: [EntityJSONController],
|
|
10
12
|
providers: [EntityJSONService],
|
|
11
13
|
exports: [],
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { FilterService } from 'src/module/filter/service/filter.service';
|
|
2
3
|
import { AttributeMaster } from 'src/module/meta/entity/attribute-master.entity';
|
|
3
4
|
import { EntityRelation } from 'src/module/meta/entity/entity-relation.entity';
|
|
4
5
|
import { EntityServiceImpl } from 'src/module/meta/service/entity-service-impl.service';
|
|
6
|
+
import { LoggingService } from 'src/utils/service/loggingUtil.service';
|
|
5
7
|
import { DataSource } from 'typeorm';
|
|
6
8
|
|
|
7
9
|
@Injectable()
|
|
8
10
|
export class EntityJSONService extends EntityServiceImpl {
|
|
9
|
-
constructor(
|
|
11
|
+
constructor(
|
|
12
|
+
private readonly dataSource: DataSource,
|
|
13
|
+
private readonly filterService: FilterService,
|
|
14
|
+
private readonly loggerService: LoggingService, // <-- inject logging service
|
|
15
|
+
) {
|
|
10
16
|
super();
|
|
11
17
|
}
|
|
12
18
|
|
|
@@ -16,10 +22,13 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
16
22
|
flag?: 'flat_json' | 'dropdown',
|
|
17
23
|
) {
|
|
18
24
|
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
|
+
);
|
|
19
31
|
|
|
20
|
-
// --------------------------------------------
|
|
21
|
-
// 1. Load Main Entity Attributes
|
|
22
|
-
// --------------------------------------------
|
|
23
32
|
const mainAttributes = await this.dataSource
|
|
24
33
|
.getRepository(AttributeMaster)
|
|
25
34
|
.createQueryBuilder('attr')
|
|
@@ -28,47 +37,46 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
28
37
|
.andWhere('attr.organization_id = :orgId', { orgId })
|
|
29
38
|
.getMany();
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
await this.loggerService.log(
|
|
41
|
+
'debug',
|
|
42
|
+
'EntityJSONService',
|
|
43
|
+
'getAttributeForFlatJSON',
|
|
44
|
+
`Loaded ${mainAttributes.length} main attributes`,
|
|
45
|
+
);
|
|
46
|
+
|
|
34
47
|
const relatedEntityTypes = await this.dataSource
|
|
35
48
|
.getRepository(EntityRelation)
|
|
36
49
|
.createQueryBuilder('rel')
|
|
37
50
|
.select(['rel.target_entity_type'])
|
|
38
51
|
.where('rel.source_entity_type = :entityType', { entityType })
|
|
39
52
|
.andWhere('rel.organization_id = :orgId', { orgId })
|
|
40
|
-
.andWhere('rel.relation_type = :relationType', {
|
|
41
|
-
relationType: 'ONE_TO_ONE',
|
|
42
|
-
})
|
|
53
|
+
.andWhere('rel.relation_type = :relationType', { relationType: 'ONE_TO_ONE' })
|
|
43
54
|
.getRawMany();
|
|
44
55
|
|
|
45
|
-
const relatedTypesList = relatedEntityTypes.map(
|
|
46
|
-
|
|
56
|
+
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`,
|
|
47
62
|
);
|
|
48
63
|
|
|
49
|
-
// --------------------------------------------
|
|
50
|
-
// 3. Fetch All Related Attributes
|
|
51
|
-
// --------------------------------------------
|
|
52
64
|
const relatedAttributes = relatedTypesList.length
|
|
53
65
|
? await this.dataSource
|
|
54
66
|
.getRepository(AttributeMaster)
|
|
55
67
|
.createQueryBuilder('attr')
|
|
56
|
-
.select([
|
|
57
|
-
|
|
58
|
-
'attr.name',
|
|
59
|
-
'attr.attribute_key',
|
|
60
|
-
'attr.mapped_entity_type',
|
|
61
|
-
])
|
|
62
|
-
.where('attr.mapped_entity_type IN (:...types)', {
|
|
63
|
-
types: relatedTypesList,
|
|
64
|
-
})
|
|
68
|
+
.select(['attr.id', 'attr.name', 'attr.attribute_key', 'attr.mapped_entity_type'])
|
|
69
|
+
.where('attr.mapped_entity_type IN (:...types)', { types: relatedTypesList })
|
|
65
70
|
.andWhere('attr.organization_id = :orgId', { orgId })
|
|
66
71
|
.getMany()
|
|
67
72
|
: [];
|
|
73
|
+
await this.loggerService.log(
|
|
74
|
+
'debug',
|
|
75
|
+
'EntityJSONService',
|
|
76
|
+
'getAttributeForFlatJSON',
|
|
77
|
+
`Loaded ${relatedAttributes.length} related attributes`,
|
|
78
|
+
);
|
|
68
79
|
|
|
69
|
-
// --------------------------------------------
|
|
70
|
-
// 4. Fetch Linked Attributes
|
|
71
|
-
// --------------------------------------------
|
|
72
80
|
const linkedAttributes = await this.dataSource
|
|
73
81
|
.getRepository('frm_linked_attribute')
|
|
74
82
|
.createQueryBuilder('fla')
|
|
@@ -85,78 +93,173 @@ export class EntityJSONService extends EntityServiceImpl {
|
|
|
85
93
|
])
|
|
86
94
|
.where('attr.organization_id = :orgId', { orgId })
|
|
87
95
|
.getRawMany();
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// MODE 1: flat_json -> return objects grouped by entity_type
|
|
95
|
-
// ============================================================
|
|
96
|
+
await this.loggerService.log(
|
|
97
|
+
'debug',
|
|
98
|
+
'EntityJSONService',
|
|
99
|
+
'getAttributeForFlatJSON',
|
|
100
|
+
`Loaded ${linkedAttributes.length} linked attributes`,
|
|
101
|
+
);
|
|
96
102
|
|
|
97
103
|
if (flag === 'flat_json') {
|
|
98
104
|
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; });
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
99
110
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
for (const type of relatedTypesList) {
|
|
109
|
-
const attrs = relatedAttributes.filter(
|
|
110
|
-
(a) => a.mapped_entity_type === type,
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
attrs.forEach((attr) => {
|
|
114
|
-
if (attr.attribute_key) {
|
|
115
|
-
result[attr.attribute_key] = null;
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
111
|
+
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
|
+
});
|
|
117
|
+
return dropdown;
|
|
118
|
+
}
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
);
|
|
126
131
|
|
|
127
|
-
|
|
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}`);
|
|
128
141
|
}
|
|
129
142
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
143
|
+
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
|
+
);
|
|
151
|
+
|
|
152
|
+
const relations = await this.dataSource
|
|
153
|
+
.getRepository('frm_entity_relation_data')
|
|
154
|
+
.createQueryBuilder('erd')
|
|
155
|
+
.select(['erd.target_entity_id AS target_entity_id', 'erd.target_entity_type AS target_entity_type'])
|
|
156
|
+
.where('erd.source_entity_type = :entityType', { entityType })
|
|
157
|
+
.andWhere('erd.source_entity_id = :entityId', { entityId })
|
|
158
|
+
.andWhere('erd.relation_type = :rt', { rt: 'ONE_TO_ONE' })
|
|
159
|
+
.getRawMany();
|
|
160
|
+
await this.loggerService.log(
|
|
161
|
+
'debug',
|
|
162
|
+
'EntityJSONService',
|
|
163
|
+
'updateEntityJSON',
|
|
164
|
+
`Found ${relations.length} ONE-TO-ONE relations`,
|
|
165
|
+
);
|
|
133
166
|
|
|
134
|
-
const
|
|
167
|
+
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
|
+
);
|
|
176
|
+
}
|
|
135
177
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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`,
|
|
142
188
|
);
|
|
143
189
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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,
|
|
196
|
+
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}`,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
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}`,
|
|
150
220
|
);
|
|
151
221
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
linked_attributes: linkedAttributes.map((a) => ({
|
|
155
|
-
label: a.attr_name,
|
|
156
|
-
value: a.attr_attribute_key,
|
|
157
|
-
})),
|
|
158
|
-
});
|
|
222
|
+
return flatJson;
|
|
223
|
+
}
|
|
159
224
|
|
|
160
|
-
|
|
225
|
+
private mergeIntoFlatJson(flatJson, entityData) {
|
|
226
|
+
for (const key of Object.keys(entityData)) {
|
|
227
|
+
if (flatJson.hasOwnProperty(key)) {
|
|
228
|
+
flatJson[key] = entityData[key];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private async applyLinkedFilterUsingSavedFilter(
|
|
234
|
+
childEntityType: string,
|
|
235
|
+
savedFilterCode: string,
|
|
236
|
+
childFilterAttribute: string,
|
|
237
|
+
mappingValue: any,
|
|
238
|
+
targetAttribute: string,
|
|
239
|
+
loggedInUser,
|
|
240
|
+
) {
|
|
241
|
+
if (!savedFilterCode && (mappingValue === null || mappingValue === undefined)) return null;
|
|
242
|
+
|
|
243
|
+
const dto: any = {
|
|
244
|
+
entity_type: childEntityType,
|
|
245
|
+
loggedInUser,
|
|
246
|
+
savedFilterCode,
|
|
247
|
+
page: 1,
|
|
248
|
+
size: 1,
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
if (mappingValue !== null && mappingValue !== undefined && mappingValue !== '') {
|
|
252
|
+
dto.quickFilter = [
|
|
253
|
+
{
|
|
254
|
+
filter_attribute: childFilterAttribute,
|
|
255
|
+
filter_operator: 'equal',
|
|
256
|
+
filter_value: mappingValue,
|
|
257
|
+
}
|
|
258
|
+
];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const result = await this.filterService.applyFilter(dto);
|
|
262
|
+
const rows = result?.data?.entity_list || [];
|
|
263
|
+
return rows.length ? rows[0][targetAttribute] ?? null : null;
|
|
161
264
|
}
|
|
162
265
|
}
|
|
@@ -24,8 +24,8 @@ import { WorkflowScheduleModule } from '../workflow-schedule/workflow-schedule.m
|
|
|
24
24
|
]),
|
|
25
25
|
FilterModule,
|
|
26
26
|
forwardRef(() => EntityModule),
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
forwardRef(() => WorkflowScheduleModule),
|
|
28
|
+
DiscoveryModule, // 👈 enables provider scanning
|
|
29
29
|
],
|
|
30
30
|
providers: [
|
|
31
31
|
WorkflowAutomationEngineService,
|