Skip to content

Commit 712b718

Browse files
committed
Merge branch 'tom-184__vpp__team_view_absence_summary'
2 parents c4dc719 + 91f514b commit 712b718

13 files changed

+928
-38
lines changed

lib/model/db/leave_type.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module.exports = function(sequelize, DataTypes) {
4343
color : '#459FF3',
4444
companyId : company.id,
4545
limit : 10,
46+
use_allowance : 0,
4647
},
4748
])
4849
},

lib/model/team_view.js

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11

22
'use strict';
33

4-
var moment = require('moment'),
5-
Promise = require('bluebird'),
6-
_ = require('underscore');
4+
const
5+
moment = require('moment'),
6+
Promise = require('bluebird'),
7+
Joi = require('joi'),
8+
_ = require('underscore');
79

810
function TeamView(args) {
911
var me = this;
@@ -87,4 +89,114 @@ TeamView.prototype.promise_team_view_details = function(args){
8789

8890
};
8991

92+
// Experimenting with parameter validation done with Joi.js
93+
const inject_statistics_args_schema = Joi.object()
94+
.keys({
95+
leave_types : Joi.array().items(
96+
Joi.object().keys({
97+
id : Joi.number().required(),
98+
use_allowance : Joi.boolean().required(),
99+
})
100+
),
101+
team_view_details : Joi.object().required().keys({
102+
users_and_leaves : Joi.array().required().items(
103+
Joi.object().keys()
104+
)
105+
}),
106+
});
107+
108+
/*
109+
* Takes "team view details" and enrich them with statistics about absences
110+
* each employee has for given month
111+
*
112+
* */
113+
114+
TeamView.prototype.inject_statistics = function(args){
115+
116+
// Validate parameters
117+
let param_validation = Joi.validate(args, inject_statistics_args_schema, { allowUnknown : true });
118+
if (param_validation.error) {
119+
console.log('An error occured when trying to validate args in inject_statistics.');
120+
console.dir(param_validation.error);
121+
throw new Error('Failed to validate parameters in TeamView.inject_statistics');
122+
}
123+
124+
let
125+
team_view_details = args.team_view_details,
126+
leave_types = args.leave_types || [];
127+
128+
// Convert leave types array into look-up map
129+
let leave_types_map = {};
130+
leave_types.forEach( lt => leave_types_map[lt.id] = lt );
131+
132+
133+
team_view_details
134+
.users_and_leaves
135+
.forEach(node => {
136+
137+
let deducted_days = 0;
138+
139+
node
140+
.days
141+
// Consider only those days that have any leave objects
142+
.filter( day => !! day.leave_obj )
143+
// Ignore those days which were not approved yet
144+
.filter( day => !! day.leave_obj.is_approved_leave() )
145+
// Ignore weekends
146+
.filter( day => ! day.is_weekend )
147+
// Ignore bank holidays
148+
.filter( day => ! day.is_bank_holiday )
149+
.forEach( day => {
150+
let leave_type = leave_types_map[ day.leave_obj.leaveTypeId ];
151+
152+
if (! (leave_type && leave_type.use_allowance)) {
153+
return;
154+
}
155+
156+
if (day.is_leave_afternoon && day.is_leave_morning){
157+
deducted_days++;
158+
} else {
159+
deducted_days = deducted_days + 0.5;
160+
}
161+
});
162+
163+
let statistics = {
164+
deducted_days : deducted_days,
165+
};
166+
167+
node.statistics = statistics;
168+
});
169+
170+
return Promise.resolve( team_view_details );
171+
};
172+
173+
/*
174+
* Take "team view details" and user for whom them were generated
175+
* and ensure the details contain statisticts for only those employees
176+
* current user has access to.
177+
*
178+
* */
179+
180+
TeamView.prototype.restrainStatisticsForUser = function(args){
181+
182+
// TODO Consider parameters validation in the same fashion as in inject_statistics method
183+
184+
let
185+
team_view_details = args.team_view_details,
186+
observer_user = args.user;
187+
188+
let supervised_user_map = {};
189+
observer_user.supervised_users.forEach( u => supervised_user_map[ u.id ] = u);
190+
191+
team_view_details
192+
.users_and_leaves
193+
.forEach(item => {
194+
if (item.statistics && ! supervised_user_map[ item.user.id ]) {
195+
delete item.statistics;
196+
}
197+
});
198+
199+
return Promise.resolve( team_view_details );
200+
};
201+
90202
module.exports = TeamView;

lib/route/calendar.js

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,38 @@ router.get('/teamview/', function(req, res){
157157
department_id : current_deparment_id,
158158
}),
159159
req.user.get_company_with_all_leave_types(),
160-
function(team_view_details, company){
161-
162-
return res.render('team_view', {
163-
base_date : base_date,
164-
prev_date : moment(base_date).add(-1,'month'),
165-
next_date : moment(base_date).add(1,'month'),
166-
users_and_leaves : team_view_details.users_and_leaves,
167-
related_departments : team_view_details.related_departments,
168-
current_department : team_view_details.current_department,
169-
company : company,
170-
});
171-
160+
(team_view_details, company) => {
161+
// Enrich "team view details" with statistics as how many deducted days each employee spent current month
162+
team_view
163+
.inject_statistics({
164+
team_view_details : team_view_details,
165+
leave_types : company.leave_types,
166+
})
167+
.then( team_view_details => team_view.restrainStatisticsForUser({
168+
team_view_details : team_view_details,
169+
user : req.user,
170+
}))
171+
.then(team_view_details => res.render('team_view', {
172+
base_date : base_date,
173+
prev_date : moment(base_date).add(-1,'month'),
174+
next_date : moment(base_date).add(1,'month'),
175+
users_and_leaves : team_view_details.users_and_leaves,
176+
related_departments : team_view_details.related_departments,
177+
current_department : team_view_details.current_department,
178+
company : company,
179+
})
180+
);
181+
})
182+
.catch(error => {
183+
console.error(
184+
'An error occured when user '+req.user.id+
185+
' tried to access Teamview page: '+error
186+
);
187+
req.session.flash_error('Failed to access Teamview page. Please contact administrator.');
188+
if (error.hasOwnProperty('user_message')) {
189+
req.session.flash_error(error.user_message);
190+
}
191+
return res.redirect_with_session('/');
172192
});
173193

174194
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"formidable": "~1.0.17",
1919
"html-to-text": "^3.2.0",
2020
"ical-generator": "^0.2.7",
21+
"joi": "~12.0.0",
2122
"ldapauth-fork": "^2.5.2",
2223
"moment": "^2.11.2",
2324
"moment-timezone": "^0.5.10",

public/css/style.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ td.leave_cell_pended {
8686
padding-top: 5px;
8787
padding-bottom: 5px; }
8888

89+
.team-view-users .user-name-cell {
90+
text-overflow: ellipsis;
91+
/* Cannot avoid specifying width with pixels... */
92+
width: 165px;
93+
white-space: nowrap;
94+
overflow: hidden;
95+
display: inline-block; }
96+
8997
td.team-view-header {
9098
height: 43px; }
9199

@@ -158,6 +166,7 @@ div.feeds-holder {
158166
body.modal-open {
159167
position: fixed; } }
160168

169+
/* To be used for selected items in lists */
161170
.selected-item {
162171
background: #F5F7F8;
163172
font-weight: bolder; }

scss/main.scss

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,17 @@ td.leave_cell_pended {
106106
max-width : 450px;
107107
}
108108
.team-view-users td {
109-
padding-top : 5px;
110-
padding-bottom : 5px;
109+
padding-top : 5px;
110+
padding-bottom : 5px;
111+
112+
}
113+
.team-view-users .user-name-cell {
114+
text-overflow: ellipsis;
115+
/* Cannot avoid specifying width with pixels... */
116+
width: 165px;
117+
white-space: nowrap;
118+
overflow: hidden;
119+
display: inline-block;
111120
}
112121
td.team-view-header {
113122
height: 43px;

t/integration/crud_leave_type.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe('CRUD for leave types', function(){
7676
},{
7777
selector : leave_type_edit_form_id+' input[name="use_allowance__1"]',
7878
tick : true,
79-
value : 'on',
79+
value : 'off',
8080
}],
8181
})
8282
.then(function(){ done() });
@@ -88,7 +88,7 @@ describe('CRUD for leave types', function(){
8888
form_params : [{
8989
selector : leave_type_edit_form_id+' input[name="use_allowance__1"]',
9090
tick : true,
91-
value : 'off',
91+
value : 'on',
9292
}],
9393
should_be_successful : true,
9494
submit_button_selector : leave_type_edit_form_id+' button[type="submit"]',
@@ -106,7 +106,7 @@ describe('CRUD for leave types', function(){
106106
tick : true,
107107
},{
108108
selector : leave_type_edit_form_id+' input[name="use_allowance__1"]',
109-
value : 'off',
109+
value : 'on',
110110
tick : true,
111111
}],
112112
})

