feat: add employee timing system, notification templates, and professor class plan sms
This commit is contained in:
@@ -100,6 +100,38 @@ const parseImportDate = (raw) => {
|
||||
return Number.isNaN(date.getTime()) ? null : date;
|
||||
};
|
||||
|
||||
const gregorianToJalali = (gy, gm, gd) => {
|
||||
const g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||
let jy;
|
||||
if (gy > 1600) {
|
||||
jy = 979;
|
||||
gy -= 1600;
|
||||
} else {
|
||||
jy = 0;
|
||||
gy -= 621;
|
||||
}
|
||||
const gy2 = gm > 2 ? gy + 1 : gy;
|
||||
let days = 365 * gy + Math.floor((gy2 + 3) / 4) - Math.floor((gy2 + 99) / 100) + Math.floor((gy2 + 399) / 400) - 80 + gd + g_d_m[gm - 1];
|
||||
jy += 33 * Math.floor(days / 12053);
|
||||
days %= 12053;
|
||||
jy += 4 * Math.floor(days / 1461);
|
||||
days %= 1461;
|
||||
if (days > 365) {
|
||||
jy += Math.floor((days - 1) / 365);
|
||||
days = (days - 1) % 365;
|
||||
}
|
||||
const jm = days < 186 ? 1 + Math.floor(days / 31) : 7 + Math.floor((days - 186) / 30);
|
||||
const jd = 1 + (days < 186 ? days % 31 : (days - 186) % 30);
|
||||
return `${jy}/${String(jm).padStart(2, '0')}/${String(jd).padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const formatJalaliDate = (rawDate) => {
|
||||
if (!rawDate) return '';
|
||||
const date = rawDate instanceof Date ? rawDate : new Date(rawDate);
|
||||
if (Number.isNaN(date.getTime())) return '';
|
||||
return gregorianToJalali(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate());
|
||||
};
|
||||
|
||||
const utcDayRange = (value) => {
|
||||
const date = parseImportDate(value);
|
||||
if (!date) return null;
|
||||
@@ -111,6 +143,8 @@ const utcDayRange = (value) => {
|
||||
module.exports = {
|
||||
toEnglishDigits,
|
||||
jalaliToGregorian,
|
||||
gregorianToJalali,
|
||||
formatJalaliDate,
|
||||
parseJalaliDate,
|
||||
parseImportDate,
|
||||
utcDayRange
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
const { sendSingleSms } = require('./sms.base');
|
||||
const { recordAndSend } = require('./notificationRecorder');
|
||||
const { getSmsTemplate } = require('../../components/settings/settingService');
|
||||
const { buildSmsParameters } = require('../../components/settings/smsTemplates');
|
||||
const { buildSmsParameters, renderSmsText } = require('../../components/settings/smsTemplates');
|
||||
const User = require('../../components/users/userModel');
|
||||
const logger = require('../logger');
|
||||
|
||||
@@ -33,22 +33,28 @@ const sendTemplateSms = async ({
|
||||
slotValues = {}
|
||||
}) => {
|
||||
const resolvedUserId = userId || await resolveUserIdByPhone(receiver);
|
||||
const { templateId, variables, enabled } = await getSmsTemplate(templateKey);
|
||||
const { templateId, variables, enabled, text: templateText } = await getSmsTemplate(templateKey);
|
||||
if (enabled === false) {
|
||||
logger.info(`[SMS] Template ${templateKey} is disabled. Skipping SMS send to ${receiver}.`);
|
||||
return { success: true, skipped: true, reason: 'template_disabled' };
|
||||
}
|
||||
|
||||
const paramsContext = {
|
||||
phoneNumber: receiver,
|
||||
mobile: receiver,
|
||||
...slotValues
|
||||
};
|
||||
|
||||
const renderedExactBody = renderSmsText(templateText, variables, paramsContext);
|
||||
const finalBody = (renderedExactBody && renderedExactBody.trim()) ? renderedExactBody.trim() : (body || subject || 'پیامک');
|
||||
|
||||
return recordAndSend({
|
||||
userId: resolvedUserId,
|
||||
channel: 'sms',
|
||||
subject,
|
||||
body,
|
||||
body: finalBody,
|
||||
relatedEvent,
|
||||
sendFn: () => sendSingleSms(receiver, templateId, buildSmsParameters(variables, {
|
||||
phoneNumber: receiver,
|
||||
mobile: receiver,
|
||||
...slotValues
|
||||
}))
|
||||
sendFn: () => sendSingleSms(receiver, templateId, buildSmsParameters(variables, paramsContext))
|
||||
});
|
||||
};
|
||||
|
||||
@@ -375,6 +381,27 @@ const sendCertificateIssuedSms = async (receiver, payload, userId = null) => {
|
||||
});
|
||||
};
|
||||
|
||||
const sendClassPlanProfessorSms = async (receiver, payload, userId = null) => {
|
||||
const data = payload || {};
|
||||
return sendTemplateSms({
|
||||
templateKey: 'classPlanProfessor',
|
||||
receiver,
|
||||
userId,
|
||||
subject: 'برنامه کلاس به استاد',
|
||||
body: `استاد ${data.professorName || ''}، برنامه کلاس ${data.className || ''}: ${data.classDays || ''}، ${data.classTimes || ''} از ${data.classStartDate || ''} الی ${data.classEndDate || ''}`,
|
||||
relatedEvent: 'class.plan_to_professor',
|
||||
slotValues: {
|
||||
professorName: data.professorName || 'استاد',
|
||||
className: data.className || '-',
|
||||
classDays: data.classDays || '',
|
||||
classTimes: data.classTimes || '',
|
||||
classStartDate: data.classStartDate || '',
|
||||
classEndDate: data.classEndDate || '',
|
||||
phoneNumber: receiver
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
sendAccountCreatedSms,
|
||||
sendPasswordResetSms,
|
||||
@@ -389,5 +416,6 @@ module.exports = {
|
||||
sendClassRequestApprovedSms,
|
||||
sendClassRequestRejectedSms,
|
||||
sendPendingRegistrationSms,
|
||||
sendCertificateIssuedSms
|
||||
sendCertificateIssuedSms,
|
||||
sendClassPlanProfessorSms
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user