diff --git a/src/controllers/va/vaLog/vaLog.controller.js b/src/controllers/va/vaLog/vaLog.controller.js index 46fe13c..833c56c 100644 --- a/src/controllers/va/vaLog/vaLog.controller.js +++ b/src/controllers/va/vaLog/vaLog.controller.js @@ -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) { diff --git a/src/controllers/va/vaProfile/vaProfileUpdate.controller.js b/src/controllers/va/vaProfile/vaProfileUpdate.controller.js index d00b0b3..b5229d3 100644 --- a/src/controllers/va/vaProfile/vaProfileUpdate.controller.js +++ b/src/controllers/va/vaProfile/vaProfileUpdate.controller.js @@ -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) diff --git a/src/routes/v1/va.routes.js b/src/routes/v1/va.routes.js index 96959a3..5f5ef48 100644 --- a/src/routes/v1/va.routes.js +++ b/src/routes/v1/va.routes.js @@ -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