rez_core 2.2.195 → 2.2.196

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 (37) hide show
  1. package/dist/module/communication/controller/communication.controller.d.ts +5 -8
  2. package/dist/module/communication/controller/communication.controller.js +18 -15
  3. package/dist/module/communication/controller/communication.controller.js.map +1 -1
  4. package/dist/module/communication/service/communication.service.d.ts +2 -3
  5. package/dist/module/communication/service/communication.service.js +29 -37
  6. package/dist/module/communication/service/communication.service.js.map +1 -1
  7. package/dist/module/communication/service/wrapper.service.js +0 -7
  8. package/dist/module/communication/service/wrapper.service.js.map +1 -1
  9. package/dist/module/communication/strategies/email/sendgrid-api.strategy.d.ts +2 -3
  10. package/dist/module/communication/strategies/email/sendgrid-api.strategy.js +2 -3
  11. package/dist/module/communication/strategies/email/sendgrid-api.strategy.js.map +1 -1
  12. package/dist/module/filter/controller/filter.controller.d.ts +1 -1
  13. package/dist/module/filter/controller/filter.controller.js +6 -2
  14. package/dist/module/filter/controller/filter.controller.js.map +1 -1
  15. package/dist/module/filter/dto/filter-request.dto.d.ts +2 -0
  16. package/dist/module/filter/service/filter.service.js +17 -2
  17. package/dist/module/filter/service/filter.service.js.map +1 -1
  18. package/dist/module/workflow/entity/comm-template.entity.d.ts +1 -0
  19. package/dist/module/workflow/entity/comm-template.entity.js +4 -0
  20. package/dist/module/workflow/entity/comm-template.entity.js.map +1 -1
  21. package/dist/module/workflow/service/comm-template.service.js +12 -1
  22. package/dist/module/workflow/service/comm-template.service.js.map +1 -1
  23. package/dist/module/workflow/service/task.service.d.ts +0 -1
  24. package/dist/module/workflow/service/task.service.js +0 -43
  25. package/dist/module/workflow/service/task.service.js.map +1 -1
  26. package/dist/tsconfig.build.tsbuildinfo +1 -1
  27. package/package.json +1 -1
  28. package/src/module/communication/controller/communication.controller.ts +19 -18
  29. package/src/module/communication/service/communication.service.ts +56 -53
  30. package/src/module/communication/service/wrapper.service.ts +0 -15
  31. package/src/module/communication/strategies/email/sendgrid-api.strategy.ts +5 -7
  32. package/src/module/filter/controller/filter.controller.ts +4 -0
  33. package/src/module/filter/dto/filter-request.dto.ts +2 -0
  34. package/src/module/filter/service/filter.service.ts +22 -1
  35. package/src/module/workflow/entity/comm-template.entity.ts +3 -0
  36. package/src/module/workflow/service/comm-template.service.ts +21 -1
  37. package/src/module/workflow/service/task.service.ts +0 -55
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.2.195",
3
+ "version": "2.2.196",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -31,9 +31,7 @@ export class ScheduledMessageDto extends GenericSendMessageDto {
31
31
 
32
32
  @Controller('communication')
33
33
  export class CommunicationController {
34
- constructor(
35
- private readonly communicationService: CommunicationService,
36
- ) {}
34
+ constructor(private readonly communicationService: CommunicationService) {}
37
35
 
38
36
  @Post('send')
39
37
  @HttpCode(HttpStatus.OK)
@@ -183,26 +181,29 @@ export class CommunicationController {
183
181
  }
184
182
  }
185
183
 
186
- @Put('config/:id/status')
187
- async updateConfigStatus(
188
- @Param('id', ParseIntPipe) hubId: number,
189
- @Body() updateStatusDto: UpdateConfigStatusDto,
190
- ) {
191
- await this.communicationService.updateConfigStatus(
192
- hubId,
193
- updateStatusDto.status,
194
- );
195
- return { message: 'Status updated successfully' };
196
- }
197
-
198
184
  @Post('config/:id/update')
199
185
  @HttpCode(HttpStatus.OK)
200
186
  async activateConfig(
201
187
  @Param('id', ParseIntPipe) hubId: number,
202
- @Query('status') status: number,
188
+ @Query('status') status: string,
203
189
  ) {
204
- await this.communicationService.updateConfigStatus(hubId, status);
205
- return { message: 'Configuration updated' };
190
+ try {
191
+ const statusNumber = parseInt(status, 10);
192
+ if (isNaN(statusNumber) || (statusNumber !== 0 && statusNumber !== 1)) {
193
+ throw new BadRequestException('Status must be 0 or 1');
194
+ }
195
+
196
+ await this.communicationService.updateConfigStatus(hubId, statusNumber);
197
+ return {
198
+ success: true,
199
+ message: 'Configuration updated successfully',
200
+ };
201
+ } catch (error) {
202
+ throw new BadRequestException({
203
+ success: false,
204
+ error: 'UPDATE_STATUS_ERROR',
205
+ });
206
+ }
206
207
  }
207
208
 
208
209
  @Post('gmail/oauth/init')
@@ -269,7 +269,7 @@ export class CommunicationService {
269
269
  ): Promise<
270
270
  CommunicationHub | { authUrl: string; state: string; message: string }
271
271
  > {
272
- // Validate that no active configuration of the same type exists (first check)
272
+ // Deactivate any existing active configurations of the same type to ensure only one is active
273
273
  await this.validateUniqueActiveConfig(levelId, levelType, configType);
274
274
 
275
275
  // Validate service/provider combination using supported combinations
@@ -649,35 +649,30 @@ export class CommunicationService {
649
649
  }
650
650
 
651
651
  async updateConfigStatus(hubId: number, status: number): Promise<void> {
652
- // Validate active status change to prevent multiple active configurations
653
- if (status === 1) {
654
- // Find the hub to get level and type information
655
- const hub = await this.hubRepository.findOne({
656
- where: { id: hubId },
657
- });
652
+ // Find the hub to get level and type information
653
+ const hub = await this.hubRepository.findOne({
654
+ where: { id: hubId },
655
+ });
658
656
 
659
- if (!hub) {
660
- throw new Error('Communication configuration not found');
661
- }
657
+ if (!hub) {
658
+ throw new Error('Communication configuration not found');
659
+ }
662
660
 
663
- // Check for existing active configuration of same type
664
- const existingActiveConfig = await this.hubRepository.findOne({
665
- where: {
661
+ // If activating, deactivate other configs with same level_id + level_type + communication_config_type
662
+ if (status === 1) {
663
+ await this.hubRepository.update(
664
+ {
666
665
  level_id: hub.level_id,
667
666
  level_type: hub.level_type,
668
667
  communication_config_type: hub.communication_config_type,
669
- status: 1, // Active status
670
- id: Not(hubId), // Exclude current hub
668
+ status: 1,
669
+ id: Not(hubId),
671
670
  },
672
- });
673
-
674
- if (existingActiveConfig) {
675
- throw new Error(
676
- `An active ${hub.communication_config_type} configuration already exists for ${hub.level_type} ${hub.level_id}. Please deactivate the existing configuration first.`,
677
- );
678
- }
671
+ { status: 0 },
672
+ );
679
673
  }
680
674
 
675
+ // Update the requested config
681
676
  await this.hubRepository.update(hubId, { status });
682
677
  }
683
678
 
@@ -739,23 +734,14 @@ export class CommunicationService {
739
734
  });
740
735
  }
741
736
 
742
- // Validate active status change to prevent multiple active configurations
737
+ // Deactivate other configurations if this one is being activated
743
738
  if (updateData.status === 1) {
744
- const existingActiveConfig = await this.hubRepository.findOne({
745
- where: {
746
- level_id: hub.level_id,
747
- level_type: hub.level_type,
748
- communication_config_type: hub.communication_config_type,
749
- status: 1, // Active status
750
- id: Not(hubId), // Exclude current hub
751
- },
752
- });
753
-
754
- if (existingActiveConfig) {
755
- throw new Error(
756
- `An active ${hub.communication_config_type} configuration already exists for ${hub.level_type} ${hub.level_id}. Please deactivate the existing configuration first.`,
757
- );
758
- }
739
+ await this.validateUniqueActiveConfig(
740
+ hub.level_id,
741
+ hub.level_type,
742
+ hub.communication_config_type,
743
+ hubId, // Exclude current hub
744
+ );
759
745
  }
760
746
 
761
747
  // Handle default configuration logic
@@ -1478,19 +1464,37 @@ export class CommunicationService {
1478
1464
  levelId: number,
1479
1465
  levelType: string,
1480
1466
  configType: CommunicationConfigType,
1467
+ excludeHubId?: number,
1481
1468
  ): Promise<void> {
1482
- const existingActiveConfig = await this.hubRepository.findOne({
1483
- where: {
1484
- level_id: levelId,
1485
- level_type: levelType,
1486
- communication_config_type: configType,
1487
- status: 1, // Active status
1488
- },
1489
- });
1469
+ // Find all active configurations of the same type for this level
1470
+ const query = this.hubRepository.createQueryBuilder('hub')
1471
+ .where('hub.level_id = :levelId', { levelId })
1472
+ .andWhere('hub.level_type = :levelType', { levelType })
1473
+ .andWhere('hub.communication_config_type = :configType', { configType })
1474
+ .andWhere('hub.status = :status', { status: 1 });
1490
1475
 
1491
- if (existingActiveConfig) {
1492
- throw new Error(
1493
- `An active ${configType} configuration already exists for ${levelType} ${levelId}. Please deactivate the existing configuration first.`,
1476
+ // Exclude current hub if updating
1477
+ if (excludeHubId) {
1478
+ query.andWhere('hub.id != :excludeHubId', { excludeHubId });
1479
+ }
1480
+
1481
+ const existingActiveConfigs = await query.getMany();
1482
+
1483
+ // If there are existing active configurations, deactivate them
1484
+ if (existingActiveConfigs.length > 0) {
1485
+ await this.hubRepository.update(
1486
+ {
1487
+ level_id: levelId,
1488
+ level_type: levelType,
1489
+ communication_config_type: configType,
1490
+ status: 1,
1491
+ ...(excludeHubId && { id: Not(excludeHubId) }),
1492
+ },
1493
+ { status: 0 } // Deactivate
1494
+ );
1495
+
1496
+ this.logger.log(
1497
+ `Deactivated ${existingActiveConfigs.length} existing ${configType} configuration(s) for ${levelType} ${levelId} to maintain single active provider rule.`,
1494
1498
  );
1495
1499
  }
1496
1500
  }
@@ -1575,7 +1579,7 @@ export class CommunicationService {
1575
1579
  priority?: number,
1576
1580
  is_default?: boolean,
1577
1581
  ): Promise<CommunicationHub> {
1578
- // Validate that no active configuration of the same type exists
1582
+ // Deactivate any existing active configurations of the same type to ensure only one is active
1579
1583
  await this.validateUniqueActiveConfig(levelId, levelType, configType);
1580
1584
 
1581
1585
  // If setting as default, remove default from other configurations of same type
@@ -1864,9 +1868,8 @@ export class CommunicationService {
1864
1868
  ): Promise<{
1865
1869
  success: boolean;
1866
1870
  data?: Array<{
1867
- id: string;
1868
- name: string;
1869
- generation: string;
1871
+ label: string;
1872
+ value: string;
1870
1873
  }>;
1871
1874
  error?: string;
1872
1875
  }> {
@@ -141,21 +141,6 @@ export class WrapperService {
141
141
  payload,
142
142
  );
143
143
  } else {
144
- // 2. Fallback → ORG-level config
145
- const fallbackConfigs = await this.datasource.query(
146
- `SELECT *
147
- FROM cr_communication_hub
148
- WHERE level_type = 'ORG'
149
- AND communication_config_type = 'CALENDAR'`,
150
- );
151
-
152
- configCred = await this.datasource.query(
153
- `SELECT config_json
154
- FROM cr_communication_config
155
- WHERE id = ?`,
156
- [fallbackConfigs[0]?.config_id],
157
- );
158
-
159
144
  const base64String = await this.icsService.generateIcs(payload);
160
145
 
161
146
  const result = await this.communicationService.sendGenericMessage({
@@ -188,9 +188,8 @@ export class SendGridApiStrategy implements CommunicationStrategy {
188
188
  async getTemplates(apiKey: string): Promise<{
189
189
  success: boolean;
190
190
  data?: Array<{
191
- id: string;
192
- name: string;
193
- generation: string;
191
+ label: string;
192
+ value: string;
194
193
  }>;
195
194
  error?: string;
196
195
  }> {
@@ -211,13 +210,12 @@ export class SendGridApiStrategy implements CommunicationStrategy {
211
210
 
212
211
  const templates = response.data.result || response.data.templates || [];
213
212
 
214
- // Format the response for dropdown usage
213
+ // Format the response for dropdown usage with template ID in both label and value
215
214
  const formattedTemplates = templates
216
215
  .filter((template: any) => template.generation === 'dynamic')
217
216
  .map((template: any) => ({
218
- id: template.id,
219
- name: template.name || `Template ${template.id}`,
220
- generation: template.generation,
217
+ label: template.name,
218
+ value: template.id,
221
219
  }));
222
220
 
223
221
  return {
@@ -30,6 +30,8 @@ export class FilterController {
30
30
  @Query('size', ParseIntPipe) size = 10,
31
31
  @Req() req: Request & { user: any },
32
32
  @Query() queryParams: Record<string, string>,
33
+ @Query('level_type') levelType?: string,
34
+ @Query('level_id') levelId?: number,
33
35
  ) {
34
36
  const loggedInUser = req.user.userData;
35
37
 
@@ -56,6 +58,8 @@ export class FilterController {
56
58
  size,
57
59
  loggedInUser,
58
60
  queryParams: otherQueryParams, // only remaining query params
61
+ customLevelType: levelType,
62
+ customLevelId: levelId,
59
63
  });
60
64
  }
61
65
 
@@ -27,4 +27,6 @@ export interface FilterRequestDto {
27
27
  size?: number;
28
28
  loggedInUser: UserData;
29
29
  queryParams?: Record<string, string>;
30
+ customLevelType?: string;
31
+ customLevelId?: number;
30
32
  }
@@ -79,6 +79,8 @@ export class FilterService {
79
79
  sortby,
80
80
  loggedInUser,
81
81
  queryParams,
82
+ customLevelType,
83
+ customLevelId,
82
84
  } = dto;
83
85
 
84
86
  // abstract user details
@@ -147,7 +149,14 @@ export class FilterService {
147
149
  const baseWhere = this.buildWhereClauses(baseFilters, attributeMetaMap);
148
150
 
149
151
  // check level_id and level_type
150
- if (entity_type != 'ORGP' && level_type && level_id && organization_id) {
152
+ if (
153
+ entity_type != 'ORGP' &&
154
+ level_type &&
155
+ level_id &&
156
+ organization_id &&
157
+ !customLevelType &&
158
+ !customLevelId
159
+ ) {
151
160
  baseWhere.push({
152
161
  query:
153
162
  'e.organization_id = :organization_id AND e.level_type = :level_type AND e.level_id = :level_id',
@@ -159,6 +168,18 @@ export class FilterService {
159
168
  });
160
169
  }
161
170
 
171
+ if (customLevelType && customLevelId) {
172
+ baseWhere.push({
173
+ query:
174
+ 'e.organization_id = :organization_id AND e.level_type = :customLevelType AND e.level_id = :customLevelId',
175
+ params: {
176
+ organization_id,
177
+ customLevelType,
178
+ customLevelId,
179
+ },
180
+ });
181
+ }
182
+
162
183
  // andWhere search with attributeName && attributeValue
163
184
  if (queryParams) {
164
185
  Object.entries(queryParams).forEach(([key, value]) => {
@@ -31,4 +31,7 @@ export class CommTemplate extends BaseEntity {
31
31
 
32
32
  @Column({ nullable: true })
33
33
  is_template: boolean;
34
+
35
+ @Column({ type: 'varchar', nullable: true })
36
+ flag: string;
34
37
  }
@@ -13,7 +13,10 @@ export class CommTemplateService extends EntityServiceImpl {
13
13
  async createEntity(entityData: any, loggedInUser: any): Promise<any> {
14
14
  const { attachments, ...templateData } = entityData;
15
15
 
16
- const tempData = await super.createEntity(templateData, loggedInUser);
16
+ const tempData = await super.createEntity(
17
+ { ...templateData, flag: templateData.flag || 'default' },
18
+ loggedInUser,
19
+ );
17
20
 
18
21
  // attachment mapper create and update
19
22
  if (attachments && attachments.length > 0) {
@@ -37,6 +40,23 @@ export class CommTemplateService extends EntityServiceImpl {
37
40
  async updateEntity(entityData: any, loggedInUser: UserData): Promise<any> {
38
41
  const { attachments, ...templateData } = entityData;
39
42
 
43
+ if (
44
+ loggedInUser.level_type === 'SCH' &&
45
+ templateData.level_type === 'ORG'
46
+ ) {
47
+ const { id, level_type, level_id, ...newTemplateData } = entityData;
48
+ const create = await this.createEntity(
49
+ {
50
+ ...newTemplateData,
51
+ level_type: loggedInUser.level_type,
52
+ level_id: loggedInUser.level_id,
53
+ flag: 'edited',
54
+ },
55
+ loggedInUser,
56
+ );
57
+ return create;
58
+ }
59
+
40
60
  const tempData = await super.updateEntity(templateData, loggedInUser);
41
61
 
42
62
  // delete existing mapper
@@ -441,59 +441,4 @@ export class TaskService extends EntityServiceImpl {
441
441
  console.log(notePayload);
442
442
  return await super.createEntity(notePayload, loggedInUser);
443
443
  }
444
-
445
- @Cron(CronExpression.EVERY_10_SECONDS)
446
- async fetchTasksDueIn30Mins() {
447
- const now = new Date();
448
- const in30Min = new Date(now.getTime() + 30 * 60 * 1000);
449
-
450
- const completedStatus = await this.dataSource.query(
451
- `SELECT id FROM cr_list_master_items WHERE name = 'completed' AND listtype = 'TKST' LIMIT 1;`,
452
- );
453
- const completedId = completedStatus[0]?.id;
454
-
455
- const tasks = await this.dataSource.query(
456
- `
457
- SELECT *
458
- FROM cr_wf_task_data
459
- WHERE status != ?
460
- AND TIMESTAMP(due_date, due_time) BETWEEN ? AND ?
461
- `,
462
- [completedId, now, in30Min],
463
- );
464
-
465
- if (tasks.length > 0) console.log('Tasks due in 30 mins', tasks);
466
-
467
- if (!tasks.length) {
468
- console.log('No tasks due in 30 mins');
469
- return;
470
- }
471
-
472
- for (const task of tasks) {
473
- const message = `Reminder: Task ${task.name} is due at ${task.due_time}`;
474
-
475
- await this.dataSource.query(
476
- `
477
- INSERT INTO cr_notification (user_id, event_type, message, entity_type, organization_id, created_date, mapped_entity_id, mapped_entity_type, level_id, level_type)
478
- VALUES (?, ?, ?, ?, ?, NOW(), ?, ?, ?, ?)
479
- `,
480
- [
481
- task.task_owner,
482
- 'Task Remainder',
483
- message,
484
- 'NOTF',
485
- task.organization_id,
486
- task.mapped_entity_id,
487
- task.mapped_entity_type,
488
- task.level_id,
489
- task.level_type,
490
- ],
491
- );
492
- await this.notificationsService.sendToUser(
493
- String(task.task_owner), // userId as string
494
- 'Task Reminder',
495
- message,
496
- );
497
- }
498
- }
499
444
  }