diff --git a/src/controllers/projectController.js b/src/controllers/projectController.js index b149416b7..466cc71c0 100644 --- a/src/controllers/projectController.js +++ b/src/controllers/projectController.js @@ -1,44 +1,47 @@ /* eslint-disable quotes */ /* eslint-disable arrow-parens */ -const mongoose = require("mongoose"); -const timeentry = require("../models/timeentry"); -const userProfile = require("../models/userProfile"); -const userProject = require("../helpers/helperModels/userProjects"); -const { hasPermission } = require("../utilities/permissions"); -const escapeRegex = require("../utilities/escapeRegex"); -const cache = require("../utilities/nodeCache")(); +const mongoose = require('mongoose'); +const timeentry = require('../models/timeentry'); +const task = require('../models/task'); +const wbs = require('../models/wbs'); +const userProfile = require('../models/userProfile'); +const { hasPermission } = require('../utilities/permissions'); +const escapeRegex = require('../utilities/escapeRegex'); +const logger = require('../startup/logger'); +const cache = require('../utilities/nodeCache')(); const projectController = function (Project) { - const getAllProjects = function (req, res) { - Project.find({}, "projectName isActive category modifiedDatetime") - .sort({ modifiedDatetime: -1 }) - .then((results) => { - res.status(200).send(results); - }) - .catch((error) => res.status(404).send(error)); + const getAllProjects = async function (req, res) { + try { + const projects = await Project.find( + { isArchived: { $ne: true } }, + 'projectName isActive category modifiedDatetime', + ).sort({ modifiedDatetime: -1 }); + res.status(200).send(projects); + } catch (error) { + logger.logException(error); + res.status(404).send('Error fetching projects. Please try again.'); + } }; const deleteProject = async function (req, res) { - if (!(await hasPermission(req.body.requestor, "deleteProject"))) { - res - .status(403) - .send({ error: "You are not authorized to delete projects." }); + if (!(await hasPermission(req.body.requestor, 'deleteProject'))) { + res.status(403).send({ error: 'You are not authorized to delete projects.' }); return; } const { projectId } = req.params; Project.findById(projectId, (error, record) => { if (error || !record || record === null || record.length === 0) { - res.status(400).send({ error: "No valid records found" }); + res.status(400).send({ error: 'No valid records found' }); return; } - // find if project has any time entries associated with it - timeentry.find({ projectId: record._id }, "_id").then((timeentries) => { + timeentry.find({ projectId: record._id }, '_id').then((timeentries) => { if (timeentries.length > 0) { res.status(400).send({ error: - "This project has associated time entries and cannot be deleted. Consider inactivaing it instead.", + 'This project has associated time entries and cannot be deleted. Consider inactivaing it instead.', }); } else { const removeprojectfromprofile = userProfile @@ -49,9 +52,8 @@ const projectController = function (Project) { Promise.all([removeprojectfromprofile, removeproject]) .then( res.status(200).send({ - message: - "Project successfully deleted and user profiles updated.", - }) + message: 'Project successfully deleted and user profiles updated.', + }), ) .catch((errors) => { res.status(400).send(errors); @@ -64,117 +66,164 @@ const projectController = function (Project) { }; const postProject = async function (req, res) { - if (!(await hasPermission(req.body.requestor, "postProject"))) { - res - .status(403) - .send({ error: "You are not authorized to create new projects." }); - return; + if (!(await hasPermission(req.body.requestor, 'postProject'))) { + return res.status(401).send('You are not authorized to create new projects.'); } - if (!req.body.projectName || !req.body.isActive) { - res.status(400).send({ - error: "Project Name and active status are mandatory fields.", - }); - return; + if (!req.body.projectName) { + return res.status(400).send('Project Name is mandatory fields.'); } - Project.find({ - projectName: { $regex: escapeRegex(req.body.projectName), $options: "i" }, - }).then((result) => { - if (result.length > 0) { - res.status(400).send({ - error: `Project Name must be unique. Another project with name ${result.projectName} already exists. Please note that project names are case insensitive.`, - }); + try { + const projectWithRepeatedName = await Project.find({ + projectName: { + $regex: escapeRegex(req.body.projectName), + $options: 'i', + }, + }); + if (projectWithRepeatedName.length > 0) { + res + .status(400) + .send( + `Project Name must be unique. Another project with name ${req.body.projectName} already exists. Please note that project names are case insensitive.`, + ); return; } const _project = new Project(); + const now = new Date(); _project.projectName = req.body.projectName; - _project.category = req.body.projectCategory || "Unspecified"; - _project.isActive = req.body.isActive; - _project.createdDatetime = Date.now(); - _project.modifiedDatetime = Date.now(); - - _project - .save() - .then((results) => res.status(201).send(results)) - .catch((error) => res.status(500).send({ error })); - }); + _project.category = req.body.projectCategory; + _project.isActive = true; + _project.createdDatetime = now; + _project.modifiedDatetime = now; + const savedProject = await _project.save(); + return res.status(200).send(savedProject); + } catch (error) { + logger.logException(error); + res.status(400).send('Error creating project. Please try again.'); + } }; const putProject = async function (req, res) { - if (!(await hasPermission(req.body.requestor, "putProject"))) { - res - .status(403) - .send("You are not authorized to make changes in the projects."); + if (!(await hasPermission(req.body.requestor, 'putProject'))) { + res.status(403).send('You are not authorized to make changes in the projects.'); return; } - - const { projectId } = req.params; - Project.findById(projectId, (error, record) => { - if (error || record === null) { - res.status(400).send("No valid records found"); + const { projectName, category, isActive, _id: projectId, isArchived } = req.body; + const sameNameProejct = await Project.find({ + projectName, + _id: { $ne: projectId }, + }); + if (sameNameProejct.length > 0) { + res.status(400).send('This project name is already taken'); + return; + } + const session = await mongoose.startSession(); + session.startTransaction(); + try { + const targetProject = await Project.findById(projectId); + if (!targetProject) { + res.status(400).send('No valid records found'); return; } - - record.projectName = req.body.projectName; - record.category = req.body.category; - record.isActive = req.body.isActive; - record.modifiedDatetime = Date.now(); - - record - .save() - .then((results) => res.status(201).send(results._id)) - .catch((errors) => res.status(400).send(errors)); - }); + targetProject.projectName = projectName; + targetProject.category = category; + targetProject.isActive = isActive; + targetProject.modifiedDatetime = Date.now(); + if (isArchived) { + targetProject.isArchived = isArchived; + // deactivate wbs within target project + await wbs.updateMany({ projectId }, { isActive: false }, { session }); + // deactivate tasks within affected wbs + const deactivatedwbsIds = await wbs.find({ projectId }, '_id'); + await task.updateMany( + { wbsId: { $in: deactivatedwbsIds } }, + { isActive: false }, + { session }, + ); + // remove project from userprofiles.projects array + await userProfile.updateMany( + { projects: projectId }, + { $pull: { projects: projectId } }, + { session }, + ); + // deactivate timeentry for affected tasks + await timeentry.updateMany({ projectId }, { isActive: false }, { session }); + } + await targetProject.save({ session }); + await session.commitTransaction(); + res.status(200).send(targetProject); + } catch (error) { + await session.abortTransaction(); + logger.logException(error); + res.status(400).send('Error updating project. Please try again.'); + } finally { + session.endSession(); + } }; const getProjectById = function (req, res) { const { projectId } = req.params; - - Project.findById(projectId, "-__v -createdDatetime -modifiedDatetime") + Project.findById(projectId, '-__v -createdDatetime -modifiedDatetime') .then((results) => res.status(200).send(results)) - .catch((error) => res.status(404).send(error)); + .catch((err) => { + logger.logException(err); + res.status(404).send('Error fetching project. Please try again.'); + }); }; - const getUserProjects = function (req, res) { - const { userId } = req.params; - - userProject - .findById(userId) - .then((results) => { - res.status(200).send(results.projects); - }) - .catch((error) => { - res.status(400).send(error); - }); + const getUserProjects = async function (req, res) { + try { + const { userId } = req.params; + const user = await userProfile.findById(userId, 'projects'); + if (!user) { + res.status(400).send('Invalid user'); + return; + } + const { projects } = user; + const projectList = await Project.find( + { _id: { $in: projects }, isActive: { $ne: false } }, + '_id projectName category', + ); + const result = projectList + .map((p) => { + p = p.toObject(); + p.projectId = p._id; + delete p._id; + return p; + }) + .sort((p1, p2) => { + if (p1.projectName.toLowerCase() < p2.projectName.toLowerCase()) return -1; + if (p1.projectName.toLowerCase() > p2.projectName.toLowerCase()) return 1; + return 0; + }); + res.status(200).send(result); + } catch (error) { + logger.logException(error); + res.status(400).send('Error fetching projects. Please try again.'); + } }; const assignProjectToUsers = async function (req, res) { // verify requestor is administrator, projectId is passed in request params and is valid mongoose objectid, and request body contains an array of users - - if (!(await hasPermission(req.body.requestor, "assignProjectToUsers"))) { - res - .status(403) - .send({ error: "You are not authorized to perform this operation" }); + if (!(await hasPermission(req.body.requestor, 'assignProjectToUsers'))) { + res.status(403).send('You are not authorized to perform this operation'); return; } - if ( !req.params.projectId || !mongoose.Types.ObjectId.isValid(req.params.projectId) || !req.body.users || req.body.users.length === 0 ) { - res.status(400).send({ error: "Invalid request" }); + res.status(400).send('Invalid request'); return; } - // verify project exists - Project.findById(req.params.projectId) .then((project) => { if (!project || project.length === 0) { - res.status(400).send({ error: "Invalid project" }); + res.status(400).send('Invalid project'); return; } const { users } = req.body; @@ -186,7 +235,7 @@ const projectController = function (Project) { if (cache.hasCache(`user-${userId}`)) { cache.removeCache(`user-${userId}`); } - if (operation === "Assign") { + if (operation === 'Assign') { assignlist.push(userId); } else { unassignlist.push(userId); @@ -194,42 +243,34 @@ const projectController = function (Project) { }); const assignPromise = userProfile - .updateMany( - { _id: { $in: assignlist } }, - { $addToSet: { projects: project._id } } - ) + .updateMany({ _id: { $in: assignlist } }, { $addToSet: { projects: project._id } }) .exec(); const unassignPromise = userProfile - .updateMany( - { _id: { $in: unassignlist } }, - { $pull: { projects: project._id } } - ) + .updateMany({ _id: { $in: unassignlist } }, { $pull: { projects: project._id } }) .exec(); Promise.all([assignPromise, unassignPromise]) .then(() => { - res.status(200).send({ result: "Done" }); + res.status(200).send({ result: 'Done' }); }) .catch((error) => { res.status(500).send({ error }); }); }) - .catch((error) => { - res.status(500).send({ error }); + .catch((err) => { + logger.logException(err); + res.status(500).send('Error fetching project. Please try again.'); }); }; const getprojectMembership = function (req, res) { const { projectId } = req.params; if (!mongoose.Types.ObjectId.isValid(projectId)) { - res.status(400).send({ error: "Invalid request" }); + res.status(400).send('Invalid request'); return; } userProfile - .find( - { projects: projectId }, - "_id firstName lastName isActive profilePic" - ) + .find({ projects: projectId }, '_id firstName lastName isActive profilePic') .sort({ firstName: 1, lastName: 1 }) .then((results) => { res.status(200).send(results); diff --git a/src/controllers/taskController.js b/src/controllers/taskController.js index 07ee7b730..1e019ffa1 100644 --- a/src/controllers/taskController.js +++ b/src/controllers/taskController.js @@ -14,6 +14,7 @@ const taskController = function (Task) { let query = { wbsId: { $in: [req.params.wbsId] }, level: { $in: [level] }, + isActive: { $ne: false }, }; const { mother } = req.params; @@ -27,16 +28,16 @@ const taskController = function (Task) { } Task.find(query) - .then(results => res.status(200).send(results)) - .catch(error => res.status(404).send(error)); + .then((results) => res.status(200).send(results)) + .catch((error) => res.status(404).send(error)); }; const getWBSId = (req, res) => { const { wbsId } = req.params; WBS.findById(wbsId) - .then(results => res.status(200).send(results)) - .catch(error => res.status(404).send(error)); + .then((results) => res.status(200).send(results)) + .catch((error) => res.status(404).send(error)); }; const updateSumUp = ( @@ -82,7 +83,7 @@ const taskController = function (Task) { }; const calculateSubTasks = (level, tasks) => { - const parentTasks = tasks.filter(task => task.level === level); + const parentTasks = tasks.filter((task) => task.level === level); parentTasks.forEach((task) => { const childTasks = tasks.filter((taskChild) => taskChild.level === level + 1); let sumHoursBest = 0; @@ -141,7 +142,7 @@ const taskController = function (Task) { }; const setDatesSubTasks = (level, tasks) => { - const parentTasks = tasks.filter(task => task.level === level); + const parentTasks = tasks.filter((task) => task.level === level); parentTasks.forEach((task) => { const childTasks = tasks.filter((taskChild) => taskChild.level === level + 1); let minStartedDate = task.startedDatetime; @@ -173,7 +174,7 @@ const taskController = function (Task) { }; const calculatePriority = (level, tasks) => { - const parentTasks = tasks.filter(task => task.level === level); + const parentTasks = tasks.filter((task) => task.level === level); parentTasks.forEach((task) => { const childTasks = tasks.filter((taskChild) => taskChild.level === level + 1); let totalNumberPriority = 0; @@ -215,7 +216,7 @@ const taskController = function (Task) { }; const setAssigned = (level, tasks) => { - const parentTasks = tasks.filter(task => task.level === level); + const parentTasks = tasks.filter((task) => task.level === level); parentTasks.forEach((task) => { const childTasks = tasks.filter((taskChild) => taskChild.level === level + 1); let isAssigned = false; @@ -248,9 +249,10 @@ const taskController = function (Task) { $and: [ { $or: [{ taskId: parentId1 }, { parentId1 }, { parentId1: null }] }, { wbsId: { $in: [wbsId] } }, + { isActive: { $ne: false } }, ], }).then((tasks) => { - tasks = [...new Set(tasks.map(item => item))]; + tasks = [...new Set(tasks.map((item) => item))]; for (let lv = 3; lv > 0; lv -= 1) { calculateSubTasks(lv, tasks); setDatesSubTasks(lv, tasks); @@ -306,7 +308,7 @@ const taskController = function (Task) { case 3: // task.num is x.x.x, has two levels of parent (parent: x.x and grandparent: x) task.parentId1 = tasksWithId.find((pTask) => pTask.num === taskNumArr[0])._id; // task of parentId1 has num prop of x task.parentId2 = tasksWithId.find( - pTask => pTask.num === `${taskNumArr[0]}.${taskNumArr[1]}`, + (pTask) => pTask.num === `${taskNumArr[0]}.${taskNumArr[1]}`, )._id; // task of parentId2 has num prop of x.x task.parentId3 = null; task.mother = task.parentId2; // parent task num prop is x.x @@ -314,10 +316,10 @@ const taskController = function (Task) { case 4: // task.num is x.x.x.x, has three levels of parent (x.x.x, x.x and x) task.parentId1 = tasksWithId.find((pTask) => pTask.num === taskNumArr[0])._id; // x task.parentId2 = tasksWithId.find( - pTask => pTask.num === `${taskNumArr[0]}.${taskNumArr[1]}`, + (pTask) => pTask.num === `${taskNumArr[0]}.${taskNumArr[1]}`, )._id; // x.x task.parentId3 = tasksWithId.find( - pTask => pTask.num === `${taskNumArr[0]}.${taskNumArr[1]}.${taskNumArr[2]}`, + (pTask) => pTask.num === `${taskNumArr[0]}.${taskNumArr[1]}.${taskNumArr[2]}`, )._id; // x.x.x task.mother = task.parentId3; // parent task num prop is x.x.x break; @@ -466,7 +468,7 @@ const taskController = function (Task) { }); Promise.all([saveTask, saveWbs, saveProject]) - .then(results => res.status(201).send(results[0])) + .then((results) => res.status(201).send(results[0])) .catch((errors) => { res.status(400).send(errors); }); @@ -490,7 +492,7 @@ const taskController = function (Task) { task .save() .then() - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); }); // level 2 @@ -506,7 +508,7 @@ const taskController = function (Task) { childTask1 .save() .then(true) - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); // level 3 Task.find({ parentId: { $in: [childTask1._id] } }) @@ -521,7 +523,7 @@ const taskController = function (Task) { childTask2 .save() .then(true) - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); // level 4 Task.find({ parentId: { $in: [childTask2._id] } }) @@ -536,19 +538,19 @@ const taskController = function (Task) { childTask3 .save() .then(true) - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); }); } }) - .catch(error => res.status(404).send(error)); + .catch((error) => res.status(404).send(error)); }); } }) - .catch(error => res.status(404).send(error)); + .catch((error) => res.status(404).send(error)); }); } }) - .catch(error => res.status(404).send(error)); + .catch((error) => res.status(404).send(error)); }); res.status(200).send(true); @@ -602,7 +604,7 @@ const taskController = function (Task) { Promise.all(queries) .then(() => res.status(200).send('Success!')) - .catch(err => res.status(400).send(err)); + .catch((err) => res.status(400).send(err)); }); }; @@ -646,7 +648,7 @@ const taskController = function (Task) { Promise.all([removeChildTasks, updateMotherChildrenQty]) .then(() => res.status(200).send({ message: 'Task successfully deleted' })) // no need to resetNum(taskId, mother); - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); }; const deleteTaskByWBS = async (req, res) => { @@ -709,7 +711,7 @@ const taskController = function (Task) { { ...req.body, modifiedDatetime: Date.now() }, ) .then(() => res.status(201).send()) - .catch(error => res.status(404).send(error)); + .catch((error) => res.status(404).send(error)); }; const swap = async function (req, res) { @@ -750,18 +752,18 @@ const taskController = function (Task) { task1 .save() .then() - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); task2 .save() .then() - .catch(errors => res.status(400).send(errors)); + .catch((errors) => res.status(400).send(errors)); Task.find({ wbsId: { $in: [task1.wbsId] }, }) - .then(results => res.status(200).send(results)) - .catch(error => res.status(404).send(error)); + .then((results) => res.status(200).send(results)) + .catch((error) => res.status(404).send(error)); }); }); }; @@ -804,7 +806,7 @@ const taskController = function (Task) { try { Task.find({ wbsId: { $in: [wbsId] } }).then((tasks) => { - tasks = tasks.filter(task => task.level === 1); + tasks = tasks.filter((task) => task.level === 1); tasks.forEach((task) => { updateParents(task.wbsId, task.taskId.toString()); }); @@ -823,26 +825,54 @@ const taskController = function (Task) { const getTasksByUserId = async (req, res) => { const { userId } = req.params; try { - Task.find( - { - 'resources.userID': mongoose.Types.ObjectId(userId), - }, - '-resources.profilePic', - ).then((results) => { - WBS.find({ - _id: { $in: results.map(item => item.wbsId) }, - }).then((WBSs) => { - const resultsWithProjectsIds = results.map((item) => { - item.set( - 'projectId', - WBSs?.find((wbs) => wbs._id.toString() === item.wbsId.toString())?.projectId, - { strict: false }, - ); - return item; - }); - res.status(200).send(resultsWithProjectsIds); + const tasks = await Task.aggregate() + .match({ + resources: { + $elemMatch: { + userID: mongoose.Types.ObjectId(userId), + completedTask: { + $ne: true, + }, + }, + }, + isActive: { + $ne: false, + }, + }) + .lookup({ + from: 'wbs', + localField: 'wbsId', + foreignField: '_id', + as: 'wbs', + }) + .unwind({ + path: '$wbs', + includeArrayIndex: 'string', + preserveNullAndEmptyArrays: true, + }) + .addFields({ + wbsName: '$wbs.wbsName', + projectId: '$wbs.projectId', + }) + .lookup({ + from: 'projects', + localField: 'projectId', + foreignField: '_id', + as: 'project', + }) + .unwind({ + path: '$project', + includeArrayIndex: 'string', + preserveNullAndEmptyArrays: true, + }) + .addFields({ + projectName: '$project.projectName', + }) + .project({ + wbs: 0, + project: 0, }); - }); + res.status(200).send(tasks); } catch (error) { res.status(400).send(error); } @@ -887,7 +917,7 @@ const taskController = function (Task) { { ...req.body, modifiedDatetime: Date.now() }, ) .then(() => res.status(201).send()) - .catch(error => res.status(404).send(error)); + .catch((error) => res.status(404).send(error)); }; const getReviewReqEmailBody = function (name, taskName) { @@ -907,7 +937,7 @@ const taskController = function (Task) { role: { $in: ['Administrator', 'Manager', 'Mentor'] }, }); membership.forEach((member) => { - if (member.teams.some(team => user.teams.includes(team))) { + if (member.teams.some((team) => user.teams.includes(team))) { recipients.push(member.email); } }); diff --git a/src/controllers/timeEntryController.js b/src/controllers/timeEntryController.js index 4e4e70631..250e5130e 100644 --- a/src/controllers/timeEntryController.js +++ b/src/controllers/timeEntryController.js @@ -858,6 +858,7 @@ const timeEntrycontroller = function (TimeEntry) { entryType: { $in: ['default', null] }, personId: userId, dateOfWork: { $gte: fromdate, $lte: todate }, + isActive: { $ne: false }, }).sort('-lastModifiedDateTime'); const results = await Promise.all( @@ -865,6 +866,18 @@ const timeEntrycontroller = function (TimeEntry) { timeEntry = { ...timeEntry.toObject() }; const { projectId, taskId } = timeEntry; if (!taskId) await updateTaskIdInTimeEntry(projectId, timeEntry); // if no taskId, then it might be old time entry data that didn't separate projectId with taskId + if (timeEntry.taskId) { + const task = await Task.findById(timeEntry.taskId); + if (task) { + timeEntry.taskName = task.taskName; + } + } + if (timeEntry.projectId) { + const project = await Project.findById(timeEntry.projectId); + if (project) { + timeEntry.projectName = project.projectName; + } + } const hours = Math.floor(timeEntry.totalSeconds / 3600); const minutes = Math.floor((timeEntry.totalSeconds % 3600) / 60); Object.assign(timeEntry, { hours, minutes, totalSeconds: undefined }); @@ -890,7 +903,7 @@ const timeEntrycontroller = function (TimeEntry) { personId: { $in: users }, dateOfWork: { $gte: fromDate, $lte: toDate }, }, - ' -createdDateTime', + '-createdDateTime', ) .populate('personId') .populate('projectId') @@ -899,7 +912,6 @@ const timeEntrycontroller = function (TimeEntry) { .sort({ lastModifiedDateTime: -1 }) .then((results) => { const data = []; - results.forEach((element) => { const record = {}; record._id = element._id; @@ -917,10 +929,8 @@ const timeEntrycontroller = function (TimeEntry) { record.taskClassification = element.taskId?.classification?.toLowerCase() || null; record.wbsId = element.wbsId?._id || null; record.wbsName = element.wbsId?.wbsName || null; - data.push(record); }); - res.status(200).send(data); }) .catch((error) => { @@ -977,6 +987,7 @@ const timeEntrycontroller = function (TimeEntry) { { projectId, dateOfWork: { $gte: fromDate, $lte: todate }, + isActive: { $ne: false }, }, '-createdDateTime -lastModifiedDateTime', ) @@ -1001,6 +1012,7 @@ const timeEntrycontroller = function (TimeEntry) { entryType: 'person', personId: { $in: users }, dateOfWork: { $gte: fromDate, $lte: toDate }, + isActive: { $ne: false }, }, ' -createdDateTime', ) @@ -1040,6 +1052,7 @@ const timeEntrycontroller = function (TimeEntry) { entryType: 'project', projectId: { $in: projects }, dateOfWork: { $gte: fromDate, $lte: toDate }, + isActive: { $ne: false }, }, ' -createdDateTime', ) @@ -1077,6 +1090,7 @@ const timeEntrycontroller = function (TimeEntry) { entryType: 'team', teamId: { $in: teams }, dateOfWork: { $gte: fromDate, $lte: toDate }, + isActive: { $ne: false }, }, ' -createdDateTime', ) diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index 8e28231e3..1db24efa0 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -92,7 +92,6 @@ const userProfileController = function (UserProfile) { await UserProfile.find( {}, - '_id firstName lastName role weeklycommittedHours email permissions isActive reactivationDate startDate createdDate endDate', ) .sort({ @@ -388,12 +387,10 @@ const userProfileController = function (UserProfile) { 'profilePic', 'firstName', 'lastName', - 'jobTitle', 'phoneNumber', 'bio', 'personalLinks', 'location', - 'profilePic', 'privacySettings', 'weeklySummaries', 'weeklySummariesCount', @@ -405,7 +402,6 @@ const userProfileController = function (UserProfile) { 'isFirstTimelog', 'teamCode', 'isVisible', - 'isRehireable', 'bioPosted', ]; @@ -437,7 +433,6 @@ const userProfileController = function (UserProfile) { 'role', 'isRehireable', 'isActive', - 'isActive', 'weeklySummaries', 'weeklySummariesCount', 'mediaUrl', @@ -473,7 +468,7 @@ const userProfileController = function (UserProfile) { } if (req.body.projects !== undefined) { - record.projects = Array.from(new Set(req.body.projects)); + record.projects = req.body.projects.map((project) => project._id); } if (req.body.email !== undefined) { diff --git a/src/controllers/wbsController.js b/src/controllers/wbsController.js index 2e325b85b..074cfaf16 100644 --- a/src/controllers/wbsController.js +++ b/src/controllers/wbsController.js @@ -1,20 +1,23 @@ /* eslint-disable quotes */ /* eslint-disable no-unused-vars */ const mongoose = require('mongoose'); -const helper = require('../utilities/permissions'); +const { hasPermission } = require('../utilities/permissions'); const Project = require('../models/project'); const Task = require('../models/task'); const wbsController = function (WBS) { const getAllWBS = function (req, res) { - WBS.find({ projectId: { $in: [req.params.projectId] } }, 'wbsName isActive modifiedDatetime') + WBS.find( + { projectId: { $in: [req.params.projectId] }, isActive: { $ne: false } }, + 'wbsName isActive modifiedDatetime', + ) .sort({ modifiedDatetime: -1 }) - .then(results => res.status(200).send(results)) - .catch(error => res.status(404).send(error)); + .then((results) => res.status(200).send(results)) + .catch((error) => res.status(404).send(error)); }; const postWBS = async function (req, res) { - if (!(await helper.hasPermission(req.body.requestor, 'postWbs'))) { + if (!(await hasPermission(req.body.requestor, 'postWbs'))) { res.status(403).send({ error: 'You are not authorized to create new projects.' }); return; } @@ -42,13 +45,13 @@ const wbsController = function (WBS) { _wbs .save() - .then(results => res.status(201).send(results)) - .catch(error => res.status(500).send({ error })); + .then((results) => res.status(201).send(results)) + .catch((error) => res.status(500).send({ error })); }; const deleteWBS = async function (req, res) { - if (!(await helper.hasPermission(req.body.requestor, 'deleteWbs'))) { - res.status(403).send({ error: 'You are not authorized to delete projects.' }); + if (!(await hasPermission(req.body.requestor, 'deleteWbs'))) { + res.status(403).send({ error: 'You are not authorized to delete projects.' }); return; } const { id } = req.params; @@ -66,15 +69,12 @@ const wbsController = function (WBS) { res.status(400).send(errors); }); }); - // .catch((errors) => { - // res.status(400).send(errors); - // }); }; const getWBS = function (req, res) { - WBS.find() - .then(results => res.status(200).send(results)) - .catch(error => res.status(500).send({ error })); + WBS.find({ isActive: { $ne: false } }) + .then((results) => res.status(200).send(results)) + .catch((error) => res.status(500).send({ error })); }; const getWBSById = function (req, res) { @@ -83,29 +83,7 @@ const wbsController = function (WBS) { .then((results) => { res.status(200).send(results); }) - .catch(error => res.status(404).send(error)); - }; - - const getWBSByUserId = async function (req, res) { - const { userId } = req.params; - try { - const result = await Task.aggregate() - .match({ 'resources.userID': mongoose.Types.ObjectId(userId) }) - .project('wbsId -_id') - .group({ _id: '$wbsId' }) - .lookup({ - from: 'wbs', - localField: '_id', - foreignField: '_id', - as: 'wbs', - }) - .unwind('wbs') - .replaceRoot('wbs'); - - res.status(200).send(result); - } catch (error) { - res.status(404).send(error); - } + .catch((error) => res.status(404).send(error)); }; return { @@ -114,7 +92,6 @@ const wbsController = function (WBS) { getAllWBS, getWBS, getWBSById, - getWBSByUserId, }; }; diff --git a/src/helpers/dashboardhelper.js b/src/helpers/dashboardhelper.js index 80422f153..b5dad13a5 100644 --- a/src/helpers/dashboardhelper.js +++ b/src/helpers/dashboardhelper.js @@ -2,28 +2,17 @@ const moment = require('moment-timezone'); const mongoose = require('mongoose'); const userProfile = require('../models/userProfile'); const timeentry = require('../models/timeentry'); -const myTeam = require('./helperModels/myTeam'); const team = require('../models/team'); const { hasPermission } = require('../utilities/permissions'); - const dashboardhelper = function () { const personaldetails = function (userId) { - return userProfile.findById( - userId, - "_id firstName lastName role profilePic badgeCollection" - ); + return userProfile.findById(userId, '_id firstName lastName role profilePic badgeCollection'); }; const getOrgData = async function () { - const pdtstart = moment() - .tz("America/Los_Angeles") - .startOf("week") - .format("YYYY-MM-DD"); - const pdtend = moment() - .tz("America/Los_Angeles") - .endOf("week") - .format("YYYY-MM-DD"); + const pdtstart = moment().tz('America/Los_Angeles').startOf('week').format('YYYY-MM-DD'); + const pdtend = moment().tz('America/Los_Angeles').endOf('week').format('YYYY-MM-DD'); /** * Previous aggregate pipeline had two issues: @@ -42,43 +31,40 @@ const dashboardhelper = function () { $gte: 1, }, role: { - $ne: "Mentor", + $ne: 'Mentor', }, }, }, { $lookup: { - from: "timeEntries", - localField: "_id", - foreignField: "personId", - as: "timeEntryData", + from: 'timeEntries', + localField: '_id', + foreignField: 'personId', + as: 'timeEntryData', }, }, { $project: { - personId: "$_id", + personId: '$_id', name: 1, weeklycommittedHours: 1, role: 1, timeEntryData: { $filter: { - input: "$timeEntryData", - as: "timeentry", + input: '$timeEntryData', + as: 'timeentry', cond: { $and: [ { - $gte: ["$$timeentry.dateOfWork", pdtstart], + $gte: ['$$timeentry.dateOfWork', pdtstart], }, { - $lte: ["$$timeentry.dateOfWork", pdtend], + $lte: ['$$timeentry.dateOfWork', pdtend], }, { $not: [ { - $in: [ - "$$timeentry.entryType", - ["person", "team", "project"], - ], + $in: ['$$timeentry.entryType', ['person', 'team', 'project']], }, ], }, @@ -90,7 +76,7 @@ const dashboardhelper = function () { }, { $unwind: { - path: "$timeEntryData", + path: '$timeEntryData', preserveNullAndEmptyArrays: true, }, }, @@ -101,27 +87,27 @@ const dashboardhelper = function () { totalSeconds: { $cond: [ { - $gte: ["$timeEntryData.totalSeconds", 0], + $gte: ['$timeEntryData.totalSeconds', 0], }, - "$timeEntryData.totalSeconds", + '$timeEntryData.totalSeconds', 0, ], }, tangibletime: { $cond: [ { - $eq: ["$timeEntryData.isTangible", true], + $eq: ['$timeEntryData.isTangible', true], }, - "$timeEntryData.totalSeconds", + '$timeEntryData.totalSeconds', 0, ], }, intangibletime: { $cond: [ { - $eq: ["$timeEntryData.isTangible", false], + $eq: ['$timeEntryData.isTangible', false], }, - "$timeEntryData.totalSeconds", + '$timeEntryData.totalSeconds', 0, ], }, @@ -130,17 +116,17 @@ const dashboardhelper = function () { { $group: { _id: { - personId: "$personId", - weeklycommittedHours: "$weeklycommittedHours", + personId: '$personId', + weeklycommittedHours: '$weeklycommittedHours', }, time_hrs: { - $sum: { $divide: ["$totalSeconds", 3600] }, + $sum: { $divide: ['$totalSeconds', 3600] }, }, tangibletime_hrs: { - $sum: { $divide: ["$tangibletime", 3600] }, + $sum: { $divide: ['$tangibletime', 3600] }, }, intangibletime_hrs: { - $sum: { $divide: ["$intangibletime", 3600] }, + $sum: { $divide: ['$intangibletime', 3600] }, }, }, }, @@ -148,15 +134,15 @@ const dashboardhelper = function () { $group: { _id: 0, memberCount: { $sum: 1 }, - totalweeklycommittedHours: { $sum: "$_id.weeklycommittedHours" }, + totalweeklycommittedHours: { $sum: '$_id.weeklycommittedHours' }, totaltime_hrs: { - $sum: "$time_hrs", + $sum: '$time_hrs', }, totaltangibletime_hrs: { - $sum: "$tangibletime_hrs", + $sum: '$tangibletime_hrs', }, totalintangibletime_hrs: { - $sum: "$intangibletime_hrs", + $sum: '$intangibletime_hrs', }, }, }, @@ -168,38 +154,28 @@ const dashboardhelper = function () { const getLeaderboard = async function (userId) { const userid = mongoose.Types.ObjectId(userId); try { - const userById = await userProfile.findOne( - { _id: userid, isActive: true }, - { role: 1 } - ); + const userById = await userProfile.findOne({ _id: userid, isActive: true }, { role: 1 }); if (userById == null) return null; const userRole = userById.role; - const pdtstart = moment() - .tz("America/Los_Angeles") - .startOf("week") - .format("YYYY-MM-DD"); + const pdtstart = moment().tz('America/Los_Angeles').startOf('week').format('YYYY-MM-DD'); - const pdtend = moment() - .tz("America/Los_Angeles") - .endOf("week") - .format("YYYY-MM-DD"); + const pdtend = moment().tz('America/Los_Angeles').endOf('week').format('YYYY-MM-DD'); let teamMemberIds = [userid]; let teamMembers = []; - const userAsRequestor = {'role': userRole, requestorId: userId }; + const userAsRequestor = { role: userRole, requestorId: userId }; const canSeeUsersInDashboard = await hasPermission(userAsRequestor, 'seeUsersInDashboard'); if (!canSeeUsersInDashboard) { // Manager , Mentor , Volunteer ... , Show only team members const teamsResult = await team.find( - { "members.userId": { $in: [userid] } }, - { members: 1 } + { 'members.userId': { $in: [userid] } }, + { members: 1 }, ); teamsResult.forEach((_myTeam) => { _myTeam.members.forEach((teamMember) => { - if (!teamMember.userId.equals(userid)) - teamMemberIds.push(teamMember.userId); + if (!teamMember.userId.equals(userid)) teamMemberIds.push(teamMember.userId); }); }); @@ -214,7 +190,7 @@ const dashboardhelper = function () { weeklySummaries: 1, timeOffFrom: 1, timeOffTill: 1, - } + }, ); } else { // 'Core Team', 'Owner' //All users @@ -229,11 +205,11 @@ const dashboardhelper = function () { weeklySummaries: 1, timeOffFrom: 1, timeOffTill: 1, - } + }, ); } - teamMemberIds = teamMembers.map(member => member._id); + teamMemberIds = teamMembers.map((member) => member._id); const timeEntries = await timeentry.find({ dateOfWork: { @@ -241,6 +217,7 @@ const dashboardhelper = function () { $lte: pdtend, }, personId: { $in: teamMemberIds }, + isActive: { $ne: false }, }); const timeEntryByPerson = {}; @@ -256,11 +233,9 @@ const dashboardhelper = function () { } if (timeEntry.isTangible === true) { - timeEntryByPerson[personIdStr].tangibleSeconds += - timeEntry.totalSeconds; + timeEntryByPerson[personIdStr].tangibleSeconds += timeEntry.totalSeconds; } else { - timeEntryByPerson[personIdStr].intangibleSeconds += - timeEntry.totalSeconds; + timeEntryByPerson[personIdStr].intangibleSeconds += timeEntry.totalSeconds; } timeEntryByPerson[personIdStr].totalSeconds += timeEntry.totalSeconds; @@ -275,24 +250,20 @@ const dashboardhelper = function () { isVisible: teamMember.isVisible, hasSummary: teamMember.weeklySummaries?.length > 0 - ? teamMember.weeklySummaries[0].summary !== "" + ? teamMember.weeklySummaries[0].summary !== '' : false, weeklycommittedHours: teamMember.weeklycommittedHours, totaltangibletime_hrs: - timeEntryByPerson[teamMember._id.toString()]?.tangibleSeconds / - 3600 || 0, + (timeEntryByPerson[teamMember._id.toString()]?.tangibleSeconds || 0) / 3600, totalintangibletime_hrs: - timeEntryByPerson[teamMember._id.toString()]?.intangibleSeconds / - 3600 || 0, - totaltime_hrs: - timeEntryByPerson[teamMember._id.toString()]?.totalSeconds / 3600 || - 0, + (timeEntryByPerson[teamMember._id.toString()]?.intangibleSeconds || 0) / 3600, + totaltime_hrs: (timeEntryByPerson[teamMember._id.toString()]?.totalSeconds || 0) / 3600, percentagespentintangible: timeEntryByPerson[teamMember._id.toString()] && timeEntryByPerson[teamMember._id.toString()]?.totalSeconds !== 0 && timeEntryByPerson[teamMember._id.toString()]?.tangibleSeconds !== 0 - ? (timeEntryByPerson[teamMember._id.toString()]?.tangibleSeconds / - timeEntryByPerson[teamMember._id.toString()]?.totalSeconds) * + ? ((timeEntryByPerson[teamMember._id.toString()]?.tangibleSeconds || 0) / + (timeEntryByPerson[teamMember._id.toString()]?.totalSeconds || 1)) * 100 : 0, timeOffFrom: teamMember.timeOffFrom || null, @@ -578,15 +549,9 @@ const dashboardhelper = function () { */ const getUserLaborData = async function (userId) { try { - const pdtStart = moment() - .tz("America/Los_Angeles") - .startOf("week") - .format("YYYY-MM-DD"); + const pdtStart = moment().tz('America/Los_Angeles').startOf('week').format('YYYY-MM-DD'); - const pdtEnd = moment() - .tz("America/Los_Angeles") - .endOf("week") - .format("YYYY-MM-DD"); + const pdtEnd = moment().tz('America/Los_Angeles').endOf('week').format('YYYY-MM-DD'); const user = await userProfile.findById({ _id: userId, @@ -597,7 +562,8 @@ const dashboardhelper = function () { $gte: pdtStart, $lte: pdtEnd, }, - entryType: { $in: ["default", null] }, + entryType: { $in: ['default', null] }, + isActive: { $ne: false }, personId: userId, }); @@ -617,14 +583,13 @@ const dashboardhelper = function () { personId: userId, role: user.role, isVisible: user.isVisible, - hasSummary: user.weeklySummaries[0].summary !== "", + hasSummary: user.weeklySummaries[0].summary !== '', weeklycommittedHours: user.weeklycommittedHours, name: `${user.firstName} ${user.lastName}`, totaltime_hrs: (tangibleSeconds + intangibleSeconds) / 3600, totaltangibletime_hrs: tangibleSeconds / 3600, totalintangibletime_hrs: intangibleSeconds / 3600, - percentagespentintangible: - (intangibleSeconds / tangibleSeconds) * 100, + percentagespentintangible: (intangibleSeconds / tangibleSeconds) * 100, timeOffFrom: user.timeOffFrom, timeOffTill: user.timeOffTill, }, @@ -632,8 +597,8 @@ const dashboardhelper = function () { } catch (err) { return [ { - personId: "error", - name: "Error Error", + personId: 'error', + name: 'Error Error', totaltime_hrs: 0, totaltangibletime_hrs: 0, totalintangibletime_hrs: 0, @@ -644,8 +609,8 @@ const dashboardhelper = function () { }; const laborthismonth = function (userId, startDate, endDate) { - const fromdate = moment(startDate).format("YYYY-MM-DD"); - const todate = moment(endDate).format("YYYY-MM-DD"); + const fromdate = moment(startDate).format('YYYY-MM-DD'); + const todate = moment(endDate).format('YYYY-MM-DD'); return timeentry.aggregate([ { @@ -661,19 +626,19 @@ const dashboardhelper = function () { { $group: { _id: { - projectId: "$projectId", + projectId: '$projectId', }, labor: { - $sum: "$totalSeconds", + $sum: '$totalSeconds', }, }, }, { $lookup: { - from: "projects", - localField: "_id.projectId", - foreignField: "_id", - as: "project", + from: 'projects', + localField: '_id.projectId', + foreignField: '_id', + as: 'project', }, }, { @@ -682,13 +647,13 @@ const dashboardhelper = function () { projectName: { $ifNull: [ { - $arrayElemAt: ["$project.projectName", 0], + $arrayElemAt: ['$project.projectName', 0], }, - "Undefined", + 'Undefined', ], }, timeSpent_hrs: { - $divide: ["$labor", 3600], + $divide: ['$labor', 3600], }, }, }, @@ -696,8 +661,8 @@ const dashboardhelper = function () { }; const laborthisweek = function (userId, startDate, endDate) { - const fromdate = moment(startDate).format("YYYY-MM-DD"); - const todate = moment(endDate).format("YYYY-MM-DD"); + const fromdate = moment(startDate).format('YYYY-MM-DD'); + const todate = moment(endDate).format('YYYY-MM-DD'); return userProfile.aggregate([ { @@ -713,10 +678,10 @@ const dashboardhelper = function () { }, { $lookup: { - from: "timeEntries", - localField: "_id", - foreignField: "personId", - as: "timeEntryData", + from: 'timeEntries', + localField: '_id', + foreignField: 'personId', + as: 'timeEntryData', }, }, { @@ -724,26 +689,23 @@ const dashboardhelper = function () { weeklycommittedHours: 1, timeEntryData: { $filter: { - input: "$timeEntryData", - as: "timeentry", + input: '$timeEntryData', + as: 'timeentry', cond: { $and: [ { - $eq: ["$$timeentry.isTangible", true], + $eq: ['$$timeentry.isTangible', true], }, { - $gte: ["$$timeentry.dateOfWork", fromdate], + $gte: ['$$timeentry.dateOfWork', fromdate], }, { - $lte: ["$$timeentry.dateOfWork", todate], + $lte: ['$$timeentry.dateOfWork', todate], }, { $not: [ { - $in: [ - "$$timeentry.entryType", - ["person", "team", "project"], - ], + $in: ['$$timeentry.entryType', ['person', 'team', 'project']], }, ], }, @@ -755,27 +717,27 @@ const dashboardhelper = function () { }, { $unwind: { - path: "$timeEntryData", + path: '$timeEntryData', preserveNullAndEmptyArrays: true, }, }, { $group: { _id: { - _id: "$_id", - weeklycommittedHours: "$weeklycommittedHours", + _id: '$_id', + weeklycommittedHours: '$weeklycommittedHours', }, effort: { - $sum: "$timeEntryData.totalSeconds", + $sum: '$timeEntryData.totalSeconds', }, }, }, { $project: { _id: 0, - weeklycommittedHours: "$_id.weeklycommittedHours", + weeklycommittedHours: '$_id.weeklycommittedHours', timeSpent_hrs: { - $divide: ["$effort", 3600], + $divide: ['$effort', 3600], }, }, }, @@ -783,8 +745,8 @@ const dashboardhelper = function () { }; const laborThisWeekByCategory = function (userId, startDate, endDate) { - const fromdate = moment(startDate).format("YYYY-MM-DD"); - const todate = moment(endDate).format("YYYY-MM-DD"); + const fromdate = moment(startDate).format('YYYY-MM-DD'); + const todate = moment(endDate).format('YYYY-MM-DD'); return userProfile.aggregate([ { @@ -800,10 +762,10 @@ const dashboardhelper = function () { }, { $lookup: { - from: "timeEntries", - localField: "_id", - foreignField: "personId", - as: "timeEntryData", + from: 'timeEntries', + localField: '_id', + foreignField: 'personId', + as: 'timeEntryData', }, }, { @@ -811,26 +773,23 @@ const dashboardhelper = function () { weeklycommittedHours: 1, timeEntryData: { $filter: { - input: "$timeEntryData", - as: "timeentry", + input: '$timeEntryData', + as: 'timeentry', cond: { $and: [ { - $eq: ["$$timeentry.isTangible", true], + $eq: ['$$timeentry.isTangible', true], }, { - $gte: ["$$timeentry.dateOfWork", fromdate], + $gte: ['$$timeentry.dateOfWork', fromdate], }, { - $lte: ["$$timeentry.dateOfWork", todate], + $lte: ['$$timeentry.dateOfWork', todate], }, { $not: [ { - $in: [ - "$$timeentry.entryType", - ["person", "team", "project"], - ], + $in: ['$$timeentry.entryType', ['person', 'team', 'project']], }, ], }, @@ -842,37 +801,37 @@ const dashboardhelper = function () { }, { $unwind: { - path: "$timeEntryData", + path: '$timeEntryData', preserveNullAndEmptyArrays: true, }, }, { $group: { - _id: "$timeEntryData.projectId", + _id: '$timeEntryData.projectId', effort: { - $sum: "$timeEntryData.totalSeconds", + $sum: '$timeEntryData.totalSeconds', }, }, }, { $lookup: { - from: "projects", - localField: "_id", - foreignField: "_id", - as: "project", + from: 'projects', + localField: '_id', + foreignField: '_id', + as: 'project', }, }, { $unwind: { - path: "$project", + path: '$project', preserveNullAndEmptyArrays: true, }, }, { $group: { - _id: "$project.category", + _id: '$project.category', effort: { - $sum: "$effort", + $sum: '$effort', }, }, }, @@ -880,7 +839,7 @@ const dashboardhelper = function () { $project: { _id: 1, timeSpent_hrs: { - $divide: ["$effort", 3600], + $divide: ['$effort', 3600], }, }, }, diff --git a/src/helpers/helperModels/userProjects.js b/src/helpers/helperModels/userProjects.js deleted file mode 100644 index a2f1f2b5e..000000000 --- a/src/helpers/helperModels/userProjects.js +++ /dev/null @@ -1,17 +0,0 @@ -const mongoose = require('mongoose'); - -const { Schema } = mongoose; - -const ProjectSchema = new Schema({ - projectId: { type: mongoose.SchemaTypes.ObjectId, ref: 'projects' }, - projectName: { type: String }, - category: { type: String }, -}); - -const userProjectSchema = new Schema({ - - _id: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile' }, - projects: [ProjectSchema], -}); - -module.exports = mongoose.model('userProject', userProjectSchema, 'userProjects'); diff --git a/src/helpers/taskHelper.js b/src/helpers/taskHelper.js index 96a8a7269..34fb36be8 100644 --- a/src/helpers/taskHelper.js +++ b/src/helpers/taskHelper.js @@ -11,7 +11,6 @@ const taskHelper = function () { const getTasksForTeams = async function (userId, requestor) { const userid = mongoose.Types.ObjectId(userId); const requestorId = mongoose.Types.ObjectId(requestor.requestorId); - const requestorRole = requestor.role; try { const userById = await userProfile.findOne( { _id: userid, isActive: true }, @@ -28,7 +27,7 @@ const taskHelper = function () { teamCode: 1, teams: 1, adminLinks: 1, - } + }, ); if (userById === null) return null; @@ -41,7 +40,7 @@ const taskHelper = function () { let teamMembers = []; const isRequestorOwnerLike = await hasPermission(requestor, 'seeUsersInDashboard'); - const userAsRequestor = {'role': userRole, requestorId: userId }; + const userAsRequestor = { role: userRole, requestorId: userId }; const isUserOwnerLike = await hasPermission(userAsRequestor, 'seeUsersInDashboard'); switch (true) { @@ -72,8 +71,8 @@ const taskHelper = function () { } case isRequestorOwnerLike && !isUserOwnerLike: { const teamsResult = await team.find( - { "members.userId": { $in: [userid] } }, - { members: 1 } + { 'members.userId': { $in: [userid] } }, + { members: 1 }, ); teamsResult.forEach((_myTeam) => { @@ -108,8 +107,8 @@ const taskHelper = function () { } default: { const sharedTeamsResult = await team.find( - { "members.userId": { $all: [userid, requestorId] } }, - { members: 1 } + { 'members.userId': { $all: [userid, requestorId] } }, + { members: 1 }, ); sharedTeamsResult.forEach((_myTeam) => { @@ -151,6 +150,7 @@ const taskHelper = function () { $lte: pdtend, }, personId: { $in: teamMemberIds }, + isActive: { $ne: false }, }); const timeEntryByPerson = {}; @@ -169,8 +169,8 @@ const taskHelper = function () { timeEntryByPerson[personIdStr].totalSeconds += timeEntry.totalSeconds; }); const teamMemberTasks = await Task.find( - { "resources.userID": { $in: teamMemberIds } }, - { "resources.profilePic": 0 } + { 'resources.userID': { $in: teamMemberIds } }, + { 'resources.profilePic': 0 }, ).populate({ path: 'wbsId', select: 'projectId', @@ -187,9 +187,7 @@ const taskHelper = function () { const taskNdUserID = `${taskIdStr},${userIdStr}`; if (taskNotificationByTaskNdUser[taskNdUserID]) { - taskNotificationByTaskNdUser[taskNdUserID].push( - teamMemberTaskNotification - ); + taskNotificationByTaskNdUser[taskNdUserID].push(teamMemberTaskNotification); } else { taskNotificationByTaskNdUser[taskNdUserID] = [teamMemberTaskNotification]; } @@ -593,6 +591,9 @@ const taskHelper = function () { { $in: ['$$timeentry.entryType', ['default', null]], }, + { + $ne: ['$$timeentry.isActive', false], + }, ], }, }, @@ -692,10 +693,15 @@ const taskHelper = function () { { $project: { tasks: { - resources: { - profilePic: 0, + $filter: { + input: '$tasks', + as: 'task', + cond: { + $ne: ['$$task.isActive', false], + }, }, }, + 'tasks.resources.profilePic': 0, }, }, { diff --git a/src/models/project.js b/src/models/project.js index 6a78a0b31..1ef8b269e 100644 --- a/src/models/project.js +++ b/src/models/project.js @@ -5,9 +5,24 @@ const { Schema } = mongoose; const projectschema = new Schema({ projectName: { type: String, required: true, unique: true }, isActive: { type: Boolean, default: true }, + isArchived: { type: Boolean, default: false }, createdDatetime: { type: Date }, modifiedDatetime: { type: Date, default: Date.now() }, - category: { type: String, enum: ['Food', 'Energy', 'Housing', 'Education', 'Society', 'Economics', 'Stewardship', 'Other', 'Unspecified'], default: 'Other' }, + category: { + type: String, + enum: [ + 'Food', + 'Energy', + 'Housing', + 'Education', + 'Society', + 'Economics', + 'Stewardship', + 'Other', + 'Unspecified', + ], + default: 'Other', + }, }); module.exports = mongoose.model('project', projectschema, 'projects'); diff --git a/src/models/timeentry.js b/src/models/timeentry.js index 4ae0b94fa..ea5303b3a 100644 --- a/src/models/timeentry.js +++ b/src/models/timeentry.js @@ -15,6 +15,7 @@ const TimeEntry = new Schema({ isTangible: { type: Boolean, default: false }, createdDateTime: { type: Date }, lastModifiedDateTime: { type: Date, default: Date.now }, + isActive: { type: Boolean, default: true }, }); module.exports = mongoose.model('timeEntry', TimeEntry, 'timeEntries'); diff --git a/src/models/wbs.js b/src/models/wbs.js index 73f9fd413..bcfbab074 100644 --- a/src/models/wbs.js +++ b/src/models/wbs.js @@ -3,13 +3,11 @@ const mongoose = require('mongoose'); const { Schema } = mongoose; const wbsschema = new Schema({ - wbsName: { type: String, required: true }, projectId: { type: mongoose.SchemaTypes.ObjectId, ref: 'project' }, isActive: { type: Boolean, default: true }, createdDatetime: { type: Date }, modifiedDatetime: { type: Date, default: Date.now() }, - }); module.exports = mongoose.model('wbs', wbsschema, 'wbs'); diff --git a/src/routes/taskRouter.js b/src/routes/taskRouter.js index b404cea0a..4f91dc4b2 100644 --- a/src/routes/taskRouter.js +++ b/src/routes/taskRouter.js @@ -2,56 +2,42 @@ const express = require('express'); const routes = function (task, userProfile) { const controller = require('../controllers/taskController')(task, userProfile); - const wbsRouter = express.Router(); + const taskRouter = express.Router(); - wbsRouter.route('/tasks/:wbsId/:level/:mother') + taskRouter + .route('/tasks/:wbsId/:level/:mother') .get(controller.getTasks) .put(controller.fixTasks); - wbsRouter.route('/task/:id') - .post(controller.postTask) - .get(controller.getTaskById); + taskRouter.route('/task/:id').post(controller.postTask).get(controller.getTaskById); - wbsRouter.route('/task/import/:id') - .post(controller.importTask); + taskRouter.route('/task/import/:id').post(controller.importTask); - wbsRouter.route('/task/del/:taskId/:mother') - .post(controller.deleteTask); + taskRouter.route('/task/del/:taskId/:mother').post(controller.deleteTask); - wbsRouter.route('/task/wbs/:wbsId') - .get(controller.getWBSId); + taskRouter.route('/task/wbs/:wbsId').get(controller.getWBSId); - wbsRouter.route('/task/wbs/del/:wbsId') - .post(controller.deleteTaskByWBS); + taskRouter.route('/task/wbs/del/:wbsId').post(controller.deleteTaskByWBS); - wbsRouter.route('/task/update/:taskId') - .put(controller.updateTask); + taskRouter.route('/task/update/:taskId').put(controller.updateTask); - wbsRouter.route('/task/updateStatus/:taskId') - .put(controller.updateTaskStatus); + taskRouter.route('/task/updateStatus/:taskId').put(controller.updateTaskStatus); - wbsRouter.route('/task/updateAllParents/:wbsId/') - .put(controller.updateAllParents); + taskRouter.route('/task/updateAllParents/:wbsId/').put(controller.updateAllParents); - wbsRouter.route('/tasks/swap/') - .put(controller.swap); + taskRouter.route('/tasks/swap/').put(controller.swap); - wbsRouter.route('/tasks/update/num') - .put(controller.updateNum); + taskRouter.route('/tasks/update/num').put(controller.updateNum); - wbsRouter.route('/tasks/moveTasks/:wbsId') - .put(controller.moveTask); + taskRouter.route('/tasks/moveTasks/:wbsId').put(controller.moveTask); - wbsRouter.route('/tasks/user/:userId') - .get(controller.getTasksByUserId); + taskRouter.route('/tasks/user/:userId').get(controller.getTasksByUserId); - wbsRouter.route('/user/:userId/teams/tasks') - .get(controller.getTasksForTeamsByUser); + taskRouter.route('/user/:userId/teams/tasks').get(controller.getTasksForTeamsByUser); - wbsRouter.route('/tasks/reviewreq/:userId') - .post(controller.sendReviewReq); + taskRouter.route('/tasks/reviewreq/:userId').post(controller.sendReviewReq); - return wbsRouter; + return taskRouter; }; module.exports = routes; diff --git a/src/routes/userProfileRouter.js b/src/routes/userProfileRouter.js index 2673bbed6..e6892026b 100644 --- a/src/routes/userProfileRouter.js +++ b/src/routes/userProfileRouter.js @@ -11,15 +11,15 @@ const routes = function (userProfile) { .route('/userProfile') .get(controller.getUserProfiles) .post( - body('firstName').customSanitizer(value => value.trim()), - body('lastName').customSanitizer(value => value.trim()), + body('firstName').customSanitizer((value) => value.trim()), + body('lastName').customSanitizer((value) => value.trim()), controller.postUserProfile, ); userProfileRouter .route('/userProfile/:userId') .get(controller.getUserById) - .put( + .put( body('firstName').customSanitizer((req) => req.trim()), body('lastName').customSanitizer((req) => req.trim()), body('personalLinks').customSanitizer((req) => diff --git a/src/routes/wbsRouter.js b/src/routes/wbsRouter.js index a5eb2d126..8a646c757 100644 --- a/src/routes/wbsRouter.js +++ b/src/routes/wbsRouter.js @@ -6,15 +6,9 @@ const routes = function (wbs) { wbsRouter.route('/wbs/:projectId').get(controller.getAllWBS); - wbsRouter.route('/wbs/:id') - .post(controller.postWBS) - .delete(controller.deleteWBS); + wbsRouter.route('/wbs/:id').post(controller.postWBS).delete(controller.deleteWBS); - wbsRouter.route('/wbsId/:id') - .get(controller.getWBSById); - - wbsRouter.route('/wbs/user/:userId') - .get(controller.getWBSByUserId); + wbsRouter.route('/wbsId/:id').get(controller.getWBSById); wbsRouter.route('/wbs').get(controller.getWBS);