163 lines
5.7 KiB
JavaScript
163 lines
5.7 KiB
JavaScript
import jwt from "jsonwebtoken";
|
|
import { VAModel, ProjectModel, AdjustedHoursModel } from "../../../models/vaModel.js";
|
|
|
|
// Adjust missing hours by creating new records
|
|
async function va_timesheet_adjustment_function(req, res) {
|
|
try {
|
|
const accessToken = req.headers.token;
|
|
|
|
if (!accessToken) {
|
|
return res.status(401).json({ success: false, message: "Missing token" });
|
|
}
|
|
|
|
const decoded = jwt.verify(accessToken, process.env.JWT_SECRET_ACCESS_TOKEN);
|
|
if (!decoded || !decoded.email) {
|
|
return res.status(401).json({ success: false, message: "Invalid token" });
|
|
}
|
|
|
|
const vaEmail = decoded.email;
|
|
const vaUser = await VAModel.findOne({ "userDetails.email": vaEmail });
|
|
if (!vaUser) {
|
|
return res.status(404).json({ success: false, message: "VA not found" });
|
|
}
|
|
|
|
const vaId = vaUser._id;
|
|
const { projectId, date, loginTime, logoutTime, comment } = req.body;
|
|
|
|
if (!projectId || !date || !loginTime || !logoutTime || !comment) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Project ID, date, loginTime, logoutTime, and comment are required"
|
|
});
|
|
}
|
|
|
|
// Validate project exists and VA is assigned to it
|
|
const project = await ProjectModel.findOne({
|
|
_id: projectId,
|
|
vaAssigned: vaId
|
|
});
|
|
|
|
if (!project) {
|
|
return res.status(404).json({ success: false, message: "Project not found or VA not assigned to this project" });
|
|
}
|
|
|
|
let adjustmentDate;
|
|
try {
|
|
adjustmentDate = new Date(date);
|
|
if (isNaN(adjustmentDate.getTime())) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Invalid date format. Use YYYY-MM-DD"
|
|
});
|
|
}
|
|
} catch (error) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Invalid date format"
|
|
});
|
|
}
|
|
|
|
const combineDateTime = (dateObj, timeStr) => {
|
|
const [hours, minutes, seconds] = timeStr.split(':').map(Number);
|
|
|
|
// // Extract date components from the Date object
|
|
// const year = dateObj.getFullYear();
|
|
// const month = dateObj.getMonth();
|
|
// const day = dateObj.getDate();
|
|
|
|
// // Create UTC date directly
|
|
// return new Date(year, month, day, hours, minutes, seconds);
|
|
const combined = new Date(dateObj);
|
|
combined.setHours(hours, minutes, seconds, 0);
|
|
|
|
return combined;
|
|
};
|
|
|
|
const loginDateTime = combineDateTime(adjustmentDate, loginTime);
|
|
const logoutDateTime = combineDateTime(adjustmentDate, logoutTime);
|
|
|
|
if (isNaN(adjustmentDate.getTime()) || isNaN(loginDateTime.getTime()) || isNaN(logoutDateTime.getTime())) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Invalid date format"
|
|
});
|
|
}
|
|
|
|
// Ensure login time is before logout time
|
|
if (loginDateTime >= logoutDateTime) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Login time must be before logout time"
|
|
});
|
|
}
|
|
|
|
// Ensure times are within the target date
|
|
const startOfDay = new Date(adjustmentDate);
|
|
startOfDay.setHours(0, 0, 0, 0);
|
|
|
|
const endOfDay = new Date(adjustmentDate);
|
|
endOfDay.setHours(23, 59, 59, 999);
|
|
|
|
if (loginDateTime < startOfDay || loginDateTime > endOfDay ||
|
|
logoutDateTime < startOfDay || logoutDateTime > endOfDay) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "Login and logout times must be within the specified date"
|
|
});
|
|
}
|
|
|
|
const existingAdjustment = await AdjustedHoursModel.findOne({
|
|
vaId,
|
|
projectId,
|
|
date: startOfDay,
|
|
status: "PENDING"
|
|
});
|
|
|
|
if (existingAdjustment) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: "You already have a pending adjustment request for this date and project"
|
|
});
|
|
}
|
|
|
|
const adjustmentRequest = new AdjustedHoursModel({
|
|
vaId,
|
|
projectId,
|
|
date: startOfDay,
|
|
loginTime: loginDateTime,
|
|
logoutTime: logoutDateTime,
|
|
comment,
|
|
status: "PENDING"
|
|
});
|
|
|
|
await adjustmentRequest.save();
|
|
|
|
const adjustedSeconds = (logoutDateTime - loginDateTime) / 1000;
|
|
const formatTime = (seconds) => {
|
|
const h = Math.floor(seconds / 3600);
|
|
const m = Math.floor((seconds % 3600) / 60);
|
|
const s = Math.floor(seconds % 60);
|
|
return `${h}h ${m}m ${s}s`;
|
|
};
|
|
|
|
return res.status(201).json({
|
|
success: true,
|
|
message: "Adjustment request submitted successfully",
|
|
data: {
|
|
adjustmentId: adjustmentRequest._id,
|
|
date: adjustmentDate.toISOString().split('T')[0],
|
|
loginTime: loginDateTime.toISOString(),
|
|
logoutTime: logoutDateTime.toISOString(),
|
|
adjustedHours: formatTime(adjustedSeconds),
|
|
comment: comment,
|
|
status: "PENDING"
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Timesheet adjustment error:", error);
|
|
return res.status(500).json({ success: false, message: "Internal Server Error" });
|
|
}
|
|
}
|
|
|
|
export { va_timesheet_adjustment_function }; |