Skip to content

Commit

Permalink
Merge pull request #1134 from OneCommunityGlobal/development
Browse files Browse the repository at this point in the history
Backend Release to Main [2.02]
  • Loading branch information
one-community authored Oct 16, 2024
2 parents 1afa0bd + 2118c51 commit d76c0b3
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 7 deletions.
68 changes: 68 additions & 0 deletions src/controllers/timeEntryController.js
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,72 @@ const timeEntrycontroller = function (TimeEntry) {
});
};

const getTimeEntriesForProjectReports = function (req, res) {
const { users, fromDate, toDate } = req.body;

// Fetch only necessary fields and avoid bringing the entire document
TimeEntry.find(
{
personId: { $in: users },
dateOfWork: { $gte: fromDate, $lte: toDate },
},
'totalSeconds isTangible dateOfWork projectId',
)
.populate('projectId', 'projectName _id')
.lean() // lean() for better performance as we don't need Mongoose document methods
.then((results) => {
const data = results.map((element) => {
const record = {
isTangible: element.isTangible,
dateOfWork: element.dateOfWork,
projectId: element.projectId ? element.projectId._id : '',
projectName: element.projectId ? element.projectId.projectName : '',
};

// Convert totalSeconds to hours and minutes
[record.hours, record.minutes] = formatSeconds(element.totalSeconds);

return record;
});

res.status(200).send(data);
})
.catch((error) => {
res.status(400).send({ message: 'Error fetching time entries for project reports', error });
});
};

const getTimeEntriesForPeopleReports = async function (req, res) {
try {
const { users, fromDate, toDate } = req.body;

const results = await TimeEntry.find(
{
personId: { $in: users },
dateOfWork: { $gte: fromDate, $lte: toDate },
},
'personId totalSeconds isTangible dateOfWork',
).lean(); // Use lean() for better performance

const data = results
.map((entry) => {
const [hours, minutes] = formatSeconds(entry.totalSeconds);
return {
personId: entry.personId,
hours,
minutes,
isTangible: entry.isTangible,
dateOfWork: entry.dateOfWork,
};
})
.filter(Boolean);

res.status(200).send(data);
} catch (error) {
res.status(400).send({ message: 'Error fetching time entries for people reports', error });
}
};

/**
* Get time entries for a specified project
*/
Expand Down Expand Up @@ -1488,6 +1554,8 @@ const timeEntrycontroller = function (TimeEntry) {
backupIntangibleHrsAllUsers,
recalculateIntangibleHrsAllUsers,
getTimeEntriesForReports,
getTimeEntriesForProjectReports,
getTimeEntriesForPeopleReports,
startRecalculation,
checkRecalculationStatus,
};
Expand Down
59 changes: 54 additions & 5 deletions src/controllers/userProfileController.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ const userProfileController = function (UserProfile, Project) {
.catch((error) => res.status(404).send(error));
};

/**
* Controller function to retrieve basic user profile information.
* This endpoint checks if the user has the necessary permissions to access user profiles.
* If authorized, it queries the database to fetch only the required fields:
* _id, firstName, lastName, isActive, startDate, and endDate, sorted by last name.
*/
const getUserProfileBasicInfo = async function (req, res) {
if (!(await checkPermission(req, 'getUserProfiles'))) {
forbidden(res, 'You are not authorized to view all users');
return;
}

await UserProfile.find({}, '_id firstName lastName isActive startDate createdDate endDate')
.sort({
lastName: 1,
})
.then((results) => {
if (!results) {
if (cache.getCache('allusers')) {
const getData = JSON.parse(cache.getCache('allusers'));
res.status(200).send(getData);
return;
}
res.status(500).send({ error: 'User result was invalid' });
return;
}
cache.setCache('allusers', JSON.stringify(results));
res.status(200).send(results);
})
.catch((error) => res.status(404).send(error));
};

