rez_core 2.2.119 → 2.2.121

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.119",
3
+ "version": "2.2.121",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -61,13 +61,27 @@ export class OtpController {
61
61
  payload: any;
62
62
  },
63
63
  ) {
64
- // return await this.emailService.sendEmail(email, 'Harry', '123456');
64
+ // console.log('result', result);
65
65
  return await this.emailService.sendEmailWithDynamicTemplate(
66
66
  body.to,
67
67
  body.subject,
68
68
  body.message,
69
69
  body.templateCode,
70
70
  body.payload,
71
+ {
72
+ title: 'Project Kickoff Meeting',
73
+ description: 'Discuss goals and deliverables',
74
+ startsAt: '2025-08-30T10:00:00+05:30',
75
+ durationMinutes: 60,
76
+ meetingUrl: 'https://meet.google.com/xyz-1234-abc',
77
+ location: 'Google Meet',
78
+ organizerName: 'Darshil',
79
+ organizerEmail: 'sample@sample',
80
+ attendees: [
81
+ { name: 'John Doe', email: 'john@example.com' },
82
+ { name: 'Jane Smith', email: 'jane@example.com' },
83
+ ],
84
+ },
71
85
  );
72
86
  }
73
87
  }
@@ -11,6 +11,7 @@ import { join } from 'path';
11
11
  import { ConfigModule, ConfigService } from '@nestjs/config';
12
12
  import { AuthModule } from '../auth/auth.module';
13
13
  import { UserModule } from '../user/user.module';
14
+ import { IcsMeetingModule } from '../ics/ics.module';
14
15
 
15
16
  @Module({
16
17
  imports: [
@@ -42,6 +43,7 @@ import { UserModule } from '../user/user.module';
42
43
  }),
43
44
  AuthModule,
44
45
  UserModule,
46
+ IcsMeetingModule,
45
47
  ],
46
48
  providers: [OtpService, OtpRepository, EmailService],
47
49
  exports: [OtpService, EmailService],
@@ -2,34 +2,63 @@ import { Injectable } from '@nestjs/common';
2
2
  import { MailerService } from '@nestjs-modules/mailer';
3
3
  import * as Handlebars from 'handlebars';
4
4
  import { DataSource } from 'typeorm';
5
+ import { IcsMeetingService } from 'src/module/ics/service/ics.service';
5
6
 
6
7
  @Injectable()
