82 lines
3.4 KiB
TypeScript
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})`);
|
|
}
|