rez_core 2.2.263 → 3.1.0
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/filter/controller/filter.controller.d.ts +7 -0
- package/dist/module/filter/controller/filter.controller.js +1 -1
- package/dist/module/filter/controller/filter.controller.js.map +1 -1
- package/dist/module/filter/dto/filter-request.dto.d.ts +6 -2
- package/dist/module/filter/entity/saved-filter-detail.entity.d.ts +4 -0
- package/dist/module/filter/entity/saved-filter-detail.entity.js +16 -0
- package/dist/module/filter/entity/saved-filter-detail.entity.js.map +1 -1
- package/dist/module/filter/service/filter-evaluator.service.js +2 -5
- package/dist/module/filter/service/filter-evaluator.service.js.map +1 -1
- package/dist/module/filter/service/filter.service.d.ts +27 -5
- package/dist/module/filter/service/filter.service.js +71 -24
- package/dist/module/filter/service/filter.service.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 +9 -0
- package/dist/module/meta/entity/attribute-master.entity.js.map +1 -1
- package/dist/module/user/entity/role.entity.d.ts +2 -0
- package/dist/module/user/entity/role.entity.js +8 -0
- package/dist/module/user/entity/role.entity.js.map +1 -1
- package/dist/module/user/service/user.service.js.map +1 -1
- package/dist/module/workflow/controller/action-category.controller.d.ts +1 -0
- package/dist/module/workflow/controller/action-category.controller.js +12 -0
- package/dist/module/workflow/controller/action-category.controller.js.map +1 -1
- package/dist/module/workflow/repository/action-category.repository.d.ts +1 -0
- package/dist/module/workflow/repository/action-category.repository.js +17 -0
- package/dist/module/workflow/repository/action-category.repository.js.map +1 -1
- package/dist/module/workflow/service/action-category.service.d.ts +1 -0
- package/dist/module/workflow/service/action-category.service.js +3 -0
- package/dist/module/workflow/service/action-category.service.js.map +1 -1
- package/dist/module/workflow/service/task.service.d.ts +2 -0
- package/dist/module/workflow/service/task.service.js +31 -0
- package/dist/module/workflow/service/task.service.js.map +1 -1
- package/dist/module/workflow-automation/entity/workflow-automation-action.entity.d.ts +1 -1
- package/dist/module/workflow-automation/entity/workflow-automation-action.entity.js +1 -1
- package/dist/module/workflow-automation/entity/workflow-automation-action.entity.js.map +1 -1
- package/dist/module/workflow-automation/service/workflow-automation-engine.service.js +0 -1
- 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 -4
- package/dist/module/workflow-automation/service/workflow-automation.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/filter/controller/filter.controller.ts +1 -1
- package/src/module/filter/dto/filter-request.dto.ts +6 -2
- package/src/module/filter/entity/saved-filter-detail.entity.ts +13 -1
- package/src/module/filter/service/filter-evaluator.service.ts +7 -13
- package/src/module/filter/service/filter.service.ts +119 -37
- package/src/module/meta/entity/attribute-master.entity.ts +8 -0
- package/src/module/user/entity/role.entity.ts +6 -0
- package/src/module/user/service/user.service.ts +2 -2
- package/src/module/workflow/controller/action-category.controller.ts +7 -0
- package/src/module/workflow/repository/action-category.repository.ts +23 -0
- package/src/module/workflow/service/action-category.service.ts +4 -0
- package/src/module/workflow/service/task.service.ts +45 -0
- package/src/module/workflow-automation/entity/workflow-automation-action.entity.ts +1 -1
- package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +21 -14
- package/src/module/workflow-automation/service/workflow-automation.service.ts +4 -4
- package/.vscode/extensions.json +0 -5
package/package.json
CHANGED
|
@@ -2,9 +2,13 @@ import { UserData } from 'src/module/user/entity/user.entity';
|
|
|
2
2
|
|
|
3
3
|
// src/module/filter/dto/filter-request.dto.ts
|
|
4
4
|
export interface FilterCondition {
|
|
5
|
+
filter_entity_type: string; // main or sub-entity code (e.g. LEAD, CONTACT, ORG)
|
|
5
6
|
filter_attribute: string;
|
|
6
7
|
filter_operator: string;
|
|
7
|
-
filter_value?: string | number | boolean;
|
|
8
|
+
filter_value?: string | number | boolean | (string | number | boolean)[];
|
|
9
|
+
filter_attribute_name?: string; // NEW - main/sub entity type (e.g. LEAD, CONTACT, ORG)
|
|
10
|
+
filter_attribute_data_type?: string;
|
|
11
|
+
filter_entity_name?: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
export interface TabsConfig {
|
|
@@ -19,7 +23,7 @@ export interface SortConfig {
|
|
|
19
23
|
export interface FilterRequestDto {
|
|
20
24
|
entity_type: string;
|
|
21
25
|
quickFilter?: FilterCondition[];
|
|
22
|
-
savedFilterCode?: string;
|
|
26
|
+
savedFilterCode?: string | null ;
|
|
23
27
|
attributeFilter?: FilterCondition[];
|
|
24
28
|
sortby?: SortConfig[];
|
|
25
29
|
tabs?: TabsConfig;
|
|
@@ -10,7 +10,10 @@ export class SavedFilterDetail extends BaseEntity {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
@Column()
|
|
13
|
-
mapped_filter_code: string; //
|
|
13
|
+
mapped_filter_code: string; // links to SavedFilterMaster.code (manual, not FK)
|
|
14
|
+
|
|
15
|
+
@Column()
|
|
16
|
+
filter_entity_type: string; // NEW - main/sub entity type (e.g. LEAD, CONTACT, ORG)
|
|
14
17
|
|
|
15
18
|
@Column()
|
|
16
19
|
filter_attribute: string;
|
|
@@ -18,6 +21,15 @@ export class SavedFilterDetail extends BaseEntity {
|
|
|
18
21
|
@Column()
|
|
19
22
|
filter_operator: string;
|
|
20
23
|
|
|
24
|
+
@Column()
|
|
25
|
+
filter_attribute_name: string; // NEW - main/sub entity type (e.g. LEAD, CONTACT, ORG)
|
|
26
|
+
|
|
27
|
+
@Column()
|
|
28
|
+
filter_attribute_data_type: string;
|
|
29
|
+
|
|
30
|
+
@Column()
|
|
31
|
+
filter_entity_name: string;
|
|
32
|
+
|
|
21
33
|
@Column()
|
|
22
34
|
filter_value: string;
|
|
23
35
|
|
|
@@ -23,42 +23,38 @@ export class FilterEvaluatorService {
|
|
|
23
23
|
savedFilterCode: string,
|
|
24
24
|
): Promise<boolean> {
|
|
25
25
|
// Fetch trigger filter details
|
|
26
|
-
console.log(
|
|
26
|
+
console.log('IN FILTER EVALUATOR SERVICE');
|
|
27
27
|
const triggerFilters: SavedFilterDetail[] = await this.dataSource.query(
|
|
28
28
|
`SELECT *
|
|
29
29
|
FROM cr_saved_filter_detail
|
|
30
30
|
WHERE mapped_filter_code = ?`,
|
|
31
31
|
[savedFilterCode],
|
|
32
32
|
);
|
|
33
|
-
|
|
34
|
-
console.log(triggerFilters, 'triggerFilters');
|
|
35
33
|
|
|
36
34
|
// If no trigger filters defined, just return true (so criteria can run)
|
|
37
35
|
if (!triggerFilters || triggerFilters.length === 0) {
|
|
38
36
|
return true;
|
|
39
37
|
}
|
|
40
|
-
|
|
38
|
+
|
|
41
39
|
const oldState = oldEntity || {};
|
|
42
|
-
|
|
40
|
+
|
|
43
41
|
// Check each trigger attribute
|
|
44
42
|
for (const filter of triggerFilters) {
|
|
45
43
|
const attr = filter.filter_attribute;
|
|
46
44
|
const expectedValue = filter.filter_value;
|
|
47
|
-
|
|
45
|
+
|
|
48
46
|
const oldVal = oldState[attr];
|
|
49
47
|
const newVal = newEntity[attr];
|
|
50
|
-
|
|
51
|
-
console.log(oldVal, newVal, expectedValue, 'comparing values');
|
|
52
48
|
// If value changed and (no expected value defined OR matches expected)
|
|
53
49
|
if (oldVal !== newVal && (!expectedValue || newVal == expectedValue)) {
|
|
54
50
|
return true;
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
|
-
|
|
53
|
+
|
|
58
54
|
// No trigger attribute matched
|
|
59
55
|
return false;
|
|
60
56
|
}
|
|
61
|
-
|
|
57
|
+
|
|
62
58
|
/**
|
|
63
59
|
* Evaluate the criteria for an entity using the filter service
|
|
64
60
|
* @param entityType type of entity
|
|
@@ -83,9 +79,7 @@ export class FilterEvaluatorService {
|
|
|
83
79
|
loggedInUser: loggedInUser || { organization_id: null },
|
|
84
80
|
} as any;
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const result = await this.filterService.applyFilter(filterRequest);
|
|
82
|
+
const result = await this.filterService.applyFilterWrapper(filterRequest);
|
|
89
83
|
|
|
90
84
|
return result?.data?.entity_list?.length > 0;
|
|
91
85
|
}
|
|
@@ -4,7 +4,7 @@ import { EntityMasterService } from 'src/module/meta/service/entity-master.servi
|
|
|
4
4
|
import { EntityTableColumnService } from 'src/module/meta/service/entity-table-column.service';
|
|
5
5
|
import { EntityTableService } from 'src/module/meta/service/entity-table.service';
|
|
6
6
|
import { DataSource } from 'typeorm';
|
|
7
|
-
import { FilterRequestDto } from '../dto/filter-request.dto';
|
|
7
|
+
import { FilterCondition, FilterRequestDto } from '../dto/filter-request.dto';
|
|
8
8
|
import { SavedFilterService } from './saved-filter.service';
|
|
9
9
|
|
|
10
10
|
import * as moment from 'moment';
|
|
@@ -13,8 +13,8 @@ import * as moment from 'moment';
|
|
|
13
13
|
export class FilterService {
|
|
14
14
|
constructor(
|
|
15
15
|
private dataSource: DataSource,
|
|
16
|
-
private readonly
|
|
17
|
-
private readonly
|
|
16
|
+
private readonly attributeMasterService: AttributeMasterService,
|
|
17
|
+
private readonly entityMasterService: EntityMasterService,
|
|
18
18
|
@Inject('SavedFilterService')
|
|
19
19
|
private readonly savedFilterService: SavedFilterService,
|
|
20
20
|
) {}
|
|
@@ -69,6 +69,86 @@ export class FilterService {
|
|
|
69
69
|
];
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
async applyFilterWrapper(dto: FilterRequestDto) {
|
|
73
|
+
const {
|
|
74
|
+
entity_type,
|
|
75
|
+
quickFilter = [],
|
|
76
|
+
savedFilterCode,
|
|
77
|
+
attributeFilter = [],
|
|
78
|
+
} = dto;
|
|
79
|
+
|
|
80
|
+
// 🔹 Step 1: Collect all filters (from body + savedFilter)
|
|
81
|
+
const savedFilters = await this.getSavedFilters(
|
|
82
|
+
savedFilterCode ?? undefined,
|
|
83
|
+
);
|
|
84
|
+
const allFilters = [
|
|
85
|
+
...quickFilter,
|
|
86
|
+
...attributeFilter,
|
|
87
|
+
...savedFilters,
|
|
88
|
+
].filter((f) => f.filter_value !== '');
|
|
89
|
+
|
|
90
|
+
// 🔹 Step 2: Group filters by filter_entity_type
|
|
91
|
+
const grouped = allFilters.reduce(
|
|
92
|
+
(acc, f) => {
|
|
93
|
+
if (!acc[f.filter_entity_type]) acc[f.filter_entity_type] = [];
|
|
94
|
+
acc[f.filter_entity_type].push(f);
|
|
95
|
+
return acc;
|
|
96
|
+
},
|
|
97
|
+
{} as Record<string, any[]>,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// 🔹 Step 3: Handle sub-entities first
|
|
101
|
+
let intersectionIds: number[] | null = null;
|
|
102
|
+
for (const [subEntityType, filters] of Object.entries(grouped)) {
|
|
103
|
+
if (subEntityType === entity_type) continue; // skip main entity for now
|
|
104
|
+
|
|
105
|
+
let { queryParams, ...newDto } = dto;
|
|
106
|
+
|
|
107
|
+
const subDto: FilterRequestDto = {
|
|
108
|
+
...newDto,
|
|
109
|
+
entity_type: subEntityType,
|
|
110
|
+
quickFilter: filters as FilterCondition[],
|
|
111
|
+
savedFilterCode: null, // already merged
|
|
112
|
+
attributeFilter: [],
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const subResult = await this.applyFilter(subDto);
|
|
116
|
+
|
|
117
|
+
// extract parent ids from sub entity result
|
|
118
|
+
const parentIds = subResult.data.entity_list.map((row) => row.parent_id);
|
|
119
|
+
|
|
120
|
+
// keep intersection
|
|
121
|
+
intersectionIds =
|
|
122
|
+
intersectionIds === null
|
|
123
|
+
? parentIds
|
|
124
|
+
: intersectionIds.filter((id) => parentIds.includes(id));
|
|
125
|
+
|
|
126
|
+
// early exit if no intersection
|
|
127
|
+
if (intersectionIds.length === 0) {
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
data: { entity_tabs: [], entity_list: [], pagination: {} },
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 🔹 Step 4: Call applyFilter for main entity
|
|
136
|
+
const mainFilters = grouped[entity_type] || [];
|
|
137
|
+
const mainDto: FilterRequestDto = {
|
|
138
|
+
...dto,
|
|
139
|
+
quickFilter: mainFilters,
|
|
140
|
+
savedFilterCode: null,
|
|
141
|
+
attributeFilter: [],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// pass intersection ids as an extra constraint
|
|
145
|
+
if (intersectionIds && intersectionIds.length > 0) {
|
|
146
|
+
mainDto['restrictIds'] = intersectionIds;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return this.applyFilter(mainDto);
|
|
150
|
+
}
|
|
151
|
+
|
|
72
152
|
async applyFilter(dto: FilterRequestDto) {
|
|
73
153
|
const {
|
|
74
154
|
entity_type,
|
|
@@ -94,7 +174,7 @@ export class FilterService {
|
|
|
94
174
|
} = loggedInUser || {};
|
|
95
175
|
|
|
96
176
|
// Fetch meta from entity table service
|
|
97
|
-
const entityMeta = await this.
|
|
177
|
+
const entityMeta = await this.entityMasterService.getEntityData(
|
|
98
178
|
entity_type,
|
|
99
179
|
loggedInUser,
|
|
100
180
|
);
|
|
@@ -105,29 +185,25 @@ export class FilterService {
|
|
|
105
185
|
}
|
|
106
186
|
|
|
107
187
|
// get table meta from cr_entity_table
|
|
108
|
-
const getTableMeta =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
);
|
|
120
|
-
}
|
|
188
|
+
// const getTableMeta =
|
|
189
|
+
// await this.attributeMasterService.findAttributesByMappedEntityType(
|
|
190
|
+
// entity_type,
|
|
191
|
+
// loggedInUser,
|
|
192
|
+
// );
|
|
193
|
+
|
|
194
|
+
// if (!getTableMeta) {
|
|
195
|
+
// throw new BadRequestException(
|
|
196
|
+
// `Table meta not found for entity_type: ${entity_type}`,
|
|
197
|
+
// );
|
|
198
|
+
// }
|
|
121
199
|
|
|
122
|
-
const
|
|
123
|
-
await this.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
true,
|
|
200
|
+
const getAttributeColumnMeta =
|
|
201
|
+
await this.attributeMasterService.findAttributesByMappedEntityType(
|
|
202
|
+
entity_type,
|
|
203
|
+
loggedInUser,
|
|
127
204
|
);
|
|
128
205
|
|
|
129
|
-
|
|
130
|
-
const attributeMetaMap = getTableColumnMeta.reduce(
|
|
206
|
+
const attributeMetaMap = getAttributeColumnMeta.reduce(
|
|
131
207
|
(acc, attr) => {
|
|
132
208
|
acc[attr.attribute_key] = attr;
|
|
133
209
|
return acc;
|
|
@@ -136,19 +212,27 @@ export class FilterService {
|
|
|
136
212
|
);
|
|
137
213
|
|
|
138
214
|
// Get and parse saved filters
|
|
139
|
-
console.log(
|
|
140
|
-
const savedFilters = await this.getSavedFilters(
|
|
141
|
-
|
|
142
|
-
|
|
215
|
+
console.log('IN FILTER SERVICE', savedFilterCode);
|
|
216
|
+
const savedFilters = await this.getSavedFilters(
|
|
217
|
+
savedFilterCode ?? undefined,
|
|
218
|
+
);
|
|
219
|
+
console.log('SAVED FILTERS', savedFilters);
|
|
220
|
+
const savedFiltersNormalized = savedFilters.map((f) => ({
|
|
143
221
|
filter_attribute: f.filter_attribute,
|
|
144
222
|
filter_operator: f.filter_operator,
|
|
145
|
-
filter_value: f.filter_value
|
|
223
|
+
filter_value: f.filter_value,
|
|
146
224
|
}));
|
|
147
|
-
|
|
225
|
+
|
|
148
226
|
const baseFilters = [
|
|
149
|
-
...(quickFilter || []).filter(
|
|
150
|
-
|
|
151
|
-
|
|
227
|
+
...(quickFilter || []).filter(
|
|
228
|
+
(f) => f.filter_value != null && f.filter_value !== '',
|
|
229
|
+
),
|
|
230
|
+
...savedFiltersNormalized.filter(
|
|
231
|
+
(f) => f.filter_value != null && f.filter_value !== '',
|
|
232
|
+
),
|
|
233
|
+
...(attributeFilter || []).filter(
|
|
234
|
+
(f) => f.filter_value != null && f.filter_value !== '',
|
|
235
|
+
),
|
|
152
236
|
];
|
|
153
237
|
|
|
154
238
|
// Build where clauses
|
|
@@ -228,7 +312,6 @@ export class FilterService {
|
|
|
228
312
|
[user_id, entity_type, level_id, level_type],
|
|
229
313
|
);
|
|
230
314
|
|
|
231
|
-
|
|
232
315
|
// Extract layout preference
|
|
233
316
|
const layout = layoutPreference?.[0]?.mapped_json?.quick_tab || {};
|
|
234
317
|
|
|
@@ -237,13 +320,13 @@ export class FilterService {
|
|
|
237
320
|
let allTabs;
|
|
238
321
|
if (layout.attribute) {
|
|
239
322
|
allTabs = await this.gettab_value_counts(
|
|
240
|
-
|
|
323
|
+
entityMeta?.data_source,
|
|
241
324
|
layout.attribute,
|
|
242
325
|
baseWhere,
|
|
243
326
|
);
|
|
244
327
|
} else {
|
|
245
328
|
allTabs = await this.gettab_value_counts(
|
|
246
|
-
|
|
329
|
+
entityMeta?.data_source,
|
|
247
330
|
tabs?.columnName,
|
|
248
331
|
baseWhere,
|
|
249
332
|
);
|
|
@@ -431,7 +514,6 @@ export class FilterService {
|
|
|
431
514
|
const size = dto.size && dto.size > 0 ? dto.size : 10;
|
|
432
515
|
qb.skip((page - 1) * size).take(size);
|
|
433
516
|
|
|
434
|
-
|
|
435
517
|
const entity_list = await qb.getRawMany();
|
|
436
518
|
|
|
437
519
|
// 1. Extract all date-type attribute keys
|
|
@@ -20,6 +20,14 @@ export class AttributeMaster extends BaseEntity {
|
|
|
20
20
|
})
|
|
21
21
|
data_source_type: string;
|
|
22
22
|
|
|
23
|
+
@Column({
|
|
24
|
+
name: 'data_type',
|
|
25
|
+
type: 'varchar',
|
|
26
|
+
nullable: true,
|
|
27
|
+
length: 50,
|
|
28
|
+
})
|
|
29
|
+
data_type: string;
|
|
30
|
+
|
|
23
31
|
@Column({ name: 'datasource_list', type: 'varchar', nullable: true })
|
|
24
32
|
datasource_list: string;
|
|
25
33
|
|
|
@@ -24,4 +24,10 @@ export class Role extends BaseEntity {
|
|
|
24
24
|
|
|
25
25
|
@Column({ type: 'int', nullable: true })
|
|
26
26
|
is_factory: number;
|
|
27
|
+
|
|
28
|
+
@Column({ type: 'varchar', length: 250, nullable: true })
|
|
29
|
+
parent_type: string;
|
|
30
|
+
|
|
31
|
+
@Column({ type: 'int', nullable: true })
|
|
32
|
+
parent_id: number;
|
|
27
33
|
}
|
|
@@ -31,7 +31,7 @@ import { Action } from 'src/module/workflow-automation/interface/action.interfac
|
|
|
31
31
|
import { ActionHandler } from 'src/module/workflow-automation/interface/action.decorator';
|
|
32
32
|
|
|
33
33
|
@Injectable()
|
|
34
|
-
@ActionHandler('User')
|
|
34
|
+
@ActionHandler('User')
|
|
35
35
|
export class UserService extends EntityServiceImpl implements Action {
|
|
36
36
|
constructor(
|
|
37
37
|
private userRepository: UserRepository,
|
|
@@ -138,7 +138,7 @@ export class UserService extends EntityServiceImpl implements Action {
|
|
|
138
138
|
return { success: true, data: savedData };
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
name
|
|
141
|
+
name: string = 'UserService';
|
|
142
142
|
async execute(payload: any): Promise<any> {
|
|
143
143
|
console.log('payload', payload);
|
|
144
144
|
}
|
|
@@ -44,4 +44,11 @@ export class ActionCategoryController {
|
|
|
44
44
|
const result = this.actionCategoryService.getActionCategory(action_cat_id);
|
|
45
45
|
return result;
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
@Post('/actionscategoryinfo')
|
|
49
|
+
@HttpCode(HttpStatus.OK)
|
|
50
|
+
async actionscategoryinfo(@Body('entity_type') entity_type: string) {
|
|
51
|
+
const result = this.actionCategoryService.actionscategoryinfo(entity_type);
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
47
54
|
}
|
|
@@ -53,4 +53,27 @@ export class ActionCategoryRepository {
|
|
|
53
53
|
|
|
54
54
|
return result;
|
|
55
55
|
}
|
|
56
|
+
|
|
57
|
+
async actionscategoryinfo(entity_type: string) {
|
|
58
|
+
const result = await this.actionCategoryRepository
|
|
59
|
+
.createQueryBuilder('ac')
|
|
60
|
+
.select(['ac.id', 'ac.name', 'ac.logo', 'ac.modalName'])
|
|
61
|
+
.where('ac.mapped_entity_type = :entityType', { entityType: entity_type })
|
|
62
|
+
.getRawMany();
|
|
63
|
+
|
|
64
|
+
const mapped = result.map((row) => ({
|
|
65
|
+
label: row.ac_name,
|
|
66
|
+
logo: row.ac_logo,
|
|
67
|
+
modalName: row.ac_modalName,
|
|
68
|
+
value: String(row.ac_id),
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
return mapped.reduce(
|
|
72
|
+
(acc, { value, ...rest }) => {
|
|
73
|
+
acc[value] = rest;
|
|
74
|
+
return acc;
|
|
75
|
+
},
|
|
76
|
+
{} as Record<string, any>,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
56
79
|
}
|
|
@@ -26,4 +26,8 @@ export class ActionCategoryService extends EntityServiceImpl {
|
|
|
26
26
|
async getActionCategory(action_cat_id: number) {
|
|
27
27
|
return this.actionCategoryRepository.getActionCategory(action_cat_id);
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
async actionscategoryinfo(entity_type: string) {
|
|
31
|
+
return this.actionCategoryRepository.actionscategoryinfo(entity_type);
|
|
32
|
+
}
|
|
29
33
|
}
|
|
@@ -8,8 +8,10 @@ import { BaseEntity } from 'src/module/meta/entity/base-entity.entity';
|
|
|
8
8
|
import { ActivityLogService } from './activity-log.service';
|
|
9
9
|
import { ACTIVITY_CATEGORIES } from '../repository/activity-log.repository';
|
|
10
10
|
import { MediaDataService } from 'src/module/meta/service/media-data.service';
|
|
11
|
+
import { ActionHandler } from 'src/module/workflow-automation/interface/action.decorator';
|
|
11
12
|
|
|
12
13
|
@Injectable()
|
|
14
|
+
@ActionHandler('add_task')
|
|
13
15
|
export class TaskService extends EntityServiceImpl {
|
|
14
16
|
constructor(
|
|
15
17
|
private readonly taskRepository: TaskRepository,
|
|
@@ -21,6 +23,49 @@ export class TaskService extends EntityServiceImpl {
|
|
|
21
23
|
) {
|
|
22
24
|
super();
|
|
23
25
|
}
|
|
26
|
+
name: string = 'add_task';
|
|
27
|
+
|
|
28
|
+
async execute(payload: any): Promise<any> {
|
|
29
|
+
console.log('BHUSHAN');
|
|
30
|
+
const { entity, user, config } = payload;
|
|
31
|
+
|
|
32
|
+
let toValue: string | null = null;
|
|
33
|
+
|
|
34
|
+
// 2. Get current stage_id from cr_wf_stage_movement_data
|
|
35
|
+
const stageRow = await this.dataSource.query(
|
|
36
|
+
`SELECT stage_id
|
|
37
|
+
FROM cr_wf_stage_movement_data
|
|
38
|
+
WHERE mapped_entity_id = ?
|
|
39
|
+
AND is_current = 'Y'
|
|
40
|
+
LIMIT 1`,
|
|
41
|
+
[entity.id],
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const stageId = stageRow.length > 0 ? stageRow[0].stage_id : null;
|
|
45
|
+
|
|
46
|
+
if (!stageId) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`No current stage found in cr_wf_stage_movement_data for entity_id=${entity.id}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 3. Build entityData
|
|
53
|
+
const entityData = {
|
|
54
|
+
...config,
|
|
55
|
+
mapped_entity_id: entity.id,
|
|
56
|
+
mapped_entity_type: entity.entity_type,
|
|
57
|
+
task_owner: config.task_owner,
|
|
58
|
+
stage_id: stageId,
|
|
59
|
+
status: config.status,
|
|
60
|
+
due_date: config.due_date,
|
|
61
|
+
due_time: config.due_time,
|
|
62
|
+
reminder: config.reminder,
|
|
63
|
+
description: config.description,
|
|
64
|
+
is_mandatory: config.is_mandatory,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return await this.createEntity(entityData, user);
|
|
68
|
+
}
|
|
24
69
|
|
|
25
70
|
async createEntity(
|
|
26
71
|
entityData: any,
|
|
@@ -29,12 +29,15 @@ export class WorkflowAutomationEngineService {
|
|
|
29
29
|
user: any,
|
|
30
30
|
preUpdateStates?: Record<number, boolean> | null,
|
|
31
31
|
) {
|
|
32
|
-
const workflows = await this.wfService.getActiveRules(
|
|
33
|
-
|
|
32
|
+
const workflows = await this.wfService.getActiveRules(
|
|
33
|
+
entityType,
|
|
34
|
+
eventType,
|
|
35
|
+
);
|
|
36
|
+
|
|
34
37
|
for (const wf of workflows) {
|
|
35
38
|
// Step 1️⃣ Condition / Trigger evaluation
|
|
36
39
|
let triggerMatched = false;
|
|
37
|
-
|
|
40
|
+
|
|
38
41
|
if (eventType === 'CREATE') {
|
|
39
42
|
triggerMatched = await this.filterEvaluator.evaluateCriteria(
|
|
40
43
|
entityType,
|
|
@@ -52,15 +55,15 @@ export class WorkflowAutomationEngineService {
|
|
|
52
55
|
);
|
|
53
56
|
triggerMatched = before !== after && after === true;
|
|
54
57
|
}
|
|
55
|
-
|
|
58
|
+
|
|
56
59
|
// 🔍 Log Step 1 result
|
|
57
60
|
console.log(
|
|
58
61
|
`[Workflow:${wf.id}] Step 1 - Trigger matched:`,
|
|
59
62
|
triggerMatched,
|
|
60
63
|
);
|
|
61
|
-
|
|
64
|
+
|
|
62
65
|
if (!triggerMatched) continue;
|
|
63
|
-
|
|
66
|
+
|
|
64
67
|
// Step 2️⃣ Final criteria evaluation
|
|
65
68
|
const criteriaMatched = await this.filterEvaluator.evaluateCriteria(
|
|
66
69
|
entityType,
|
|
@@ -68,20 +71,19 @@ export class WorkflowAutomationEngineService {
|
|
|
68
71
|
newEntity.id,
|
|
69
72
|
user,
|
|
70
73
|
);
|
|
71
|
-
|
|
74
|
+
|
|
72
75
|
// 🔍 Log Step 2 result
|
|
73
76
|
console.log(
|
|
74
77
|
`[Workflow:${wf.id}] Step 2 - Criteria matched:`,
|
|
75
78
|
criteriaMatched,
|
|
76
79
|
);
|
|
77
|
-
|
|
80
|
+
|
|
78
81
|
if (!criteriaMatched) continue;
|
|
79
|
-
|
|
82
|
+
|
|
80
83
|
// Step 3️⃣ Execute workflow actions
|
|
81
84
|
await this.executeActions(wf.id, newEntity, user);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
|
-
|
|
85
87
|
|
|
86
88
|
private async executeActions(
|
|
87
89
|
workflow_automation_id: number,
|
|
@@ -89,17 +91,22 @@ export class WorkflowAutomationEngineService {
|
|
|
89
91
|
user: any,
|
|
90
92
|
) {
|
|
91
93
|
// Load actions for this rule from DB
|
|
92
|
-
const actions = await this.wfService.getActionsForRule(
|
|
93
|
-
|
|
94
|
+
const actions = await this.wfService.getActionsForRule(
|
|
95
|
+
workflow_automation_id,
|
|
96
|
+
);
|
|
94
97
|
|
|
95
98
|
for (const action of actions) {
|
|
96
99
|
const impl = this.actions.get(String(action.action_decorator)); // action_code = registered name
|
|
97
100
|
if (!impl) {
|
|
98
|
-
console.warn(
|
|
101
|
+
console.warn(
|
|
102
|
+
`⚠️ No implementation found for action: ${action.action_decorator}`,
|
|
103
|
+
);
|
|
99
104
|
continue;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
console.log(
|
|
107
|
+
console.log(
|
|
108
|
+
`🚀 Executing action ${action.action_decorator} for entity ${entity.id}`,
|
|
109
|
+
);
|
|
103
110
|
await impl.execute({ entity, user, config: action.payload });
|
|
104
111
|
}
|
|
105
112
|
}
|
|
@@ -199,8 +199,8 @@ export class WorkflowAutomationService extends EntityServiceImpl {
|
|
|
199
199
|
if (existing) {
|
|
200
200
|
// update
|
|
201
201
|
existing.payload = a.actionPayload ?? {};
|
|
202
|
-
existing.
|
|
203
|
-
a.actionCategoryName ?? existing.
|
|
202
|
+
existing.actionCategoryName =
|
|
203
|
+
a.actionCategoryName ?? existing.actionCategoryName;
|
|
204
204
|
await this.dataSource
|
|
205
205
|
.getRepository(WorkflowAutomationActionEntity)
|
|
206
206
|
.save(existing);
|
|
@@ -211,7 +211,7 @@ export class WorkflowAutomationService extends EntityServiceImpl {
|
|
|
211
211
|
actionEntity.entity_type = 'WFAA';
|
|
212
212
|
actionEntity.workflow_automation_id = workflow.id;
|
|
213
213
|
actionEntity.action_category_id = a.actionCategory;
|
|
214
|
-
actionEntity.
|
|
214
|
+
actionEntity.actionCategoryName = a.actionCategoryName;
|
|
215
215
|
actionEntity.payload = a.actionPayload ?? {};
|
|
216
216
|
|
|
217
217
|
await this.dataSource
|
|
@@ -313,7 +313,7 @@ export class WorkflowAutomationService extends EntityServiceImpl {
|
|
|
313
313
|
|
|
314
314
|
const action = actions.map((a) => ({
|
|
315
315
|
actionCategory: a.action_category_id,
|
|
316
|
-
actionCategoryName: a.
|
|
316
|
+
actionCategoryName: a.actionCategoryName,
|
|
317
317
|
actionPayload: a.payload,
|
|
318
318
|
}));
|
|
319
319
|
|