rez_core 2.2.39 → 2.2.41

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.2.39",
3
+ "version": "2.2.41",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -32,13 +32,17 @@ export class StageGroupController {
32
32
  );
33
33
  }
34
34
 
35
- @Post('/get-all-stage-groups-and-stages')
35
+ @Post('/get-workflow-stage-hierarchy')
36
36
  @HttpCode(HttpStatus.OK)
37
- async getAllStageGroupAndStageHierarchy(@Req() req: Request & { user: any }) {
37
+ async getAllStageGroupAndStageHierarchy(
38
+ @Req() req: Request & { user: any },
39
+ @Body() body: { lead_id: number },
40
+ ) {
38
41
  const loggedInUser = req.user.userData;
39
42
 
40
43
  return this.stageGroupService.getAllStageGroupAndStageHierarchy(
41
44
  loggedInUser,
45
+ body.lead_id,
42
46
  );
43
47
  }
44
48
  }
@@ -61,11 +61,15 @@ export class StageGroupRepository {
61
61
 
62
62
  const stages = await this.dataSource.query(
63
63
  `
64
- SELECT * FROM cr_wf_stage
65
- WHERE stage_group_id IN (${stageGroupIds.map(() => '?').join(',')})
66
- AND organization_id = ?
67
- ORDER BY sequence ASC
68
- `,
64
+ SELECT
65
+ cr_wf_stage.*,
66
+ cr_user.name AS created_by_name
67
+ FROM cr_wf_stage
68
+ LEFT JOIN cr_user ON cr_wf_stage.created_by = cr_user.id
69
+ WHERE cr_wf_stage.stage_group_id IN (${stageGroupIds.map(() => '?').join(',')})
70
+ AND cr_wf_stage.organization_id = ?
71
+ ORDER BY cr_wf_stage.sequence ASC
72
+ `,
69
73
  [...stageGroupIds, organization_id],
70
74
  );
71
75
 
@@ -27,8 +27,13 @@ export class ActionService extends EntityServiceImpl {
27
27
  }
28
28
 
29
29
  const result = await this.dataSource.query(
30
- `SELECT template_code, form_id FROM cr_wf_action_resources_mapping WHERE stg_act_mapping_id =
31
- (SELECT id FROM cr_wf_stage_action_mapping WHERE action_id = ? AND entity_type = 'STGM')`,
30
+ `SELECT template_code, form_id
31
+ FROM cr_wf_action_resources_mapping
32
+ WHERE stg_act_mapping_id IN (
33
+ SELECT id
34
+ FROM cr_wf_stage_action_mapping
35
+ WHERE action_id = ? AND entity_type = 'STGM'
36
+ )`,
32
37
  [actionData.id],
33
38
  );
34
39
 
@@ -7,6 +7,8 @@ import { StageService } from './stage.service';
7
7
  import { DataSource, Repository } from 'typeorm';
8
8
  import { WorkflowLevelMappingEntity } from '../entity/workflow-level-mapping.entity';
9
9
  import { InjectRepository } from '@nestjs/typeorm';
10
+ import { StageMovementData } from '../entity/stage-movement-data.entity';
11
+ import * as moment from 'moment';
10
12
 
11
13
  @Injectable()
12
14
  export class StageGroupService extends EntityServiceImpl {
@@ -17,6 +19,8 @@ export class StageGroupService extends EntityServiceImpl {
17
19
  private readonly dataSource: DataSource,
18
20
  @InjectRepository(WorkflowLevelMappingEntity)
19
21
  private readonly workflowLevelMappingRepo: Repository<WorkflowLevelMappingEntity>,
22
+ @InjectRepository(StageMovementData)
23
+ private readonly stageMovementRepo: Repository<StageMovementData>,
20
24
  ) {
21
25
  super();
22
26
  }
@@ -27,8 +31,11 @@ export class StageGroupService extends EntityServiceImpl {
27
31
  );
28
32
  }
29
33
 
30
- async getAllStageGroupAndStageHierarchy(loggedInUser: UserData) {
31
- // Try finding mapping at user's level
34
+ async getAllStageGroupAndStageHierarchy(
35
+ loggedInUser: UserData,
36
+ lead_id: number,
37
+ ) {
38
+ // 1. Find workflow mapping at user level
32
39
  let workflowLevelMapping = await this.workflowLevelMappingRepo.findOne({
33
40
  where: {
34
41
  mapped_level_type: loggedInUser.level_type,
@@ -36,7 +43,7 @@ export class StageGroupService extends EntityServiceImpl {
36
43
  },
37
44
  });
38
45
 
39
- // If not found, fallback to organization-level mapping
46
+ // 2. Fallback to organization level if not found
40
47
  if (!workflowLevelMapping) {
41
48
  workflowLevelMapping = await this.workflowLevelMappingRepo.findOne({
42
49
  where: {
@@ -46,13 +53,96 @@ export class StageGroupService extends EntityServiceImpl {
46
53
  });
47
54
  }
48
55
 
49
- // If still not found, return null
50
56
  if (!workflowLevelMapping) return null;
51
57
 
52
- return await this.stageGroupRepository.getAllStageGroupAndStageHierarchy(
53
- workflowLevelMapping.workflow_id,
54
- loggedInUser.organization_id,
55
- );
58
+ // 3. Fetch stage groups and their stages
59
+ const stageGroupAndStageHierarchy =
60
+ (await this.stageGroupRepository.getAllStageGroupAndStageHierarchy(
61
+ workflowLevelMapping.workflow_id,
62
+ loggedInUser.organization_id,
63
+ )) as Array<{
64
+ stages: any[];
65
+ stage_group_status?: string; // Extend type here to satisfy TS
66
+ [key: string]: any; // Allow additional dynamic props
67
+ }>;
68
+
69
+ if (stageGroupAndStageHierarchy.length === 0) return [];
70
+
71
+ // 4. Fetch all stage movement data for this lead
72
+ const stageMovementData = await this.stageMovementRepo.find({
73
+ where: {
74
+ mapped_entity_type: 'LEAD',
75
+ mapped_entity_id: lead_id,
76
+ },
77
+ });
78
+
79
+ // 5. Map: stage_id => movement data
80
+ const stageMovementMap = new Map<number, any>();
81
+ for (const movement of stageMovementData) {
82
+ stageMovementMap.set(movement.stage_id, movement);
83
+ }
84
+
85
+ // 6. Attach movement info to each stage
86
+ for (const group of stageGroupAndStageHierarchy) {
87
+ for (const stage of group.stages || []) {
88
+ const movement = stageMovementMap.get(Number(stage.id));
89
+
90
+ if (movement) {
91
+ stage.is_current = movement.is_current === 'Y';
92
+ stage.is_done = movement.is_current === 'N';
93
+ stage.start_time = movement.start_date
94
+ ? moment(movement.start_date).format('DD-MMM, hh:mm A')
95
+ : null;
96
+ stage.end_time = movement.end_date
97
+ ? moment(movement.end_date).format('DD-MMM, hh:mm A')
98
+ : null;
99
+ stage.time_spent = await this.calculateTimeSpent(
100
+ movement.start_date,
101
+ movement.end_date ?? new Date(), // fallback to current datetime
102
+ );
103
+ } else {
104
+ stage.is_current = false;
105
+ stage.is_done = false;
106
+ stage.start_time = null;
107
+ stage.end_time = null;
108
+ stage.time_spent = null;
109
+ stage.created_by_name = null;
110
+ }
111
+ }
112
+
113
+ // 7. Set stage_group_status based on all its stages
114
+ group.stage_group_status =
115
+ group.stages && group.stages.length > 0
116
+ ? group.stages.every((stage) => stage.is_done)
117
+ ? 'COMPLETED'
118
+ : 'IN_PROGRESS'
119
+ : 'NOT_STARTED';
120
+ }
121
+
122
+ return stageGroupAndStageHierarchy;
123
+ }
124
+
125
+ async calculateTimeSpent(
126
+ start: Date | string,
127
+ end?: Date | string,
128
+ ): Promise<string> {
129
+ const startMoment = moment(start);
130
+ const endMoment = end ? moment(end) : moment();
131
+
132
+ const duration = moment.duration(endMoment.diff(startMoment));
133
+ const days = duration.asDays();
134
+
135
+ if (days > 7) {
136
+ return startMoment.format('DD-MMM-YYYY');
137
+ } else if (days >= 1) {
138
+ return `${Math.floor(days)} days`;
139
+ } else if (duration.asHours() >= 1) {
140
+ return `${Math.floor(duration.asHours())} hours`;
141
+ } else if (duration.asMinutes() >= 1) {
142
+ return `${Math.floor(duration.asMinutes())} mins`;
143
+ } else {
144
+ return `${Math.floor(duration.asSeconds())} sec`;
145
+ }
56
146
  }
57
147
 
58
148
  async updateEntity(