attendance section update
This commit is contained in:
parent
db4fd7a834
commit
1f5630586b
4
app.js
4
app.js
@ -170,7 +170,7 @@ import CouponRoute from "./resources/Affiliate&Coupon/Coupon/CouponRoute.js";
|
|||||||
// import ShortUrlRouter from "./resources/Businesses/Short_Urls/ShortUrlRoute.js";
|
// import ShortUrlRouter from "./resources/Businesses/Short_Urls/ShortUrlRoute.js";
|
||||||
//support Ticket
|
//support Ticket
|
||||||
// attandance
|
// attandance
|
||||||
import attandanceSalesCoordinator from "./resources/SalesCoOrdinatorAttandance/AttandanceSalesCoordinatorRoute.js"
|
import attendance from "./resources/Attendance/AttandanceRoute.js"
|
||||||
app.use("/api/v1/", user);
|
app.use("/api/v1/", user);
|
||||||
|
|
||||||
//Product
|
//Product
|
||||||
@ -227,7 +227,7 @@ app.use("/api/v1/coupon", CouponRoute);
|
|||||||
//Blog
|
//Blog
|
||||||
app.use("/api/v1/blog", BlogRoute);
|
app.use("/api/v1/blog", BlogRoute);
|
||||||
//attendance
|
//attendance
|
||||||
app.use("/api/v1/salescoordinator", attandanceSalesCoordinator);
|
app.use("/api/v1/", attendance);
|
||||||
|
|
||||||
//config specialty
|
//config specialty
|
||||||
// app.use("/api/config/specialty", SpecialtiesRouter);
|
// app.use("/api/config/specialty", SpecialtiesRouter);
|
||||||
|
@ -6,23 +6,23 @@ export const isAuthenticatedSalesCoOrdinator = async (req, res, next) => {
|
|||||||
if (!req.headers.authorization) {
|
if (!req.headers.authorization) {
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Please Login to access this resource",
|
message: "Please login to access this resource",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const getToken = req.headers;
|
const getToken = req.headers.authorization;
|
||||||
// Remove Bearer from token
|
const token = getToken.slice(7);
|
||||||
const fronttoken = getToken.authorization.slice(7);
|
|
||||||
|
|
||||||
const frontdecoded = jwt.verify(fronttoken, process.env.JWT_SECRET);
|
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
||||||
if (!frontdecoded) {
|
if (!decoded) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Incorrect token",
|
message: "Incorrect token",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const salescoordinator = await SalesCoOrdinator.findById(frontdecoded.id);
|
const salescoordinator = await SalesCoOrdinator.findById(decoded.id);
|
||||||
if (salescoordinator) {
|
if (salescoordinator) {
|
||||||
req.salescoordinator = salescoordinator;
|
req.user = salescoordinator;
|
||||||
|
req.userType = 'SalesCoOrdinator';
|
||||||
return next();
|
return next();
|
||||||
} else {
|
} else {
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
@ -34,11 +34,7 @@ export const isAuthenticatedSalesCoOrdinator = async (req, res, next) => {
|
|||||||
if (error.name === "TokenExpiredError") {
|
if (error.name === "TokenExpiredError") {
|
||||||
return res.status(401).json({ message: "Token has expired." });
|
return res.status(401).json({ message: "Token has expired." });
|
||||||
} else if (error.name === "JsonWebTokenError") {
|
} else if (error.name === "JsonWebTokenError") {
|
||||||
if (error.message === "invalid signature") {
|
|
||||||
return res.status(401).json({ message: "Invalid token!." });
|
|
||||||
} else {
|
|
||||||
return res.status(401).json({ message: "Invalid token." });
|
return res.status(401).json({ message: "Invalid token." });
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return res.status(500).json({
|
return res.status(500).json({
|
||||||
message: "An internal error occurred while verifying the token.",
|
message: "An internal error occurred while verifying the token.",
|
||||||
|
102
resources/Attendance/AttandanceRoute.js
Normal file
102
resources/Attendance/AttandanceRoute.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// import express from "express";
|
||||||
|
// import {
|
||||||
|
// markAttendance,
|
||||||
|
// getAttendanceBySalesCoordinator,
|
||||||
|
// getTodayAttendance,
|
||||||
|
// AdmingetAttendanceBySalesCoordinator,
|
||||||
|
// } from "./AttandanceController.js";
|
||||||
|
// import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
||||||
|
// import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
|
||||||
|
|
||||||
|
// const router = express.Router();
|
||||||
|
|
||||||
|
// // Place more specific routes first
|
||||||
|
|
||||||
|
// // Route to get today's attendance for admin
|
||||||
|
// router.get(
|
||||||
|
// "/attendance/today",
|
||||||
|
// isAuthenticatedUser,
|
||||||
|
// authorizeRoles("admin"),
|
||||||
|
// getTodayAttendance
|
||||||
|
// );
|
||||||
|
|
||||||
|
// // Route to mark attendance
|
||||||
|
// router.post("/attendance", isAuthenticatedSalesCoOrdinator, markAttendance);
|
||||||
|
|
||||||
|
// // Route to get attendance for the logged-in sales coordinator
|
||||||
|
// router.get(
|
||||||
|
// "/attendance",
|
||||||
|
// isAuthenticatedSalesCoOrdinator,
|
||||||
|
// getAttendanceBySalesCoordinator
|
||||||
|
// );
|
||||||
|
|
||||||
|
// // Admin route to get attendance by sales coordinator ID
|
||||||
|
// router.get(
|
||||||
|
// "/attendance/:id",
|
||||||
|
// isAuthenticatedUser,
|
||||||
|
// authorizeRoles("admin"),
|
||||||
|
// AdmingetAttendanceBySalesCoordinator
|
||||||
|
// );
|
||||||
|
|
||||||
|
// export default router;
|
||||||
|
|
||||||
|
import express from "express";
|
||||||
|
import {
|
||||||
|
markAttendance,
|
||||||
|
getAttendanceByUser,
|
||||||
|
getTodayAttendance,
|
||||||
|
AdmingetAttendanceByUser,
|
||||||
|
} from "./AttendanceController.js";
|
||||||
|
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
||||||
|
// import { isAuthenticatedTerritoryManager } from "../../middlewares/TerritoryManagerAuth.js";
|
||||||
|
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
// Place more specific routes first
|
||||||
|
|
||||||
|
// Route to get today's attendance for admin
|
||||||
|
router.get(
|
||||||
|
"/attendance/today",
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
getTodayAttendance
|
||||||
|
);
|
||||||
|
|
||||||
|
// Route to mark attendance for Sales Coordinators
|
||||||
|
router.post(
|
||||||
|
"/attendance/salescoordinator",
|
||||||
|
isAuthenticatedSalesCoOrdinator,
|
||||||
|
markAttendance
|
||||||
|
);
|
||||||
|
|
||||||
|
// Route to mark attendance for Territory Managers
|
||||||
|
router.post(
|
||||||
|
"/attendance/territorymanager",
|
||||||
|
// isAuthenticatedTerritoryManager,
|
||||||
|
markAttendance
|
||||||
|
);
|
||||||
|
|
||||||
|
// Route to get attendance for the logged-in sales coordinator
|
||||||
|
router.get(
|
||||||
|
"/attendance/salescoordinator",
|
||||||
|
isAuthenticatedSalesCoOrdinator,
|
||||||
|
getAttendanceByUser
|
||||||
|
);
|
||||||
|
|
||||||
|
// Route to get attendance for the logged-in territory manager
|
||||||
|
router.get(
|
||||||
|
"/attendance/territorymanager",
|
||||||
|
// isAuthenticatedTerritoryManager,
|
||||||
|
getAttendanceByUser
|
||||||
|
);
|
||||||
|
|
||||||
|
// Admin route to get attendance by user ID
|
||||||
|
router.get(
|
||||||
|
"/attendance/:id",
|
||||||
|
isAuthenticatedUser,
|
||||||
|
authorizeRoles("admin"),
|
||||||
|
AdmingetAttendanceByUser
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
383
resources/Attendance/AttendanceController.js
Normal file
383
resources/Attendance/AttendanceController.js
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
// import { Attendance } from "./AttandanceModel.js";
|
||||||
|
|
||||||
|
// export const markAttendance = async (req, res) => {
|
||||||
|
// try {
|
||||||
|
// const { date, time, location, notes } = req.body;
|
||||||
|
// const salesCoordinatorId = req.user._id;
|
||||||
|
|
||||||
|
// // Get the start and end of the day to check if the attendance is already marked
|
||||||
|
// const startOfDay = new Date(date);
|
||||||
|
// startOfDay.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// const endOfDay = new Date(date);
|
||||||
|
// endOfDay.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
// // Check if the attendance record exists for today
|
||||||
|
// const existingAttendance = await AttendanceSalesCoOrdinator.findOne({
|
||||||
|
// salesCoordinator: salesCoordinatorId,
|
||||||
|
// "records.date": { $gte: startOfDay, $lte: endOfDay },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// if (existingAttendance) {
|
||||||
|
// return res.status(400).json({
|
||||||
|
// success: false,
|
||||||
|
// message: "Attendance for today is already marked.",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Check if attendance record exists for the sales coordinator
|
||||||
|
// let attendance = await AttendanceSalesCoOrdinator.findOne({
|
||||||
|
// salesCoordinator: salesCoordinatorId,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// if (!attendance) {
|
||||||
|
// // Create a new attendance record if it doesn't exist
|
||||||
|
// attendance = new AttendanceSalesCoOrdinator({
|
||||||
|
// salesCoordinator: salesCoordinatorId,
|
||||||
|
// records: [],
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Add the new attendance record to the array
|
||||||
|
// attendance.records.push({ date, time, location, notes });
|
||||||
|
// await attendance.save();
|
||||||
|
|
||||||
|
// res.status(201).json({
|
||||||
|
// success: true,
|
||||||
|
// message: "Attendance marked successfully",
|
||||||
|
// record: { date, time, location, notes },
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// res.status(500).json({
|
||||||
|
// success: false,
|
||||||
|
// message: error.message || "Something went wrong",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export const getAttendanceBySalesCoordinator = async (req, res) => {
|
||||||
|
// try {
|
||||||
|
// const salesCoordinatorId = req.user._id;
|
||||||
|
|
||||||
|
// const attendance = await AttendanceSalesCoOrdinator.findOne({
|
||||||
|
// salesCoordinator: salesCoordinatorId,
|
||||||
|
// }).populate("salesCoordinator", "name email");
|
||||||
|
|
||||||
|
// if (!attendance) {
|
||||||
|
// return res.status(404).json({
|
||||||
|
// success: false,
|
||||||
|
// message: "No attendance records found for this sales coordinator.",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// res.status(200).json({
|
||||||
|
// success: true,
|
||||||
|
// attendance,
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// res.status(500).json({
|
||||||
|
// success: false,
|
||||||
|
// message: error.message || "Something went wrong",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// // admin
|
||||||
|
// export const AdmingetAttendanceBySalesCoordinator = 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 attendance records for the given sales coordinator
|
||||||
|
// const attendanceDoc = await AttendanceSalesCoOrdinator.findOne({
|
||||||
|
// salesCoordinator: id,
|
||||||
|
// }).populate("salesCoordinator", "name email");
|
||||||
|
|
||||||
|
// if (!attendanceDoc) {
|
||||||
|
// return res.status(404).json({
|
||||||
|
// success: false,
|
||||||
|
// message: "No attendance records found for this sales coordinator.",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Pagination and slicing records
|
||||||
|
// const totalData = attendanceDoc.records.length;
|
||||||
|
// const paginatedRecords = attendanceDoc.records.slice(skip, skip + limit);
|
||||||
|
|
||||||
|
// res.status(200).json({
|
||||||
|
// success: true,
|
||||||
|
// salesCoordinator: attendanceDoc.salesCoordinator,
|
||||||
|
// attendance: paginatedRecords,
|
||||||
|
// total_data: totalData,
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// res.status(500).json({
|
||||||
|
// success: false,
|
||||||
|
// message: error.message || "Something went wrong",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export const getTodayAttendance = async (req, res) => {
|
||||||
|
// try {
|
||||||
|
// const today = new Date();
|
||||||
|
// today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// const startOfDay = new Date(today);
|
||||||
|
// const endOfDay = new Date(today);
|
||||||
|
// endOfDay.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
// const { page = 1, show = 10 } = req.query;
|
||||||
|
// const limit = parseInt(show);
|
||||||
|
// const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// const attendances = await AttendanceSalesCoOrdinator.aggregate([
|
||||||
|
// { $unwind: '$records' },
|
||||||
|
// {
|
||||||
|
// $match: {
|
||||||
|
// 'records.date': { $gte: startOfDay, $lte: endOfDay }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// $lookup: {
|
||||||
|
// from: 'salescoordinators',
|
||||||
|
// localField: 'salesCoordinator',
|
||||||
|
// foreignField: '_id',
|
||||||
|
// as: 'salesCoordinator'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// { $unwind: '$salesCoordinator' },
|
||||||
|
// {
|
||||||
|
// $facet: {
|
||||||
|
// totalData: [{ $count: 'count' }],
|
||||||
|
// attendance: [
|
||||||
|
// { $skip: skip },
|
||||||
|
// { $limit: limit },
|
||||||
|
// {
|
||||||
|
// $project: {
|
||||||
|
// salesCoordinator: {
|
||||||
|
// id: '$salesCoordinator._id',
|
||||||
|
// name: '$salesCoordinator.name',
|
||||||
|
// email: '$salesCoordinator.email'
|
||||||
|
// },
|
||||||
|
// date: '$records.date',
|
||||||
|
// time: '$records.time',
|
||||||
|
// location: '$records.location',
|
||||||
|
// note: '$records.notes'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ]);
|
||||||
|
|
||||||
|
// const totalData = attendances[0].totalData[0] ? attendances[0].totalData[0].count : 0;
|
||||||
|
|
||||||
|
// res.status(200).json({
|
||||||
|
// success: true,
|
||||||
|
// attendance: attendances[0].attendance,
|
||||||
|
// total_data: totalData
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// res.status(500).json({
|
||||||
|
// success: false,
|
||||||
|
// message: error.message || 'Something went wrong'
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
import { Attendance } from "./AttendanceModel.js";
|
||||||
|
|
||||||
|
// Mark attendance
|
||||||
|
export const markAttendance = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { date, time, location, notes } = req.body;
|
||||||
|
const userId = req.user._id;
|
||||||
|
const userType = req.userType;
|
||||||
|
|
||||||
|
// Get the start and end of the day to check if the attendance is already marked
|
||||||
|
const startOfDay = new Date(date);
|
||||||
|
startOfDay.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const endOfDay = new Date(date);
|
||||||
|
endOfDay.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
// Check if the attendance record exists for today
|
||||||
|
const existingAttendance = await Attendance.findOne({
|
||||||
|
userId,
|
||||||
|
userType,
|
||||||
|
"records.date": { $gte: startOfDay, $lte: endOfDay },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingAttendance) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: "Attendance for today is already marked.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if attendance record exists for the user
|
||||||
|
let attendance = await Attendance.findOne({ userId, userType });
|
||||||
|
|
||||||
|
if (!attendance) {
|
||||||
|
// Create a new attendance record if it doesn't exist
|
||||||
|
attendance = new Attendance({
|
||||||
|
userId,
|
||||||
|
userType,
|
||||||
|
records: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new attendance record to the array
|
||||||
|
attendance.records.push({ date, time, location, notes });
|
||||||
|
await attendance.save();
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
success: true,
|
||||||
|
message: "Attendance marked successfully",
|
||||||
|
record: { date, time, location, notes },
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message || "Something went wrong",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get attendance by user ID
|
||||||
|
export const getAttendanceByUser = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const userId = req.user._id;
|
||||||
|
|
||||||
|
const attendance = await Attendance.findOne({
|
||||||
|
userId,
|
||||||
|
}).populate("userId", "name email");
|
||||||
|
|
||||||
|
if (!attendance) {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: "No attendance records found for this user.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
attendance,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message || "Something went wrong",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Admin route to get attendance by user ID
|
||||||
|
export const AdmingetAttendanceByUser = 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 attendance records for the given user
|
||||||
|
const attendanceDoc = await Attendance.findOne({
|
||||||
|
userId: id,
|
||||||
|
}).populate("userId", "name email");
|
||||||
|
|
||||||
|
if (!attendanceDoc) {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: "No attendance records found for this user.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pagination and slicing records
|
||||||
|
const totalData = attendanceDoc.records.length;
|
||||||
|
const paginatedRecords = attendanceDoc.records.slice(skip, skip + limit);
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
user: attendanceDoc.userId,
|
||||||
|
attendance: paginatedRecords,
|
||||||
|
total_data: totalData,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message || "Something went wrong",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get today's attendance for admin
|
||||||
|
export const getTodayAttendance = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const today = new Date();
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const startOfDay = new Date(today);
|
||||||
|
const endOfDay = new Date(today);
|
||||||
|
endOfDay.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
const { page = 1, show = 10 } = req.query;
|
||||||
|
const limit = parseInt(show);
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
const attendances = await Attendance.aggregate([
|
||||||
|
{ $unwind: '$records' },
|
||||||
|
{
|
||||||
|
$match: {
|
||||||
|
'records.date': { $gte: startOfDay, $lte: endOfDay }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: 'users',
|
||||||
|
localField: 'userId',
|
||||||
|
foreignField: '_id',
|
||||||
|
as: 'user'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ $unwind: '$user' },
|
||||||
|
{
|
||||||
|
$facet: {
|
||||||
|
totalData: [{ $count: 'count' }],
|
||||||
|
attendance: [
|
||||||
|
{ $skip: skip },
|
||||||
|
{ $limit: limit },
|
||||||
|
{
|
||||||
|
$project: {
|
||||||
|
user: {
|
||||||
|
id: '$user._id',
|
||||||
|
name: '$user.name',
|
||||||
|
email: '$user.email',
|
||||||
|
userType: '$userType'
|
||||||
|
},
|
||||||
|
date: '$records.date',
|
||||||
|
time: '$records.time',
|
||||||
|
location: '$records.location',
|
||||||
|
notes: '$records.notes',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const totalData = attendances[0].totalData[0]?.count || 0;
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
total_data: totalData,
|
||||||
|
attendance: attendances[0].attendance
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: error.message || "Something went wrong",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
68
resources/Attendance/AttendanceModel.js
Normal file
68
resources/Attendance/AttendanceModel.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
// const attendanceRecordSchema = new mongoose.Schema({
|
||||||
|
// date: {
|
||||||
|
// type: Date,
|
||||||
|
// required: true,
|
||||||
|
// },
|
||||||
|
// time: {
|
||||||
|
// type: String,
|
||||||
|
// required: true,
|
||||||
|
// },
|
||||||
|
// location: {
|
||||||
|
// type: String,
|
||||||
|
// required: true,
|
||||||
|
// },
|
||||||
|
// notes: {
|
||||||
|
// type: String,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const attendanceSchema = new mongoose.Schema({
|
||||||
|
// salesCoordinator: {
|
||||||
|
// type: mongoose.Schema.Types.ObjectId,
|
||||||
|
// ref: 'SalesCoOrdinator',
|
||||||
|
// required: true,
|
||||||
|
// unique: true,
|
||||||
|
// },
|
||||||
|
// records: [attendanceRecordSchema],
|
||||||
|
// }, { timestamps: true, versionKey: false });
|
||||||
|
|
||||||
|
// export const AttendanceSalesCoOrdinator = mongoose.model('Attendance', attendanceSchema);
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
// Define attendance record schema
|
||||||
|
const attendanceRecordSchema = new mongoose.Schema({
|
||||||
|
date: {
|
||||||
|
type: Date,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
location: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
notes: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define main attendance schema
|
||||||
|
const attendanceSchema = new mongoose.Schema({
|
||||||
|
userId: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
refPath: 'userType',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
userType: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
enum: ['SalesCoOrdinator', 'TerritoryManager'], // Specify allowed user types
|
||||||
|
},
|
||||||
|
records: [attendanceRecordSchema],
|
||||||
|
}, { timestamps: true, versionKey: false });
|
||||||
|
|
||||||
|
export const Attendance = mongoose.model('Attendance', attendanceSchema);
|
@ -1,189 +0,0 @@
|
|||||||
import { AttendanceSalesCoOrdinator } from "./AttandanceSalesCoordinatorModel.js";
|
|
||||||
|
|
||||||
export const markAttendance = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { date, time, location, notes } = req.body;
|
|
||||||
const salesCoordinatorId = req.salescoordinator._id;
|
|
||||||
|
|
||||||
// Get the start and end of the day to check if the attendance is already marked
|
|
||||||
const startOfDay = new Date(date);
|
|
||||||
startOfDay.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const endOfDay = new Date(date);
|
|
||||||
endOfDay.setHours(23, 59, 59, 999);
|
|
||||||
|
|
||||||
// Check if the attendance record exists for today
|
|
||||||
const existingAttendance = await AttendanceSalesCoOrdinator.findOne({
|
|
||||||
salesCoordinator: salesCoordinatorId,
|
|
||||||
"records.date": { $gte: startOfDay, $lte: endOfDay },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (existingAttendance) {
|
|
||||||
return res.status(400).json({
|
|
||||||
success: false,
|
|
||||||
message: "Attendance for today is already marked.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if attendance record exists for the sales coordinator
|
|
||||||
let attendance = await AttendanceSalesCoOrdinator.findOne({
|
|
||||||
salesCoordinator: salesCoordinatorId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!attendance) {
|
|
||||||
// Create a new attendance record if it doesn't exist
|
|
||||||
attendance = new AttendanceSalesCoOrdinator({
|
|
||||||
salesCoordinator: salesCoordinatorId,
|
|
||||||
records: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the new attendance record to the array
|
|
||||||
attendance.records.push({ date, time, location, notes });
|
|
||||||
await attendance.save();
|
|
||||||
|
|
||||||
res.status(201).json({
|
|
||||||
success: true,
|
|
||||||
message: "Attendance marked successfully",
|
|
||||||
record: { date, time, location, notes },
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: error.message || "Something went wrong",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAttendanceBySalesCoordinator = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const salesCoordinatorId = req.salescoordinator._id;
|
|
||||||
|
|
||||||
const attendance = await AttendanceSalesCoOrdinator.findOne({
|
|
||||||
salesCoordinator: salesCoordinatorId,
|
|
||||||
}).populate("salesCoordinator", "name email");
|
|
||||||
|
|
||||||
if (!attendance) {
|
|
||||||
return res.status(404).json({
|
|
||||||
success: false,
|
|
||||||
message: "No attendance records found for this sales coordinator.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
success: true,
|
|
||||||
attendance,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: error.message || "Something went wrong",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// admin
|
|
||||||
export const AdmingetAttendanceBySalesCoordinator = 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 attendance records for the given sales coordinator
|
|
||||||
const attendanceDoc = await AttendanceSalesCoOrdinator.findOne({
|
|
||||||
salesCoordinator: id,
|
|
||||||
}).populate("salesCoordinator", "name email");
|
|
||||||
|
|
||||||
if (!attendanceDoc) {
|
|
||||||
return res.status(404).json({
|
|
||||||
success: false,
|
|
||||||
message: "No attendance records found for this sales coordinator.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pagination and slicing records
|
|
||||||
const totalData = attendanceDoc.records.length;
|
|
||||||
const paginatedRecords = attendanceDoc.records.slice(skip, skip + limit);
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
success: true,
|
|
||||||
salesCoordinator: attendanceDoc.salesCoordinator,
|
|
||||||
attendance: paginatedRecords,
|
|
||||||
total_data: totalData,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: error.message || "Something went wrong",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export const getTodayAttendance = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const today = new Date();
|
|
||||||
today.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const startOfDay = new Date(today);
|
|
||||||
const endOfDay = new Date(today);
|
|
||||||
endOfDay.setHours(23, 59, 59, 999);
|
|
||||||
|
|
||||||
const { page = 1, show = 10 } = req.query;
|
|
||||||
const limit = parseInt(show);
|
|
||||||
const skip = (page - 1) * limit;
|
|
||||||
|
|
||||||
const attendances = await AttendanceSalesCoOrdinator.aggregate([
|
|
||||||
{ $unwind: '$records' },
|
|
||||||
{
|
|
||||||
$match: {
|
|
||||||
'records.date': { $gte: startOfDay, $lte: endOfDay }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: 'salescoordinators',
|
|
||||||
localField: 'salesCoordinator',
|
|
||||||
foreignField: '_id',
|
|
||||||
as: 'salesCoordinator'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ $unwind: '$salesCoordinator' },
|
|
||||||
{
|
|
||||||
$facet: {
|
|
||||||
totalData: [{ $count: 'count' }],
|
|
||||||
attendance: [
|
|
||||||
{ $skip: skip },
|
|
||||||
{ $limit: limit },
|
|
||||||
{
|
|
||||||
$project: {
|
|
||||||
salesCoordinator: {
|
|
||||||
id: '$salesCoordinator._id',
|
|
||||||
name: '$salesCoordinator.name',
|
|
||||||
email: '$salesCoordinator.email'
|
|
||||||
},
|
|
||||||
date: '$records.date',
|
|
||||||
time: '$records.time',
|
|
||||||
location: '$records.location',
|
|
||||||
note: '$records.notes'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
const totalData = attendances[0].totalData[0] ? attendances[0].totalData[0].count : 0;
|
|
||||||
|
|
||||||
res.status(200).json({
|
|
||||||
success: true,
|
|
||||||
attendance: attendances[0].attendance,
|
|
||||||
total_data: totalData
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: error.message || 'Something went wrong'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,31 +0,0 @@
|
|||||||
import mongoose from 'mongoose';
|
|
||||||
|
|
||||||
const attendanceRecordSchema = new mongoose.Schema({
|
|
||||||
date: {
|
|
||||||
type: Date,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
time: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
location: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
notes: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const attendanceSchema = new mongoose.Schema({
|
|
||||||
salesCoordinator: {
|
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
|
||||||
ref: 'SalesCoOrdinator',
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
records: [attendanceRecordSchema],
|
|
||||||
}, { timestamps: true, versionKey: false });
|
|
||||||
|
|
||||||
export const AttendanceSalesCoOrdinator = mongoose.model('Attendance', attendanceSchema);
|
|
@ -1,41 +0,0 @@
|
|||||||
import express from "express";
|
|
||||||
import {
|
|
||||||
markAttendance,
|
|
||||||
getAttendanceBySalesCoordinator,
|
|
||||||
getTodayAttendance,
|
|
||||||
AdmingetAttendanceBySalesCoordinator,
|
|
||||||
} from "./AttandanceSalesCoordinatorController.js";
|
|
||||||
import { isAuthenticatedSalesCoOrdinator } from "../../middlewares/SalesCoOrdinatorAuth.js";
|
|
||||||
import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js";
|
|
||||||
|
|
||||||
const router = express.Router();
|
|
||||||
|
|
||||||
// Place more specific routes first
|
|
||||||
|
|
||||||
// Route to get today's attendance for admin
|
|
||||||
router.get(
|
|
||||||
"/attendance/today",
|
|
||||||
isAuthenticatedUser,
|
|
||||||
authorizeRoles("admin"),
|
|
||||||
getTodayAttendance
|
|
||||||
);
|
|
||||||
|
|
||||||
// Route to mark attendance
|
|
||||||
router.post("/attendance", isAuthenticatedSalesCoOrdinator, markAttendance);
|
|
||||||
|
|
||||||
// Route to get attendance for the logged-in sales coordinator
|
|
||||||
router.get(
|
|
||||||
"/attendance",
|
|
||||||
isAuthenticatedSalesCoOrdinator,
|
|
||||||
getAttendanceBySalesCoordinator
|
|
||||||
);
|
|
||||||
|
|
||||||
// Admin route to get attendance by sales coordinator ID
|
|
||||||
router.get(
|
|
||||||
"/attendance/:id",
|
|
||||||
isAuthenticatedUser,
|
|
||||||
authorizeRoles("admin"),
|
|
||||||
AdmingetAttendanceBySalesCoordinator
|
|
||||||
);
|
|
||||||
|
|
||||||
export default router;
|
|
@ -383,7 +383,7 @@ export const verifyUpdatedMobileOtp = async (req, res) => {
|
|||||||
//getmyProfile
|
//getmyProfile
|
||||||
export const getmyProfile = async (req, res) => {
|
export const getmyProfile = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const myData = await SalesCoOrdinator.findById(req.salescoordinator?._id);
|
const myData = await SalesCoOrdinator.findById(req.user?._id);
|
||||||
if (myData) {
|
if (myData) {
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user