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/dist/module/notification/controller/otp.controller.d.ts +1 -4
- package/dist/module/notification/controller/otp.controller.js +14 -1
- package/dist/module/notification/controller/otp.controller.js.map +1 -1
- package/dist/module/notification/notification.module.js +2 -0
- package/dist/module/notification/notification.module.js.map +1 -1
- package/dist/module/notification/service/email.service.d.ts +5 -6
- package/dist/module/notification/service/email.service.js +46 -15
- package/dist/module/notification/service/email.service.js.map +1 -1
- package/dist/module/workflow/service/populate-workflow.service.js +9 -5
- package/dist/module/workflow/service/populate-workflow.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/notification/controller/otp.controller.ts +15 -1
- package/src/module/notification/notification.module.ts +2 -0
- package/src/module/notification/service/email.service.ts +60 -13
- package/src/module/workflow/service/populate-workflow.service.ts +15 -6
- package/.vscode/extensions.json +0 -5
package/package.json
CHANGED
|
@@ -61,13 +61,27 @@ export class OtpController {
|
|
|
61
61
|
payload: any;
|
|
62
62
|
},
|
|
63
63
|
) {
|
|
64
|
-
//
|
|
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(
|
|
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
|
-
|
|
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
|
|
48
|
+
subject,
|
|
29
49
|
html: htmlContent,
|
|
50
|
+
attachments,
|
|
51
|
+
})
|
|
52
|
+
.then(() => {
|
|
53
|
+
console.log(`Email sent to ${email}`);
|
|
30
54
|
})
|
|
31
|
-
.
|
|
32
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
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
|
-
|
|
153
|
-
`SELECT * FROM cr_list_master_items WHERE code='STATUS_ACTIVE' AND organization_id =
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
313
|
+
status: statusValue,
|
|
305
314
|
},
|
|
306
315
|
loggedInUser,
|
|
307
316
|
);
|