t/integration/basic_wall_chart.js renamed to t/integration/team_view/basic_wall_chart.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ var test = require('selenium-webdriver/testing'),
88
Promise = require("bluebird"),
99
until = require('selenium-webdriver').until,
1010
_ = require('underscore'),
11-
register_new_user_func = require('../lib/register_new_user'),
12-
login_user_func = require('../lib/login_with_user'),
13-
open_page_func = require('../lib/open_page'),
14-
submit_form_func = require('../lib/submit_form'),
15-
add_new_user_func = require('../lib/add_new_user'),
16-
logout_user_func = require('../lib/logout_user'),
17-
config = require('../lib/config'),
11+
register_new_user_func = require('../../lib/register_new_user'),
12+
login_user_func = require('../../lib/login_with_user'),
13+
open_page_func = require('../../lib/open_page'),
14+
submit_form_func = require('../../lib/submit_form'),
15+
add_new_user_func = require('../../lib/add_new_user'),
16+
logout_user_func = require('../../lib/logout_user'),
17+
config = require('../../lib/config'),
1818
new_department_form_id = '#add_new_department_form',
1919
application_host = config.get_application_host(),
2020
company_edit_form_id ='#company_edit_form';
@@ -54,7 +54,7 @@ function check_teamview(data, emails){
5454
})
5555
.then(function(data){
5656
var promise_to_check = data.driver
57-
.findElements(By.css( 'tr.teamview-user-list-row > td' ))
57+
.findElements(By.css( 'tr.teamview-user-list-row > td.user-name-cell' ))
5858

5959
// Make sure that number of users is as expected
6060
.then(function(elements){

0 commit comments

Comments
 (0)