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.
- package/dist/module/entity_json/controller/entity_json.controller.d.ts +11 -1
- package/dist/module/entity_json/controller/entity_json.controller.js +14 -0
- package/dist/module/entity_json/controller/entity_json.controller.js.map +1 -1
- package/dist/module/entity_json/entity/entityJson.entity.d.ts +10 -0
- package/dist/module/entity_json/entity/entityJson.entity.js +55 -0
- package/dist/module/entity_json/entity/entityJson.entity.js.map +1 -0
- package/dist/module/entity_json/entity_json.module.js +4 -2
- package/dist/module/entity_json/entity_json.module.js.map +1 -1
- package/dist/module/entity_json/service/entityJson.repository.d.ts +7 -0
- package/dist/module/entity_json/service/entityJson.repository.js +45 -0
- package/dist/module/entity_json/service/entityJson.repository.js.map +1 -0
- package/dist/module/entity_json/service/entity_json.service.d.ts +14 -4
- package/dist/module/entity_json/service/entity_json.service.js +84 -57
- package/dist/module/entity_json/service/entity_json.service.js.map +1 -1
- package/dist/module/filter/service/filter.service.js +84 -14
- package/dist/module/filter/service/filter.service.js.map +1 -1
- package/dist/module/linked_attributes/controller/linked_attributes.controller.d.ts +2 -0
- package/dist/module/linked_attributes/controller/linked_attributes.controller.js +26 -0
- package/dist/module/linked_attributes/controller/linked_attributes.controller.js.map +1 -1
- package/dist/module/linked_attributes/entity/linked_attribute.entity.d.ts +1 -0
- package/dist/module/linked_attributes/entity/linked_attribute.entity.js +4 -0
- package/dist/module/linked_attributes/entity/linked_attribute.entity.js.map +1 -1
- package/dist/module/linked_attributes/service/linked_attributes.service.d.ts +6 -1
- package/dist/module/linked_attributes/service/linked_attributes.service.js +61 -2
- package/dist/module/linked_attributes/service/linked_attributes.service.js.map +1 -1
- package/dist/module/listmaster/service/list-master.service.js +4 -2
- package/dist/module/listmaster/service/list-master.service.js.map +1 -1
- package/dist/module/meta/controller/attribute-master.controller.d.ts +2 -3
- package/dist/module/meta/controller/attribute-master.controller.js +2 -12
- package/dist/module/meta/controller/attribute-master.controller.js.map +1 -1
- package/dist/module/meta/entity/attribute-master.entity.d.ts +1 -0
- package/dist/module/meta/entity/attribute-master.entity.js +4 -0
- package/dist/module/meta/entity/attribute-master.entity.js.map +1 -1
- package/dist/module/notification/controller/otp.controller.d.ts +1 -31
- package/dist/module/notification/service/otp.service.d.ts +1 -31
- package/dist/module/notification/service/otp.service.js +1 -0
- package/dist/module/notification/service/otp.service.js.map +1 -1
- package/dist/module/user/controller/login.controller.js +2 -1
- package/dist/module/user/controller/login.controller.js.map +1 -1
- package/dist/module/user/service/login.service.d.ts +3 -57
- package/dist/module/user/service/login.service.js +12 -2
- package/dist/module/user/service/login.service.js.map +1 -1
- package/dist/module/user/service/user.service.js +1 -1
- package/dist/module/user/service/user.service.js.map +1 -1
- package/dist/module/workflow/repository/action.repository.js +1 -0
- package/dist/module/workflow/repository/action.repository.js.map +1 -1
- package/dist/module/workflow/service/workflow-meta.service.js +1 -1
- package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
- package/dist/module/workflow-automation/service/schedule-handler.service.d.ts +11 -5
- package/dist/module/workflow-automation/service/schedule-handler.service.js +50 -18
- package/dist/module/workflow-automation/service/schedule-handler.service.js.map +1 -1
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.d.ts +4 -3
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.js +12 -4
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.js.map +1 -1
- package/dist/module/workflow-automation/service/workflow-automation.service.js +4 -2
- package/dist/module/workflow-automation/service/workflow-automation.service.js.map +1 -1
- package/dist/module/workflow-automation/workflow-automation.module.js +6 -0
- package/dist/module/workflow-automation/workflow-automation.module.js.map +1 -1
- package/dist/module/workflow-schedule/service/workflow-schedule.service.js +1 -1
- package/dist/module/workflow-schedule/service/workflow-schedule.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/entity_json/controller/entity_json.controller.ts +14 -14
- package/src/module/entity_json/entity/entityJson.entity.ts +39 -0
- package/src/module/entity_json/entity_json.module.ts +5 -2
- package/src/module/entity_json/service/entityJson.repository.ts +37 -0
- package/src/module/entity_json/service/entity_json.service.ts +109 -140
- package/src/module/filter/service/filter.service.ts +109 -16
- package/src/module/linked_attributes/controller/linked_attributes.controller.ts +25 -1
- package/src/module/linked_attributes/entity/linked_attribute.entity.ts +3 -0
- package/src/module/linked_attributes/service/linked_attributes.service.ts +81 -1
- package/src/module/listmaster/service/list-master.service.ts +27 -18
- package/src/module/meta/controller/attribute-master.controller.ts +11 -13
- package/src/module/meta/entity/attribute-master.entity.ts +3 -0
- package/src/module/notification/service/otp.service.ts +1 -0
- package/src/module/user/controller/login.controller.ts +2 -1
- package/src/module/user/service/login.service.ts +25 -3
- package/src/module/user/service/user.service.ts +4 -1
- package/src/module/workflow/repository/action.repository.ts +1 -0
- package/src/module/workflow/service/workflow-meta.service.ts +1 -1
- package/src/module/workflow-automation/service/schedule-handler.service.ts +45 -26
- package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +16 -6
- package/src/module/workflow-automation/service/workflow-automation.service.ts +10 -3
- package/src/module/workflow-automation/workflow-automation.module.ts +7 -0
- package/src/module/workflow-schedule/service/workflow-schedule.service.ts +1 -1
package/package.json
CHANGED
|
@@ -29,19 +29,19 @@ export class EntityJSONController {
|
|
|
29
29
|
);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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,
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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.
|
|
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
|
-
|
|
74
|
-
|
|
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(
|
|
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
|
-
'
|
|
91
|
-
'
|
|
92
|
-
'
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
106
|
-
relatedAttributes.forEach(attr => { if (attr.
|
|
107
|
-
linkedAttributes.forEach(link => { if (link.
|
|
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.
|
|
113
|
-
dropdown.push(...relatedAttributes.map(a => ({ label: a.name, value: a.
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
loggedInUser,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
'
|
|
127
|
-
|
|
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.
|
|
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
|
|
169
|
-
this.
|
|
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
|
|
179
|
-
.
|
|
180
|
-
.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
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.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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][
|
|
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
|
-
|
|
896
|
+
case 'is':
|
|
897
|
+
return {
|
|
898
|
+
query: `${dateColumn} = :${key}`,
|
|
899
|
+
params: { [key]: val },
|
|
900
|
+
};
|
|
901
|
+
|
|
891
902
|
case 'before':
|
|
892
|
-
|
|
903
|
+
case 'is_before':
|
|
904
|
+
return {
|
|
905
|
+
query: `${dateColumn} < :${key}`,
|
|
906
|
+
params: { [key]: val },
|
|
907
|
+
};
|
|
908
|
+
|
|
893
909
|
case 'after':
|
|
894
|
-
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
921
|
-
|
|
1015
|
+
const today = moment().format('YYYY-MM-DD');
|
|
922
1016
|
return {
|
|
923
|
-
query:
|
|
924
|
-
params: {
|
|
925
|
-
today,
|
|
926
|
-
},
|
|
1017
|
+
query: `${dateColumn} = :today`,
|
|
1018
|
+
params: { today },
|
|
927
1019
|
};
|
|
928
1020
|
}
|
|
929
1021
|
|
|
930
|
-
|
|
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
|
}
|