Re_Backend/src/jobs/form16NotificationJob.ts
2026-03-18 12:59:20 +05:30

82 lines
3.4 KiB
TypeScript

import { getForm16Config } from '../services/form16Config.service';
import { runForm16AlertSubmitJob, runForm16ReminderJob, runForm16Remind26AsUploadJob } from '../services/form16Notification.service';
import logger from '../utils/logger';
const TZ = process.env.TZ || 'Asia/Kolkata';
// 26AS reminder is quarter-based; we evaluate once daily at this fixed time.
const RE_26AS_REMINDER_CHECK_TIME = '08:30';
/** Last date (YYYY-MM-DD) we ran the alert job in the configured timezone. */
let lastAlertRunDate: string | null = null;
/** Last date (YYYY-MM-DD) we ran the reminder job in the configured timezone. */
let lastReminderRunDate: string | null = null;
/** Last date (YYYY-MM-DD) we ran the 26AS upload reminder job in the configured timezone. */
let last26AsReminderRunDate: string | null = null;
/**
* Get current time in configured TZ as HH:mm (24h, zero-padded).
*/
function getCurrentTimeHHmm(): string {
const now = new Date();
const str = now.toLocaleTimeString('en-CA', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: TZ });
const [h, m] = str.split(':').map((x) => parseInt(x, 10));
if (Number.isNaN(h) || Number.isNaN(m)) return '00:00';
return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;
}
/**
* Get current date in configured TZ as YYYY-MM-DD.
*/
function getCurrentDateString(): string {
const now = new Date();
const str = now.toLocaleDateString('en-CA', { timeZone: TZ });
return str;
}
/**
* Tick: run every minute; if current time matches config run-at time and we haven't run today, run the job.
*/
async function form16NotificationTick(): Promise<void> {
try {
const config = await getForm16Config();
const nowTime = getCurrentTimeHHmm();
const today = getCurrentDateString();
const alertTime = (config.alertSubmitForm16RunAtTime || '').trim();
if (config.alertSubmitForm16Enabled && alertTime && alertTime === nowTime && lastAlertRunDate !== today) {
lastAlertRunDate = today;
logger.info(`[Form16 Job] Running alert submit job (scheduled at ${alertTime})`);
await runForm16AlertSubmitJob();
}
const reminderTime = (config.reminderRunAtTime || '').trim();
if (config.reminderNotificationEnabled && reminderTime && reminderTime === nowTime && lastReminderRunDate !== today) {
lastReminderRunDate = today;
logger.info(`[Form16 Job] Running reminder job (scheduled at ${reminderTime})`);
await runForm16ReminderJob();
}
if (config.reminder26AsUploadEnabled && RE_26AS_REMINDER_CHECK_TIME === nowTime && last26AsReminderRunDate !== today) {
last26AsReminderRunDate = today;
logger.info(`[Form16 Job] Running 26AS upload reminder job (daily check at ${RE_26AS_REMINDER_CHECK_TIME})`);
await runForm16Remind26AsUploadJob();
}
} catch (e) {
logger.error('[Form16 Job] Tick error:', e);
}
}
/**
* Start Form 16 scheduled notification jobs.
* Schedule is read from Form 16 admin config (alertSubmitForm16RunAtTime, reminderRunAtTime).
* A tick runs every minute; when server time (in configured TZ) matches the run-at time, the job runs once that day.
*/
export function startForm16NotificationJobs(): void {
const cron = require('node-cron');
cron.schedule('* * * * *', () => {
form16NotificationTick();
}, { timezone: TZ });
logger.info(`[Form16 Job] Form 16 notification jobs scheduled (config-driven run times, TZ: ${TZ})`);
}