import Task from "./TaskModel.js"; import crypto from "crypto"; import cron from "node-cron"; import { sendPushNotification } from "../../Utils/sendPushNotification.js"; import SalesCoOrdinator from "../SalesCoOrdinators/SalesCoOrdinatorModel.js"; import TerritoryManager from "../TerritoryManagers/TerritoryManagerModel.js"; // Function to update task statuses export const updateOverdueTasks = async () => { try { const currentDate = new Date(); const currentDateOnly = new Date(currentDate.setHours(0, 0, 0, 0)); // Find tasks where dueDate is before the current date and status is "New" const overdueTasks = await Task.find({ taskDueDate: { $lt: currentDateOnly }, taskStatus: "New", }); // Update tasks to "Pending" for (const task of overdueTasks) { task.taskStatus = "Pending"; await task.save(); // Fetch the Sales Coordinator who is assigned the task const salesCoordinator = await SalesCoOrdinator.findById(task.taskAssignedTo); if (salesCoordinator) { const fcmToken = salesCoordinator.fcm_token; if (fcmToken) { // Send push notification const message = `Your task "${task.task}" is Pending.`; await sendPushNotification(fcmToken, "Task Status Updated", message); } } } console.log('Overdue tasks updated to "Pending".'); } catch (error) { console.error("Error updating overdue tasks:", error); } }; // Schedule the cron job to run daily at midnight // cron.schedule("5 9 * * *", updateOverdueTasks, { // timezone: "Asia/Kolkata", // }); // cron.schedule("30 9 * * *", updateOverdueTasks); const parseDate = (dateStr) => { const [day, month, year] = dateStr.split("/").map(Number); // Create a date object in local timezone const localDate = new Date(year, month - 1, day); // Convert to a date with time set to the start of the day in UTC return new Date(Date.UTC(year, month - 1, day)); }; export const assignTask = async (req, res) => { try { const { task, note, taskPriority, taskDueDate, taskAssignedTo, addedFor, addedForId, tradename, } = req.body; // Convert the taskDueDate from DD/MM/YYYY string to Date object const dueDate = parseDate(taskDueDate); const currentDate = new Date(); // Set the time of the currentDate to the start of the day for comparison const currentDateOnly = new Date( Date.UTC( currentDate.getUTCFullYear(), currentDate.getUTCMonth(), currentDate.getUTCDate() ) ); // Check if the due date is in the past if (dueDate < currentDateOnly) { return res.status(400).json({ success: false, message: "Due date cannot be earlier than the current date.", }); } const currentYear = new Date().getFullYear().toString().slice(-2); const randomChars = crypto.randomBytes(4).toString("hex").toUpperCase(); const uniqueId = `${currentYear}-${randomChars}`; // Create a new task const newTask = await Task.create({ taskId: uniqueId, task, note, taskStatus: "New", taskPriority, taskDueDate: dueDate, // Save the date as a Date object taskAssignedTo, taskAssignedBy: req.user._id, addedFor, addedForId, tradename, }); // Fetch the FCM token of the assigned sales coordinator const salesCoordinator = await SalesCoOrdinator.findById(taskAssignedTo); if (!salesCoordinator) { return res.status(404).json({ success: false, message: "Sales Coordinator not found.", }); } const fcmToken = salesCoordinator.fcm_token; if (fcmToken) { // Send push notification const message = `You have been assigned a new task: ${task}`; await sendPushNotification(fcmToken, "New Task Assigned", message); } res.status(201).json({ success: true, message: "Task assigned successfully", task: newTask, }); } catch (error) { res.status(400).json({ success: false, message: error.message, }); } }; export const getTasksByStatus = async (req, res) => { try { const { status } = req.params; // This should be "New", "Pending", or "Completed" // Validate the provided status if (!["New", "Pending", "Completed"].includes(status)) { return res.status(400).json({ success: false, message: "Invalid status type provided.", }); } // Find tasks assigned to the user, filtered by status, and sorted by creation date (newest to oldest) const tasks = await Task.find({ taskAssignedTo: req.user._id, taskStatus: status, }).sort({ createdAt: -1 }); // Sort by createdAt in descending order (-1 means newest first) res.status(200).json({ success: true, tasks, }); } catch (error) { res.status(500).json({ success: false, message: error.message, }); } }; export const getAllTasksByStatus = async (req, res) => { try { const { status } = req.params; // This should be "New", "Pending", or "Completed" // Validate the provided status if (!["New", "Pending", "Completed"].includes(status)) { return res.status(400).json({ success: false, message: "Invalid status type provided.", }); } // Find tasks assigned to the user, filtered by status, and sorted by creation date (newest to oldest) const tasks = await Task.find({ taskAssignedBy: req.user._id, taskStatus: status, }) .populate({ path: "taskAssignedTo", select: "name mobileNumber email", }) .sort({ createdAt: -1 }); // Sort by createdAt in descending order (-1 means newest first) res.status(200).json({ success: true, tasks, }); } catch (error) { res.status(500).json({ success: false, message: error.message, }); } }; export const getTasksbytask = async (req, res) => { try { const { task } = req.params; // Validate the provided status if ( ![ "Visit RD/PD", "Update Sales Data", "Update Inventory Data", "Collect KYC", "Update Sales", ].includes(task) ) { return res.status(400).json({ success: false, message: "Invalid task type provided.", }); } const tasks = await Task.find({ taskAssignedTo: req.user._id, task: task, }).sort({ createdAt: -1 }); res.status(200).json({ success: true, tasks, }); } catch (error) { res.status(500).json({ success: false, message: error.message, }); } }; export const updateTaskStatus = async (req, res) => { try { const { taskId } = req.params; const task = await Task.findOne({ _id: taskId, taskAssignedTo: req.user._id, }); if (!task) { return res.status(404).json({ success: false, message: "Task not found or you're not authorized to update this task.", }); } // Update the task status to "Completed" task.taskStatus = "Completed"; await task.save(); // Fetch the Sales Coordinator who completed the task const salesCoordinator = await SalesCoOrdinator.findById(req.user._id); if (!salesCoordinator) { return res.status(404).json({ success: false, message: "Sales Coordinator not found.", }); } // Fetch the FCM token of the Territory Manager const territoryManager = await TerritoryManager.findById(task.taskAssignedBy); if (!territoryManager) { return res.status(404).json({ success: false, message: "Territory Manager not found.", }); } const fcmToken = territoryManager.fcm_token; if (fcmToken) { // Send push notification const message = `Task "${task.task}" has been completed by ${salesCoordinator.name}.`; await sendPushNotification(fcmToken, "Task Completed", message); } res.status(200).json({ success: true, message: "Task status updated to Completed.", task, }); } catch (error) { res.status(400).json({ success: false, message: error.message, }); } };