diff --git a/lib/model/db/department.js b/lib/model/db/department.js index 087877e6a..ae2254695 100644 --- a/lib/model/db/department.js +++ b/lib/model/db/department.js @@ -98,7 +98,8 @@ module.exports = function(sequelize, DataTypes) { // Return users related to current department and still active promise_active_users : function(){ return this.getUsers({ - where : sequelize.models.User.get_active_user_filter() + scope: ["withDepartments"], + where: sequelize.models.User.get_active_user_filter() }); }, diff --git a/lib/route/calendar.js b/lib/route/calendar.js index 8c47a373f..202d7ba4b 100644 --- a/lib/route/calendar.js +++ b/lib/route/calendar.js @@ -14,6 +14,7 @@ var express = require('express'), const {createNewLeave, getLeaveForUserView, doesUserHasExtendedViewOfLeave} = require('../model/leave'); const { leaveIntoObject } = require('../model/Report'); const { getCommentsForLeave } = require('../model/comment'); +const { sorter } = require('../util'); router.post('/bookleave/', function(req, res){ @@ -125,66 +126,88 @@ router.get('/', function(req, res) { }); -router.get('/teamview/', function(req, res){ +router.get('/teamview/', async (req, res) => { + const user = req.user; - if (req.user.company.is_team_view_hidden && ! req.user.admin) { + if (user.company.is_team_view_hidden && !user.admin) { return res.redirect_with_session('/'); } const base_date = validator.isDate(req.query['date']) ? moment.utc(req.query['date']) - : req.user.company.get_today(); + : user.company.get_today(); - const team_view = new TeamView({ - base_date : base_date, - user : req.user, - }); + const grouped_mode = !! req.query['grouped_mode']; + + const team_view = new TeamView({ user, base_date }); - const current_deparment_id = validator.isNumeric(req.query['department']) + const currentDepartmentId = validator.isNumeric(req.query['department']) ? req.query['department'] : null; - Promise.join( - team_view.promise_team_view_details({ - department_id : current_deparment_id, - }), - req.user.get_company_with_all_leave_types(), - (team_view_details, company) => { - // Enrich "team view details" with statistics as how many deducted days each employee spent current month - team_view - .inject_statistics({ - team_view_details : team_view_details, - leave_types : company.leave_types, - }) - .then( team_view_details => team_view.restrainStatisticsForUser({ - team_view_details : team_view_details, - user : req.user, - })) - .then(team_view_details => res.render('team_view', { - base_date : base_date, - prev_date : moment.utc(base_date).add(-1,'month'), - next_date : moment.utc(base_date).add(1,'month'), - users_and_leaves : team_view_details.users_and_leaves, - related_departments : team_view_details.related_departments, - current_department : team_view_details.current_department, - company : company, - }) - ); - }) - .catch(error => { - console.error( - 'An error occured when user '+req.user.id+ - ' tried to access Teamview page: '+error - ); - req.session.flash_error('Failed to access Teamview page. Please contact administrator.'); - if (error.hasOwnProperty('user_message')) { - req.session.flash_error(error.user_message); - } - return res.redirect_with_session('/'); + try { + const [team_view_details, company] = await Promise.all([ + team_view.promise_team_view_details({ + department_id: currentDepartmentId, + }), + user.get_company_with_all_leave_types(), + ]); + + // Enrich "team view details" with statistics as how many deducted days each employee spent current month + const team_view_details_with_stat = await team_view.inject_statistics({ + team_view_details, + leave_types: company.leave_types, + }); + + const {users_and_leaves, related_departments, current_department} = await team_view.restrainStatisticsForUser({ + user, + team_view_details: team_view_details_with_stat, }); + const renderingContext = { + company, + users_and_leaves, + related_departments, + current_department, + base_date, + prev_date: moment.utc(base_date).add(-1, 'month'), + next_date: moment.utc(base_date).add(1, 'month'), + }; + + if (grouped_mode) { + renderingContext.grouped_mode = true; + renderingContext.users_and_leaves_by_departments = groupUsersOnTeamViewByDepartments(users_and_leaves); + } + + res.render('team_view', renderingContext); + } + catch (error) { + console.error( + `An error occurred when user ${user.id} tried to access TeamView page: ${error}, at ${error.stack}` + ); + req.session.flash_error('Failed to access TeamView page. Please contact administrator.'); + + if (error.hasOwnProperty('user_message')) { + req.session.flash_error(error.user_message); + } + + return res.redirect_with_session('/'); + }; }); +const groupUsersOnTeamViewByDepartments = (usersAndLeaves) => { + const departmentsDict = usersAndLeaves.reduce( + (acc, item) => ({ ...acc, [item.user.department.id]: { departmentName: item.user.department.name, users_and_leaves: [] } }), + {} + ); + + usersAndLeaves.forEach(item => { + departmentsDict[item.user.department.id].users_and_leaves.push(item); + }); + + return Object.values(departmentsDict).sort((a, b) => sorter(a.departmentName, b.departmentName)); +}; + router.get('/feeds/', function(req, res){ req.user .getFeeds() diff --git a/views/partials/footer.hbs b/views/partials/footer.hbs index 78589c700..98be24770 100644 --- a/views/partials/footer.hbs +++ b/views/partials/footer.hbs @@ -6,7 +6,7 @@