1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
odoo.define('hr_holidays.LeaveStatsWidget', function (require) {
"use strict";
var time = require('web.time');
var Widget = require('web.Widget');
var widget_registry = require('web.widget_registry');
var LeaveStatsWidget = Widget.extend({
template: 'hr_holidays.leave_stats',
/**
* @override
* @param {Widget|null} parent
* @param {Object} params
*/
init: function (parent, params) {
this._setState(params);
this._super(parent);
},
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @override to fetch data before rendering.
*/
willStart: function () {
return Promise.all([this._super(), this._fetchLeaveTypesData(), this._fetchDepartmentLeaves()]);
},
/**
* Fetch new data if needed (according to updated fields) and re-render the widget.
* Called by the basic renderer when the view changes.
* @param {Object} state
* @returns {Promise}
*/
updateState: function (state) {
var self = this;
var to_await = [];
var updatedFields = this._setState(state);
if (_.intersection(updatedFields, ['employee', 'date']).length) {
to_await.push(this._fetchLeaveTypesData());
}
if (_.intersection(updatedFields, ['department', 'date']).length) {
to_await.push(this._fetchDepartmentLeaves());
}
return Promise.all(to_await).then(function () {
self.renderElement();
});
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Update the state
* @param {Object} state
* @returns {String[]} list of updated fields
*/
_setState: function (state) {
var updatedFields = [];
if (state.data.employee_id.res_id !== (this.employee && this.employee.res_id)) {
updatedFields.push('employee');
this.employee = state.data.employee_id;
}
if (state.data.department_id.res_id !== (this.department && this.department.res_id)) {
updatedFields.push('department');
this.department = state.data.department_id;
}
if (state.data.date_from !== this.date) {
updatedFields.push('date');
this.date = state.data.date_from;
}
return updatedFields;
},
/**
* Fetch leaves taken by members of ``this.department`` in the
* month of ``this.date``.
* Three fields are fetched for each leave, namely: employee_id, date_from
* and date_to.
* The resulting data is assigned to ``this.departmentLeaves``
* @private
* @returns {Promise}
*/
_fetchDepartmentLeaves: function () {
if (!this.date || !this.department) {
this.departmentLeaves = null;
return Promise.resolve();
}
var self = this;
var month_date_from = this.date.clone().startOf('month');
var month_date_to = this.date.clone().endOf('month');
return this._rpc({
model: 'hr.leave',
method: 'search_read',
args: [
[['department_id', '=', this.department.res_id],
['state', '=', 'validate'],
['holiday_type', '=', 'employee'],
['date_from', '<=', month_date_to],
['date_to', '>=', month_date_from]],
['employee_id', 'date_from', 'date_to', 'number_of_days'],
],
}).then(function (data) {
var dateFormat = time.getLangDateFormat();
self.departmentLeaves = data.map(function (leave) {
// Format datetimes to date (in the user's format)
return _.extend(leave, {
date_from: moment(leave.date_from).format(dateFormat),
date_to: moment(leave.date_to).format(dateFormat),
number_of_days: leave.number_of_days,
});
});
});
},
/**
* Fetch the number of leaves, grouped by leave type, taken by ``this.employee``
* in the year of ``this.date``.
* The resulting data is assigned to ``this.leavesPerType``
* @private
* @returns {Promise}
*/
_fetchLeaveTypesData: function () {
if (!this.date || !this.employee) {
this.leavesPerType = null;
return Promise.resolve();
}
var self = this;
var year_date_from = this.date.clone().startOf('year');
var year_date_to = this.date.clone().endOf('year');
return this._rpc({
model: 'hr.leave',
method: 'read_group',
kwargs: {
domain: [['employee_id', '=', this.employee.res_id], ['state', '=', 'validate'], ['date_from', '<=', year_date_to], ['date_to', '>=', year_date_from]],
fields: ['holiday_status_id', 'number_of_days:sum'],
groupby: ['holiday_status_id'],
},
}).then(function (data) {
self.leavesPerType = data;
});
}
});
widget_registry.add('hr_leave_stats', LeaveStatsWidget);
return LeaveStatsWidget;
});
|