202 lines
7.7 KiB
JavaScript
202 lines
7.7 KiB
JavaScript
const http = require('http');
|
|
const db = require('./config/dbproc.js');
|
|
|
|
const RECIPIENT = 'rizki.rmdhn1304@gmail.com';
|
|
|
|
function buildHtml(approverName, title, priorName, idxjustification, remark, status) {
|
|
const url = status === 'RETURNED'
|
|
? `https://e-portal.telkomcel.tl/app/ext/eproc/justifikasi/${idxjustification}/edit`
|
|
: `https://e-portal.telkomcel.tl/app/ext/eproc/circulation/${idxjustification}`;
|
|
const statusLabel = status || 'READY FOR APPROVAL';
|
|
const notesLine = remark ? ` <li><strong>Notes:</strong> ${remark}</li>\n` : '';
|
|
return `<p>Dear ${approverName},</p>
|
|
|
|
<p>A new workflow task requires your review and approval. Please find the details regarding this justification below:</p>
|
|
|
|
<ul>
|
|
<li><strong>Justification:</strong> ${title}</li>
|
|
<li><strong>Task Type:</strong> OPEN</li>
|
|
<li><strong>Status:</strong> ${statusLabel}</li>
|
|
${notesLine} <li><strong>Sent By:</strong> ${priorName}</li>
|
|
</ul>
|
|
|
|
<p><strong>Action Required:</strong><br>
|
|
Please access the document and complete the approval via the E-Procurement Portal using the link below:<br>
|
|
<a href="${url}">${url}</a></p>
|
|
|
|
<p>If you have any questions or require further clarification, please do not hesitate to contact the Procurement Division.</p>
|
|
|
|
<p>Thank you for your attention and cooperation.</p>
|
|
|
|
<p>Best regards,<br>
|
|
Procurement Division<br>
|
|
Finance Business Partner Unit</p>`;
|
|
}
|
|
|
|
function logEmail(trxId, toEmail, subject, html, fromEmail, status, responseMessage) {
|
|
const qry = `
|
|
INSERT INTO email_logs (trx_id, to_email, subject, body, from_email, is_attachment, status, response_message, created_at)
|
|
VALUES (?, ?, ?, ?, ?, 0, ?, ?, NOW())
|
|
`;
|
|
db.query(qry, [trxId, toEmail, subject, html, fromEmail, status, responseMessage], function(err) {
|
|
if (err) console.error('[email-notif] logEmail failed:', err.message);
|
|
});
|
|
}
|
|
|
|
function postEmail(approverName, title, priorName, idxjustification, remark, status) {
|
|
const subject = status === 'RETURNED'
|
|
? `[Returned] Justification for ${title}`
|
|
: `[Approval Required] Justification for ${title}`;
|
|
const html = buildHtml(approverName, title, priorName, idxjustification, remark, status);
|
|
const payload = JSON.stringify({
|
|
to: [RECIPIENT],
|
|
cc: [],
|
|
bcc: [],
|
|
subject,
|
|
html
|
|
});
|
|
|
|
const req = http.request({
|
|
hostname: 'localhost',
|
|
port: 7004,
|
|
path: '/api/email/send-telkomcel',
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': Buffer.byteLength(payload)
|
|
}
|
|
}, (res) => {
|
|
let body = '';
|
|
res.on('data', (chunk) => { body += chunk; });
|
|
res.on('end', () => {
|
|
let trxId = '';
|
|
let responseMessage = body;
|
|
try {
|
|
const parsed = JSON.parse(body);
|
|
trxId = parsed?.data?.trx_id || '';
|
|
responseMessage = JSON.stringify(parsed);
|
|
} catch (_) {}
|
|
|
|
const logStatus = res.statusCode >= 200 && res.statusCode < 300 ? 'success' : 'failed';
|
|
console.log('[email-notif] sent, status:', res.statusCode, '| trxId:', trxId);
|
|
logEmail(trxId, RECIPIENT, subject, html, '', logStatus, responseMessage);
|
|
});
|
|
});
|
|
|
|
req.on('error', (err) => {
|
|
console.error('[email-notif] failed:', err.message);
|
|
logEmail('', RECIPIENT, subject, html, '', 'failed', err.message);
|
|
});
|
|
|
|
req.write(payload);
|
|
req.end();
|
|
}
|
|
|
|
/**
|
|
* Notify first approver when justification is submitted.
|
|
*/
|
|
function notifyOnSubmit(idxjustification) {
|
|
const qryJustification = `
|
|
select j.title, j.remark, e.fullname as creator_name
|
|
from tbl_justification j
|
|
join dbssotcel.tbl_employee e on e.nik = j.iby
|
|
where j._idx = '${idxjustification}' limit 1
|
|
`;
|
|
db.query(qryJustification, [], function(err, rows) {
|
|
if (err || rows.length === 0) {
|
|
console.error('[email-notif] notifyOnSubmit: failed to get justification data', err);
|
|
return;
|
|
}
|
|
const title = rows[0].title;
|
|
const remark = rows[0].remark || '';
|
|
const creatorName = rows[0].creator_name;
|
|
|
|
const qryApprover = `
|
|
select t.nik, e.fullname
|
|
from tbl_justificationttd t
|
|
join dbssotcel.tbl_employee e on e.nik = t.nik
|
|
where t.idxjustification = '${idxjustification}' and t.issigned = 0 and t.isdeleted = 0
|
|
order by t._idx asc limit 1
|
|
`;
|
|
db.query(qryApprover, [], function(err2, rows2) {
|
|
if (err2 || rows2.length === 0) {
|
|
console.error('[email-notif] notifyOnSubmit: no approver found', err2);
|
|
return;
|
|
}
|
|
postEmail(rows2[0].fullname, title, creatorName, idxjustification, remark);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Notify next approver after someone signs.
|
|
*/
|
|
function notifyOnSigned(idxjustification, signerNik) {
|
|
const qryTitle = `select title, remark from tbl_justification where _idx = '${idxjustification}' limit 1`;
|
|
db.query(qryTitle, [], function(err, rows) {
|
|
if (err || rows.length === 0) {
|
|
console.error('[email-notif] notifyOnSigned: failed to get justification title', err);
|
|
return;
|
|
}
|
|
const title = rows[0].title;
|
|
const remark = rows[0].remark || '';
|
|
|
|
const qrySigner = `select fullname from dbssotcel.tbl_employee where nik = '${signerNik}' limit 1`;
|
|
db.query(qrySigner, [], function(err2, rows2) {
|
|
if (err2 || rows2.length === 0) {
|
|
console.error('[email-notif] notifyOnSigned: failed to get signer name', err2);
|
|
return;
|
|
}
|
|
const signerName = rows2[0].fullname;
|
|
|
|
const qryNext = `
|
|
select t.nik, e.fullname
|
|
from tbl_justificationttd t
|
|
join dbssotcel.tbl_employee e on e.nik = t.nik
|
|
where t.idxjustification = '${idxjustification}' and t.issigned = 0 and t.isdeleted = 0
|
|
order by t._idx asc limit 1
|
|
`;
|
|
db.query(qryNext, [], function(err3, rows3) {
|
|
if (err3 || rows3.length === 0) {
|
|
console.log('[email-notif] notifyOnSigned: no more approvers to notify');
|
|
return;
|
|
}
|
|
postEmail(rows3[0].fullname, title, signerName, idxjustification, remark);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Notify creator when justification is returned.
|
|
*/
|
|
function notifyOnReturn(idxjustification, returnerNik) {
|
|
const qryJustification = `
|
|
select j.title, j.remark, e.fullname as creator_name
|
|
from tbl_justification j
|
|
join dbssotcel.tbl_employee e on e.nik = j.iby
|
|
where j._idx = '${idxjustification}' limit 1
|
|
`;
|
|
db.query(qryJustification, [], function(err, rows) {
|
|
if (err || rows.length === 0) {
|
|
console.error('[email-notif] notifyOnReturn: failed to get justification data', err);
|
|
return;
|
|
}
|
|
const title = rows[0].title;
|
|
const remark = rows[0].remark || '';
|
|
const creatorName = rows[0].creator_name;
|
|
|
|
const qryReturner = `select fullname from dbssotcel.tbl_employee where nik = '${returnerNik}' limit 1`;
|
|
db.query(qryReturner, [], function(err2, rows2) {
|
|
if (err2 || rows2.length === 0) {
|
|
console.error('[email-notif] notifyOnReturn: failed to get returner name', err2);
|
|
return;
|
|
}
|
|
const returnerName = rows2[0].fullname;
|
|
postEmail(creatorName, title, returnerName, idxjustification, remark, 'RETURNED');
|
|
});
|
|
});
|
|
}
|
|
|
|
module.exports = { notifyOnSubmit, notifyOnSigned, notifyOnReturn };
|