const getProjectMembers = async function (req, res) {
if (!(await hasPermission(req.body.requestor, 'getProjectMembers'))) {
res.status(403).send('You are not authorized to view all users');
Expand Down Expand Up @@ -326,6 +358,7 @@ const userProfileController = function (UserProfile, Project) {
up.adminLinks = req.body.adminLinks;
up.teams = Array.from(new Set(req.body.teams));
up.projects = Array.from(new Set(req.body.projects));
up.teamCode = req.body.teamCode;
up.createdDate = req.body.createdDate;
up.startDate = req.body.startDate ? req.body.startDate : req.body.createdDate;
up.email = req.body.email;
Expand Down Expand Up @@ -644,7 +677,7 @@ const userProfileController = function (UserProfile, Project) {
}

if (req.body.startDate !== undefined && record.startDate !== req.body.startDate) {
record.startDate = moment(req.body.startDate).toDate();
record.startDate = moment.tz(req.body.startDate, 'America/Los_Angeles').toDate();
// Make sure weeklycommittedHoursHistory isn't empty
if (record.weeklycommittedHoursHistory.length === 0) {
const newEntry = {
Expand All @@ -667,7 +700,7 @@ const userProfileController = function (UserProfile, Project) {

if (req.body.endDate !== undefined) {
if (yearMonthDayDateValidator(req.body.endDate)) {
record.endDate = moment(req.body.endDate).toDate();
record.endDate = moment.tz(req.body.endDate, 'America/Los_Angeles').toDate();
if (isUserInCache) {
userData.endDate = record.endDate.toISOString();
}
Expand Down Expand Up @@ -888,9 +921,9 @@ const userProfileController = function (UserProfile, Project) {
options: {
sort: {
date: -1, // Sort by date descending if needed
},
},
},
},
])
.exec()
.then((results) => {
Expand Down Expand Up @@ -1178,7 +1211,7 @@ const userProfileController = function (UserProfile, Project) {
const setEndDate = dateObject;
if (moment().isAfter(moment(setEndDate).add(1, 'days'))) {
activeStatus = false;
}else if(moment().isBefore(moment(endDate).subtract(3, 'weeks'))){
} else if (moment().isBefore(moment(endDate).subtract(3, 'weeks'))) {
emailThreeWeeksSent = true;
}
}
Expand Down Expand Up @@ -1762,9 +1795,23 @@ const userProfileController = function (UserProfile, Project) {
.status(500)
.send({ message: 'Encountered an error to get all team codes, please try again!' });
}

};

const updateUserInformation = async function (req,res){
try {
const data=req.body;
data.map(async (e)=> {
let result = await UserProfile.findById(e.user_id);
result[e.item]=e.value
let newdata=await result.save()
})
res.status(200).send({ message: 'Update successful'});
} catch (error) {
console.log(error)
return res.status(500)
}
}

return {
postUserProfile,
getUserProfiles,
Expand Down Expand Up @@ -1793,6 +1840,8 @@ const userProfileController = function (UserProfile, Project) {
getProjectsByPerson,
getAllTeamCode,
getAllTeamCodeHelper,
updateUserInformation,
getUserProfileBasicInfo
};
};

Expand Down
11 changes: 11 additions & 0 deletions src/cronjobs/userProfileJobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ const userProfileJobs = () => {
}
await userhelper.awardNewBadges();
await userhelper.reActivateUser();
},
null,
false,
'America/Los_Angeles',
);

// Job to run every day, 1 minute past midnight to deactivate the user
const dailyUserDeactivateJobs = new CronJob(
'1 0 * * *', // Every day, 1 minute past midnight
async () => {
await userhelper.deActivateUser();
},
null,
Expand All @@ -27,5 +37,6 @@ const userProfileJobs = () => {
);

allUserProfileJobs.start();
dailyUserDeactivateJobs.start();
};
module.exports = userProfileJobs;
8 changes: 7 additions & 1 deletion src/helpers/taskHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,15 @@ const taskHelper = function () {
);

sharedTeamsResult.forEach((_myTeam) => {
let hasTeamVisibility = false;
_myTeam.members.forEach((teamMember) => {
if (!teamMember.userId.equals(userid)) teamMemberIds.push(teamMember.userId);
if (teamMember.userId.equals(userid) && teamMember.visible) hasTeamVisibility = true;
});
if (hasTeamVisibility) {
_myTeam.members.forEach((teamMember) => {
if (!teamMember.userId.equals(userid)) teamMemberIds.push(teamMember.userId);
});
}
});

teamMembers = await userProfile
Expand Down
8 changes: 8 additions & 0 deletions src/routes/timeentryRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ const routes = function (TimeEntry) {

TimeEntryRouter.route('/TimeEntry/reports').post(controller.getTimeEntriesForReports);

TimeEntryRouter.route('/TimeEntry/reports/projects').post(
controller.getTimeEntriesForProjectReports,
);

TimeEntryRouter.route('/TimeEntry/reports/people').post(
controller.getTimeEntriesForPeopleReports,
);

TimeEntryRouter.route('/TimeEntry/lostUsers').post(controller.getLostTimeEntriesForUserList);

TimeEntryRouter.route('/TimeEntry/lostProjects').post(
Expand Down
3 changes: 3 additions & 0 deletions src/routes/userProfileRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const routes = function (userProfile, project) {
controller.postUserProfile,
);

userProfileRouter.route('/userProfile/update').patch(controller.updateUserInformation);
// Endpoint to retrieve basic user profile information
userProfileRouter.route('/userProfile/basicInfo').get(controller.getUserProfileBasicInfo);
userProfileRouter
.route('/userProfile/:userId')
.get(controller.getUserById)
Expand Down
1 change: 0 additions & 1 deletion src/utilities/createInitialPermissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ const permissionsRoles = [
permissions: [
'suggestTask',
'putReviewStatus',
'putUserProfile',
'getReporteesLimitRoles',
'getAllInvInProjectWBS',
'postInvInProjectWBS',
Expand Down

0 comments on commit d76c0b3

Please sign in to comment.