node-cron 라이브러리를 사용하여 generateNextDates 함수를 정기적으로 불러 마지막 수업일과 현재 날짜가 같은 경우 23:59pm에 다음 회차에 대한 수업일들을 자동 생성한다.
이때, 피드백도 함께 생성해주며, 정산과 관련된 데이터들도 업데이트 및 생성해준다.
const db = require('../config/db');
const cron = require('node-cron');
const generateNextDates = async (classId) => {
try {
const getLastDateSql = `SELECT date FROM dates WHERE classid = ? ORDER BY date DESC LIMIT 1`;
const [lastDateResult] = await db.query(getLastDateSql, [classId]);
if (lastDateResult.length === 0) {
console.error(`No dates found for classId: ${classId}`);
return;
}
const lastDate = lastDateResult[0].date;
const getClassDetailsSql = `
SELECT time, period, day, prepay, hourlyrate
FROM classes
WHERE classid = ?`;
const [classDetailsResult] = await db.query(getClassDetailsSql, [classId]);
if (classDetailsResult.length === 0) {
console.error(`Class details not found for classId: ${classId}`);
return;
}
const { time, period, day, prepay, hourlyrate } = classDetailsResult[0];
const dayMap = { "월": 1, "화": 2, "수": 3, "목": 4, "금": 5, "토": 6, "일": 0 };
const classDays = day.split('/').map(d => dayMap[d]);
const nextDates = [];
let currentDate = new Date(lastDate);
let generatedDates = 0;
while (generatedDates < period) {
currentDate.setDate(currentDate.getDate() + 1); // Move to the next day
if (classDays.includes(currentDate.getDay())) {
nextDates.push({
classid: classId,
date: new Date(currentDate), // Clone the date
time,
feedback_written: 0,
createdAt: new Date(),
updatedAt: new Date(),
});
generatedDates++;
}
}
const insertDatesSql = `INSERT INTO dates (classid, date, time, feedback_written, createdAt, updatedAt) VALUES ?`;
const dateValues = nextDates.map(d => [d.classid, d.date, d.time, d.feedback_written, d.createdAt, d.updatedAt]);
const [dateInsertResult] = await db.query(insertDatesSql, [dateValues]);
const fetchDateIdsSql = `
SELECT dateid, date
FROM dates
WHERE classid = ? AND date > ?
ORDER BY date ASC`;
const [insertedDates] = await db.query(fetchDateIdsSql, [classId, lastDate]);
const feedbackEntries = insertedDates.map(d => [d.dateid, new Date(), new Date()]);
const insertFeedbackSql = `INSERT INTO feedback (dateid, createdAt, updatedAt) VALUES ?`;
await db.query(insertFeedbackSql, [feedbackEntries]);
const paymentDate = prepay
? nextDates[0].date // First date for prepay
: nextDates[nextDates.length - 1].date; // Last date otherwise
const paymentCost = period * hourlyrate * time;
const insertPaymentSql = `
INSERT INTO payment (date, cost, unpay, classid, updatedAt, createdAt)
VALUES (?, ?, 0, ?, NOW(), NOW())`;
const [paymentInsertResult] = await db.query(insertPaymentSql, [paymentDate, paymentCost, classId]);
const updateClassSql = `
UPDATE classes
SET dateofpayment = ?, paymentid = ?
WHERE classid = ?`;
await db.query(updateClassSql, [paymentDate, paymentInsertResult.insertId, classId]);
console.log(`Successfully generated dates, feedback, and payment for classId: ${classId}`);
} catch (err) {
console.error('Error generating next period dates:', err);
}
};
// Schedule to run daily at 11:59 PM
cron.schedule('59 23 * * *', async () => {
console.log("Running daily check for generating lesson dates at 11:59 PM...");
const sqlGetClasses = `SELECT classid FROM classes`;
try {
const [classes] = await db.query(sqlGetClasses);
for (const { classid } of classes) {
await generateNextDates(classid);
}
} catch (err) {
console.error("Error in scheduled task:", err);
}
});