7
8
  export class EmailService {
8
9
  constructor(
9
10
  private readonly mailerService: MailerService,
10
11
  private readonly datasource: DataSource,
12
+ private readonly icsService: IcsMeetingService,
11
13
  ) {}
12
14
 
13
- async sendEmail(email: string, subject: string, context?: any) {
15
+ async sendEmail(
16
+ email: string,
17
+ subject: string,
18
+ context?: any,
19
+ icsPayload?: any,
20
+ ) {
14
21
  const template = await this.datasource
15
22
  .getRepository('cr_wf_comm_template')
16
23
  .findOne({ where: { code: 'OTP_TEMPLATE' } });
17
24
 
18
- if (!template) {
19
- return;
20
- }
25
+ if (!template) return;
21
26
 
22
27
  const compiled = Handlebars.compile(template.rich_text || '');
23
28
  const htmlContent = compiled(context);
24
29
 
25
- this.mailerService
30
+ let attachments: any[] = [];
31
+
32
+ if (icsPayload) {
33
+ const icsBase64 = await this.icsService.generateIcs(icsPayload);
34
+ if (icsBase64) {
35
+ attachments.push({
36
+ filename: 'invite.ics',
37
+ content: icsBase64,
38
+ encoding: 'base64',
39
+ contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
40
+ });
41
+ }
42
+ }
43
+
44
+ // fire-and-forget
45
+ const result = await this.mailerService
26
46
  .sendMail({
27
47
  to: email,
28
- subject: subject,
48
+ subject,
29
49
  html: htmlContent,
50
+ attachments,
51
+ })
52
+ .then(() => {
53
+ console.log(`Email sent to ${email}`);
30
54
  })
31
- .then(() => {})
32
- .catch(() => {});
55
+ .catch((err) => {
56
+ console.error(`Failed to send email to ${email}`, err);
57
+ // Optionally: push to a retry queue, Sentry, DB log, etc.
58
+ });
59
+
60
+ console.log(result); // Return immediately (parent doesn’t block)
61
+ return;
33
62
  }
34
63
 
35
64
  async sendEmailWithDynamicTemplate(
@@ -38,6 +67,7 @@ export class EmailService {
38
67
  templateCode: string,
39
68
  message?: string,
40
69
  context?: any,
70
+ icsPayload?: any,
41
71
  ) {
42
72
  // retrieve the rich_text from the database table cr_wf_comm_template for the given templateCode
43
73
 
@@ -46,14 +76,16 @@ export class EmailService {
46
76
  .findOne({ where: { code: templateCode } });
47
77
 
48
78
  if (!template) {
49
- return {
50
- success: false,
51
- message: `Template with code ${templateCode} not found`,
52
- };
79
+ console.log(`Template with code ${templateCode} not found`);
80
+
81
+ // return {
82
+ // success: false,
83
+ // message: `Template with code ${templateCode} not found`,
84
+ // };
53
85
  }
54
86
 
55
87
  // Compile the template string with Handlebars
56
- const templateString = template.rich_text || '';
88
+ const templateString = template?.rich_text || '';
57
89
 
58
90
  let compiled;
59
91
  if (message) {
@@ -63,10 +95,25 @@ export class EmailService {
63
95
  }
64
96
  const htmlContent = compiled(context);
65
97
 
98
+ let attachments: any[] = [];
99
+
100
+ if (icsPayload) {
101
+ const icsBase64 = await this.icsService.generateIcs(icsPayload);
102
+ if (icsBase64) {
103
+ attachments.push({
104
+ filename: 'invite.ics',
105
+ content: icsBase64,
106
+ encoding: 'base64',
107
+ contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
108
+ });
109
+ }
110
+ }
111
+
66
112
  await this.mailerService.sendMail({
67
113
  to: email,
68
114
  subject: subject,
69
115
  html: htmlContent,
116
+ attachments,
70
117
  });
71
118
  }
72
119
  }
@@ -149,10 +149,19 @@ export class PopulateWorkflowService extends EntityServiceImpl {
149
149
  );
150
150
  const [workflows, stageGroups, stages] = factoryData;
151
151
 
152
- const status_name = await this.dataSource.query(
153
- `SELECT * FROM cr_list_master_items WHERE code='STATUS_ACTIVE' AND organization_id = 1`,
152
+ let statusRow = await this.dataSource.query(
153
+ `SELECT * FROM cr_list_master_items WHERE code='STATUS_ACTIVE' AND organization_id = ?`,
154
+ [organization_id],
154
155
  );
155
156
 
157
+ if (statusRow.length === 0) {
158
+ statusRow = await this.dataSource.query(
159
+ `SELECT * FROM cr_list_master_items WHERE code='STATUS_ACTIVE' AND organization_id = -1`,
160
+ );
161
+ }
162
+
163
+ const statusValue = statusRow[0]?.name ?? 'Active';
164
+
156
165
  // === 1. Workflow mapping
157
166
  const workflowIdMap: Record<number, number> = {};
158
167
  for (const row of workflows) {
@@ -163,7 +172,7 @@ export class PopulateWorkflowService extends EntityServiceImpl {
163
172
  organization_id,
164
173
  level_id: organization_id,
165
174
  entity_type: 'WRFW',
166
- status: status_name[0].name,
175
+ status: statusValue,
167
176
  },
168
177
  loggedInUser,
169
178
  );
@@ -190,7 +199,7 @@ export class PopulateWorkflowService extends EntityServiceImpl {
190
199
  organization_id,
191
200
  level_id: organization_id,
192
201
  entity_type: 'STGP',
193
- status: status_name[0].name,
202
+ status: statusValue,
194
203
  },
195
204
  loggedInUser,
196
205
  );
@@ -213,7 +222,7 @@ export class PopulateWorkflowService extends EntityServiceImpl {
213
222
  organization_id,
214
223
  level_id: organization_id,
215
224
  entity_type: 'STG',
216
- status: status_name[0].name,
225
+ status: statusValue,
217
226
  },
218
227
  loggedInUser,
219
228
  );
@@ -301,7 +310,7 @@ export class PopulateWorkflowService extends EntityServiceImpl {
301
310
  level_id: organization_id,
302
311
  entity_type: 'ACTN',
303
312
  form: formActionCategory.length > 0 ? formViewMaster[0]?.id : null,
304
- status: status_name[0].name,
313
+ status: statusValue,
305
314
  },
306
315
  loggedInUser,
307
316
  );
@@ -1,5 +0,0 @@
1
- {
2
- "recommendations": [
3
- "dbaeumer.vscode-eslint"
4
- ]
5
- }