Updated project logs function

This commit is contained in:
Aakash Mittal 2025-11-07 19:34:23 +05:30
parent e55183a2ef
commit 07075bdefb
3 changed files with 121 additions and 32 deletions

View File

@ -1,5 +1,11 @@
import { LoggedModel, ProjectModel } from "../../../models/vaModel.js";
function formatHMS(totalSeconds) {
const hrs = Math.floor(totalSeconds / 3600);
const mins = Math.floor((totalSeconds % 3600) / 60);
const secs = Math.floor(totalSeconds % 60);
return `${hrs}h ${mins}m ${secs}s`;
}
async function va_log_callback(req, res) {
try {
@ -35,42 +41,86 @@ async function va_log_callback(req, res) {
};
const logs = await LoggedModel.find(query).sort({ time: 1 });
const logs = await LoggedModel.find(query).sort({ time: 1 }).lean();
if (!logs.length) {
return res.json({ success: true, message: "No logs found", totalWork: "0h 0m" });
return res.json({ success: true, message: "No logs found", totalWork: "0h 0m 0s", totalSeconds: 0, sessions: [] });
}
// Find first LOGIN and last LOGOUT
const firstLogin = logs.find((l) => l.loggedType === "LOGIN");
const lastLogout = [...logs].reverse().find((l) => l.loggedType === "LOGOUT");
let totalSeconds = 0;
const sessions = [];
let lastLogin = null; // keep Date object
let lastLoginRaw = null; // raw log object for session details
if (!firstLogin || !lastLogout) {
return res.json({
success: true,
message: "Incomplete log data (missing LOGIN or LOGOUT)",
totalWork: "0h 0m",
firstLogin,
lastLogout,
});
for (const log of logs) {
const t = new Date(log.time);
if (String(log.loggedType).toUpperCase() === "LOGIN") {
// If there's already an open login (multiple consecutive LOGINS), ignore the new one
if (!lastLogin) {
lastLogin = t;
lastLoginRaw = log;
} else {
// consecutive LOGIN without LOGOUT — ignore this login (or you may choose to update lastLogin to this newer time)
// we'll ignore to favor the first login until a logout arrives
}
} else if (String(log.loggedType).toUpperCase() === "LOGOUT") {
if (lastLogin) {
// valid pair: lastLogin -> this logout
const diffSec = Math.floor((t - lastLogin) / 1000);
if (diffSec > 0) {
totalSeconds += diffSec;
sessions.push({
loginId: lastLoginRaw?._id || null,
logoutId: log._id,
from: lastLogin,
to: t,
durationSeconds: diffSec,
durationFormatted: formatHMS(diffSec)
});
}
// reset for next pair
lastLogin = null;
lastLoginRaw = null;
} else {
// LOGOUT with no preceding LOGIN in range — ignore
}
}
}
// Calculate duration
const diffMs = new Date(lastLogout.time) - new Date(firstLogin.time);
const totalMinutes = Math.floor(diffMs / (1000 * 60));
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
// If there's an open LOGIN at the end of the range, close it at toDate (or now if toDate > now)
if (lastLogin) {
// Use the smaller of toDate and current time as the end point
const now = new Date();
const endPoint = toDate > now ? now : toDate;
res.json({
const diffSec = Math.floor((endPoint - lastLogin) / 1000);
if (diffSec > 0) {
totalSeconds += diffSec;
sessions.push({
loginId: lastLoginRaw?._id || null,
logoutId: null,
from: lastLogin,
to: endPoint,
durationSeconds: diffSec,
durationFormatted: formatHMS(diffSec),
note: "Open session closed at range end"
});
}
}
return res.json({
success: true,
vaId,
projectId,
firstLogin: firstLogin.time,
lastLogout: lastLogout.time,
logs: logs,
totalTimeLogged: `${hours}h ${minutes}m`,
hoursLogged: hours,
minutesLogged: minutes,
from: fromDate,
to: toDate,
logs,
sessions,
totalTimeLogged: formatHMS(totalSeconds),
totalSeconds,
hoursLogged: Math.floor(totalSeconds / 3600),
minutesLogged: Math.floor((totalSeconds % 3600) / 60),
});
} catch (err) {

View File

@ -47,26 +47,59 @@ async function va_profile_update_callback(req, res) {
}
});
if (userDetails.password) {
if (!userDetails.cPassword) {
/* ---------------------- PASSWORD UPDATE ---------------------- */
if (userDetails.password || userDetails.cPassword || userDetails.oldPassword) {
const { oldPassword, password, cPassword } = userDetails;
if (!oldPassword || !password || !cPassword) {
return res.status(400).json({
success: false,
message: "Please confirm your new password",
message: "Please provide oldPassword, password, and cPassword to update password",
});
}
if (userDetails.password !== userDetails.cPassword) {
if (password !== cPassword) {
return res.status(400).json({
success: false,
message: "Passwords do not match",
message: "New passwords do not match",
});
}
// Verify old password
const isMatch = await bcrypt.compare(oldPassword, vaUser.userDetails.password);
if (!isMatch) {
return res.status(400).json({
success: false,
message: "Old password is incorrect",
});
}
// Hash and update new password
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(userDetails.password, saltRounds);
const hashedPassword = await bcrypt.hash(password, saltRounds);
vaUser.userDetails.password = hashedPassword;
}
// if (userDetails.password) {
// if (!userDetails.cPassword) {
// return res.status(400).json({
// success: false,
// message: "Please confirm your new password",
// });
// }
// if (userDetails.password !== userDetails.cPassword) {
// return res.status(400).json({
// success: false,
// message: "Passwords do not match",
// });
// }
// const saltRounds = 10;
// const hashedPassword = await bcrypt.hash(userDetails.password, saltRounds);
// vaUser.userDetails.password = hashedPassword;
// }
await vaUser.save();
const updatedUser = await VAModel.findById(vaUser._id)

View File

@ -37,7 +37,13 @@ vaRoutes.get("/search", va_filter_search);
vaRoutes.get("/clients/:clientID", va_clients_callback); // VA Clients Callback for getting all clients or specific client by ID
vaRoutes.get("/clients/:clientId/projects/:projectId", va_clients_projects_callback); // VA Clients Projects Callback
vaRoutes.get("/project/:projectId", va_projects_callback);
// Getting Project List assigned to VA should be ACTIVE and add total logged hours added by VA
vaRoutes.get("/list/project/:projectId", va_projects_callback);
// GET Windows Tab Logged Data for VA IN Between Login and LOGOUT
vaRoutes.get("/report/project/:projectId", va_projects_callback);
vaRoutes.post("/log/project", authValidator, va_project_log_callback); // VA Logged IN / Logged Out in project