import { Leave } from "./LeaveModel.js"; import { Attendance } from "../Attendance/AttendanceModel.js"; // Mark leave export const markLeave = async (req, res) => { try { const { date, time, location, reason, leaveType } = req.body; const userId = req.user._id; const userType = req.userType; // Parse the input date const [year, month, day] = date.split("/"); const parsedDate = new Date(Date.UTC(year, month - 1, day)); const today = new Date(); today.setUTCHours(0, 0, 0, 0); // Check if the date in req.body is not today's date if (parsedDate.getTime() !== today.getTime()) { return res.status(400).json({ success: false, message: `Leave can only be marked for today's date: ${ today.toISOString().split("T")[0] }`, }); } // Get the start and end of the day to check if the leave is already marked const startOfDay = new Date(parsedDate); const endOfDay = new Date(parsedDate); endOfDay.setUTCHours(23, 59, 59, 999); // Check if the leave record exists for today const existingLeave = await Leave.findOne({ userId, userType, records: { $elemMatch: { date: { $gte: startOfDay, $lte: endOfDay }, }, }, }); if (existingLeave) { return res.status(400).json({ success: false, message: "Leave for today is already marked.", }); } // Check if the attendance record exists for today const existingAttendance = await Attendance.findOne({ userId, userType, records: { $elemMatch: { date: { $gte: startOfDay, $lte: endOfDay }, }, }, }); if (existingAttendance) { return res.status(400).json({ success: false, message: "Attendance for today is already marked.", }); } // Check if leave record exists for the user let leave = await Leave.findOne({ userId, userType }); if (!leave) { // Create a new leave record if it doesn't exist leave = new Leave({ userId, userType, records: [], }); } // Add the new leave record to the array leave.records.push({ date: startOfDay, time, location, reason, leaveType }); await leave.save(); res.status(201).json({ success: true, message: "Leave marked successfully", record: { date: startOfDay, time, location, reason, leaveType }, }); } catch (error) { res.status(500).json({ success: false, message: error.message || "Something went wrong", }); } }; // Helper function to check if two dates are on the same day function isSameDay(date1, date2) { return ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate() ); } // Get leave by user ID export const getLeaveByUser = async (req, res) => { try { const userId = req.user._id; const leave = await Leave.findOne({ userId, }).populate("userId", "name email"); if (!leave) { return res.status(404).json({ success: false, message: "No leave records found for this user.", }); } res.status(200).json({ success: true, leave, }); } catch (error) { res.status(500).json({ success: false, message: error.message || "Something went wrong", }); } }; // Admin route to get leave by user ID export const AdmingetLeaveByUser = async (req, res) => { try { const { id } = req.params; const { page = 1, show = 10 } = req.query; const limit = parseInt(show); const skip = (page - 1) * limit; // Find leave records for the given user const leaveDoc = await Leave.findOne({ userId: id, }).populate("userId", "name email"); if (!leaveDoc) { return res.status(404).json({ success: false, message: "No leave records found for this user.", }); } // Pagination and slicing records const totalData = leaveDoc.records.length; const paginatedRecords = leaveDoc.records.slice(skip, skip + limit); res.status(200).json({ success: true, user: leaveDoc.userId, leave: paginatedRecords, userType: leaveDoc.userType, total_data: totalData, }); } catch (error) { res.status500().json({ success: false, message: error.message || "Something went wrong", }); } }; export const getTodayLeave = async (req, res) => { try { // Step 1: Get today's date in UTC and set the time to 00:00:00.000 const today = new Date(); const todayStartUTC = new Date( Date.UTC( today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate(), 0, 0, 0 ) ); const tomorrowStartUTC = new Date(todayStartUTC); tomorrowStartUTC.setUTCDate(todayStartUTC.getUTCDate() + 1); // Start of the next day // Step 2: Parse query parameters const { page = 1, show = 10 } = req.query; const limit = parseInt(show, 10); const skip = (page - 1) * limit; // Step 3: Aggregate query to get today's leave records const leavesWithUserLookup = await Leave.aggregate([ { $unwind: "$records" }, { $match: { "records.date": { $gte: todayStartUTC, $lt: tomorrowStartUTC, }, }, }, { $lookup: { from: "salescoordinators", localField: "userId", foreignField: "_id", as: "salesCoOrdinatorUser", }, }, { $lookup: { from: "territorymanagers", localField: "userId", foreignField: "_id", as: "territoryManagerUser", }, }, { $addFields: { user: { $cond: { if: { $eq: ["$userType", "SalesCoOrdinator"] }, then: { $arrayElemAt: ["$salesCoOrdinatorUser", 0] }, else: { $arrayElemAt: ["$territoryManagerUser", 0] }, }, }, }, }, { $project: { salesCoOrdinatorUser: 0, territoryManagerUser: 0, }, }, ]); // Step 4: Calculate total data const totalData = leavesWithUserLookup.length; // Step 5: Implement pagination const paginatedLeaves = leavesWithUserLookup.slice(skip, skip + limit); // Step 6: Format the response const formattedLeaves = paginatedLeaves.map((record) => ({ user: record.user ? { id: record.user._id, name: record.user.name, email: record.user.email, mobileNumber: record.user.mobileNumber, userType: record.userType, uniqueId: record.user.uniqueId, } : null, date: record.records.date, time: record.records.time, location: record.records.location, reason: record.records.reason, leaveType: record.records.leaveType, })); // Send response res.status(200).json({ success: true, total_data: totalData, leave: formattedLeaves, page: parseInt(page, 10), limit: limit, }); } catch (error) { console.error("Error fetching today’s leave:", error); res.status(500).json({ success: false, message: error.message || "Something went wrong", }); } };