Merge lp:~laetitia-gangloff/acsone-addons/hr_utilization_group_by_report into lp:~acsone-openerp/acsone-addons/7.0
- hr_utilization_group_by_report
- Merge into 7.0
Proposed by
Laetitia Gangloff (Acsone)
Status: | Needs review |
---|---|
Proposed branch: | lp:~laetitia-gangloff/acsone-addons/hr_utilization_group_by_report |
Merge into: | lp:~acsone-openerp/acsone-addons/7.0 |
Diff against target: |
392 lines (+211/-56) 4 files modified
hr_utilization/report/hr_utilization_report.mako (+101/-15) hr_utilization/report/hr_utilization_report.py (+105/-40) hr_utilization/wizard/hr_utilization_print.py (+3/-1) hr_utilization/wizard/hr_utilization_print.xml (+2/-0) |
To merge this branch: | bzr merge lp:~laetitia-gangloff/acsone-addons/hr_utilization_group_by_report |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Acsone OpenErp Team | Pending | ||
Review via email: mp+168651@code.launchpad.net |
Commit message
Description of the change
This change add group by company/department function for the report generation.
To post a comment you must log in.
Unmerged revisions
- 36. By Laetitia Gangloff (Acsone)
-
hr_utilization: add group by department/company for the report
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'hr_utilization/images/screenshot2.png' | |||
2 | 0 | Binary files hr_utilization/images/screenshot2.png 2013-02-07 09:57:56 +0000 and hr_utilization/images/screenshot2.png 2013-06-11 12:25:39 +0000 differ | 0 | Binary files hr_utilization/images/screenshot2.png 2013-02-07 09:57:56 +0000 and hr_utilization/images/screenshot2.png 2013-06-11 12:25:39 +0000 differ |
3 | === modified file 'hr_utilization/report/hr_utilization_report.mako' | |||
4 | --- hr_utilization/report/hr_utilization_report.mako 2013-02-07 09:57:56 +0000 | |||
5 | +++ hr_utilization/report/hr_utilization_report.mako 2013-06-11 12:25:39 +0000 | |||
6 | @@ -61,10 +61,21 @@ | |||
7 | 61 | /* border-right: 1px solid lightGrey; uncomment to active column lines */ | 61 | /* border-right: 1px solid lightGrey; uncomment to active column lines */ |
8 | 62 | } | 62 | } |
9 | 63 | .list_table .act_as_cell.first_column { | 63 | .list_table .act_as_cell.first_column { |
10 | 64 | padding-left: 20px; | ||
11 | 65 | /* font-weight: bold; */ | ||
12 | 66 | /* border-left: 1px solid lightGrey; uncomment to active column lines */ | ||
13 | 67 | } | ||
14 | 68 | |||
15 | 69 | .list_table .act_as_cell.company_column { | ||
16 | 64 | padding-left: 0px; | 70 | padding-left: 0px; |
17 | 65 | font-weight: bold; | 71 | font-weight: bold; |
18 | 66 | /* border-left: 1px solid lightGrey; uncomment to active column lines */ | 72 | /* border-left: 1px solid lightGrey; uncomment to active column lines */ |
19 | 67 | } | 73 | } |
20 | 74 | .list_table .act_as_cell.department_column { | ||
21 | 75 | padding-left: 10px; | ||
22 | 76 | font-weight: bold;font-style:italic; | ||
23 | 77 | /* border-left: 1px solid lightGrey; uncomment to active column lines */ | ||
24 | 78 | } | ||
25 | 68 | 79 | ||
26 | 69 | .overflow_ellipsis { | 80 | .overflow_ellipsis { |
27 | 70 | text-overflow: ellipsis; | 81 | text-overflow: ellipsis; |
28 | @@ -76,8 +87,14 @@ | |||
29 | 76 | <body> | 87 | <body> |
30 | 77 | <% | 88 | <% |
31 | 78 | setLang(user.lang) | 89 | setLang(user.lang) |
34 | 79 | lines = [line for line in data['res'].values() if 'pct' in line] | 90 | |
35 | 80 | lines_nc = [line for line in data['res'].values() if 'pct' not in line] | 91 | lines = {id: line for (id, has_schedule), line in data['res'].items() if 'pct' in line} |
36 | 92 | departments = {id: line for (id, has_schedule), line in data['res_department'].items() if has_schedule} | ||
37 | 93 | companies = [line for (id, has_schedule), line in data['res_company'].items() if has_schedule] | ||
38 | 94 | lines_nc = {id: line for (id, has_schedule), line in data['res'].items() if 'pct' not in line} | ||
39 | 95 | departments_nc = {id: line for (id, has_schedule), line in data['res_department'].items() if not has_schedule} | ||
40 | 96 | companies_nc = [line for (id, has_schedule), line in data['res_company'].items() if not has_schedule] | ||
41 | 97 | |||
42 | 81 | column_names = data['column_names'] | 98 | column_names = data['column_names'] |
43 | 82 | nb_cols=len(column_names)+2 | 99 | nb_cols=len(column_names)+2 |
44 | 83 | w1=100.0/(nb_cols+int(data['with_fte'])) | 100 | w1=100.0/(nb_cols+int(data['with_fte'])) |
45 | @@ -106,17 +123,56 @@ | |||
46 | 106 | %endif | 123 | %endif |
47 | 107 | </div></div> | 124 | </div></div> |
48 | 108 | <div class="act_as_tbody"> | 125 | <div class="act_as_tbody"> |
60 | 109 | <!-- all lines sorted by sort criteria, then total line --> | 126 | <!-- total line, then all lines sorted by sort criteria and group by company and department --> |
61 | 110 | %for u in sorted(lines, key=lambda u: -u['pct'][sort]) + [data['res_total']]: | 127 | %for u in [data['res_total']]: |
62 | 111 | <div class="act_as_row lines"> | 128 | <div class="act_as_row lines"> |
63 | 112 | <div class="act_as_cell first_column overflow_ellipsis">${u['name']}</div> | 129 | <div class="act_as_cell first_column overflow_ellipsis">${u['name']}</div> |
64 | 113 | % for column_name in column_names: | 130 | % for column_name in column_names: |
65 | 114 | <div class="act_as_cell amount" style="width: ${w1}%">${hrs(u['hours'][column_name])}<br/>${pct(u['pct'][column_name])}</div> | 131 | <div class="act_as_cell amount" style="width: ${w1}%">${hrs(u['hours'][column_name])}<br/>${pct(u['pct'][column_name])}</div> |
66 | 115 | %endfor | 132 | %endfor |
67 | 116 | %if data['with_fte']: | 133 | %if data['with_fte']: |
68 | 117 | <div class="act_as_cell amount" style="width: ${w1}%">${u['fte']}</div> | 134 | <div class="act_as_cell amount" style="width: ${w1}%">${u['fte']}</div> |
69 | 118 | %endif | 135 | %endif |
70 | 119 | </div> | 136 | </div> |
71 | 137 | %endfor | ||
72 | 138 | %for company in companies: | ||
73 | 139 | %if company['name']: | ||
74 | 140 | <div class="act_as_row lines"> | ||
75 | 141 | <div class="act_as_cell company_column overflow_ellipsis">${company['name']}</div> | ||
76 | 142 | % for column_name in column_names: | ||
77 | 143 | <div class="act_as_cell amount" style="width: ${w1}%">${hrs(company['hours'][column_name])}<br/>${pct(company['pct'][column_name])}</div> | ||
78 | 144 | %endfor | ||
79 | 145 | %if data['with_fte']: | ||
80 | 146 | <div class="act_as_cell amount" style="width: ${w1}%">${company['fte']}</div> | ||
81 | 147 | %endif | ||
82 | 148 | </div> | ||
83 | 149 | %endif | ||
84 | 150 | %for department_id, department in departments.items(): | ||
85 | 151 | %if department['name'] and department_id in company['departments']: | ||
86 | 152 | <div class="act_as_row lines"> | ||
87 | 153 | <div class="act_as_cell department_column overflow_ellipsis">${department['name']}</div> | ||
88 | 154 | % for column_name in column_names: | ||
89 | 155 | <div class="act_as_cell amount" style="width: ${w1}%">${hrs(department['hours'][column_name])}<br/>${pct(department['pct'][column_name])}</div> | ||
90 | 156 | %endfor | ||
91 | 157 | %if data['with_fte']: | ||
92 | 158 | <div class="act_as_cell amount" style="width: ${w1}%">${company['fte']}</div> | ||
93 | 159 | %endif | ||
94 | 160 | </div> | ||
95 | 161 | %endif | ||
96 | 162 | %for user_id, u in sorted(lines.items(), key=lambda u: -u[1]['pct'][sort]): | ||
97 | 163 | %if user_id in department['users'] and user_id in company['users']: | ||
98 | 164 | <div class="act_as_row lines"> | ||
99 | 165 | <div class="act_as_cell first_column overflow_ellipsis">${u['name']}</div> | ||
100 | 166 | % for column_name in column_names: | ||
101 | 167 | <div class="act_as_cell amount" style="width: ${w1}%">${hrs(u['hours'][column_name])}<br/>${pct(u['pct'][column_name])}</div> | ||
102 | 168 | %endfor | ||
103 | 169 | %if data['with_fte']: | ||
104 | 170 | <div class="act_as_cell amount" style="width: ${w1}%">${u['fte']}</div> | ||
105 | 171 | %endif | ||
106 | 172 | </div> | ||
107 | 173 | %endif | ||
108 | 174 | %endfor | ||
109 | 175 | %endfor | ||
110 | 120 | %endfor | 176 | %endfor |
111 | 121 | </div> | 177 | </div> |
112 | 122 | </div> | 178 | </div> |
113 | @@ -132,15 +188,45 @@ | |||
114 | 132 | <div class="act_as_cell amount" style="width: ${w2}%">${column_name}</div> | 188 | <div class="act_as_cell amount" style="width: ${w2}%">${column_name}</div> |
115 | 133 | %endfor | 189 | %endfor |
116 | 134 | </div></div> | 190 | </div></div> |
119 | 135 | <div class="act_as_tbody"> | 191 | <div class="act_as_tbody"> |
120 | 136 | %for u in sorted(lines_nc, key=lambda u: -u['hours'][sort]) + [data['res_nc_total']]: | 192 | %for u in [data['res_nc_total']]: |
121 | 137 | <div class="act_as_row lines"> | 193 | <div class="act_as_row lines"> |
122 | 138 | <div class="act_as_cell first_column overflow_ellipsis">${u['name']}</div> | 194 | <div class="act_as_cell first_column overflow_ellipsis">${u['name']}</div> |
123 | 139 | % for column_name in column_names: | 195 | % for column_name in column_names: |
124 | 140 | <div class="act_as_cell amount" style="width: ${w2}%">${hrs(u['hours'][column_name])}</div> | 196 | <div class="act_as_cell amount" style="width: ${w2}%">${hrs(u['hours'][column_name])}</div> |
125 | 141 | %endfor | 197 | %endfor |
126 | 142 | </div> | 198 | </div> |
127 | 199 | %endfor | ||
128 | 200 | %for company in companies_nc: | ||
129 | 201 | %if company['name']: | ||
130 | 202 | <div class="act_as_row lines"> | ||
131 | 203 | <div class="act_as_cell company_column overflow_ellipsis">${company['name']}</div> | ||
132 | 204 | % for column_name in column_names: | ||
133 | 205 | <div class="act_as_cell amount" style="width: ${w2}%">${hrs(company['hours'][column_name])}</div> | ||
134 | 206 | %endfor | ||
135 | 207 | </div> | ||
136 | 208 | %endif | ||
137 | 209 | %for department_id, department in departments_nc.items(): | ||
138 | 210 | %if department['name'] and department_id in company['departments']: | ||
139 | 211 | <div class="act_as_row lines"> | ||
140 | 212 | <div class="act_as_cell department_column overflow_ellipsis">${department['name']}</div> | ||
141 | 213 | % for column_name in column_names: | ||
142 | 214 | <div class="act_as_cell amount" style="width: ${w2}%">${hrs(company['hours'][column_name])}</div> | ||
143 | 215 | %endfor | ||
144 | 216 | </div> | ||
145 | 217 | %endif | ||
146 | 218 | %for user_id, u in sorted(lines_nc.items(), key=lambda u: -u[1]['hours'][sort]): | ||
147 | 219 | %if user_id in department['users'] and user_id in company['users']: | ||
148 | 220 | <div class="act_as_row lines"> | ||
149 | 221 | <div class="act_as_cell first_column overflow_ellipsis">${u['name']}</div> | ||
150 | 222 | % for column_name in column_names: | ||
151 | 223 | <div class="act_as_cell amount" style="width: ${w2}%">${hrs(u['hours'][column_name])}</div> | ||
152 | 224 | %endfor | ||
153 | 225 | </div> | ||
154 | 226 | %endif | ||
155 | 227 | %endfor | ||
156 | 143 | %endfor | 228 | %endfor |
157 | 229 | %endfor | ||
158 | 144 | </div> | 230 | </div> |
159 | 145 | </div> | 231 | </div> |
160 | 146 | %endif | 232 | %endif |
161 | 147 | 233 | ||
162 | === modified file 'hr_utilization/report/hr_utilization_report.py' | |||
163 | --- hr_utilization/report/hr_utilization_report.py 2013-04-10 11:44:07 +0000 | |||
164 | +++ hr_utilization/report/hr_utilization_report.py 2013-06-11 12:25:39 +0000 | |||
165 | @@ -152,7 +152,7 @@ | |||
166 | 152 | # (which is the OpenErp default and the convention used in account_analytic_analysis) | 152 | # (which is the OpenErp default and the convention used in account_analytic_analysis) |
167 | 153 | # XXX: this query assumes all timesheets are entered in hours | 153 | # XXX: this query assumes all timesheets are entered in hours |
168 | 154 | self.cr.execute(""" | 154 | self.cr.execute(""" |
170 | 155 | select al.user_id, al.account_id, r.name, r.company_id, c.id, sum(al.unit_amount) | 155 | select e.department_id, al.user_id, al.account_id, r.name, r.company_id, c.id, sum(al.unit_amount) |
171 | 156 | from account_analytic_line al | 156 | from account_analytic_line al |
172 | 157 | left join res_users u on u.id = al.user_id | 157 | left join res_users u on u.id = al.user_id |
173 | 158 | left join resource_resource r on r.user_id = u.id | 158 | left join resource_resource r on r.user_id = u.id |
174 | @@ -163,15 +163,15 @@ | |||
175 | 163 | (c.date_end is null or al.date <= c.date_end) | 163 | (c.date_end is null or al.date <= c.date_end) |
176 | 164 | where al.journal_id = (select id from account_analytic_journal where type='general') | 164 | where al.journal_id = (select id from account_analytic_journal where type='general') |
177 | 165 | and al.date >= %s and al.date <= %s | 165 | and al.date >= %s and al.date <= %s |
179 | 166 | group by al.user_id, al.account_id, r.name, r.company_id, c.id | 166 | group by e.department_id, al.user_id, al.account_id, r.name, r.company_id, c.id |
180 | 167 | order by r.name""", (data['period_start'], data['period_end'])) | 167 | order by r.name""", (data['period_start'], data['period_end'])) |
181 | 168 | 168 | ||
188 | 169 | res = {} # user_id: {'name':name,'columns':{column_name:hours}} | 169 | res = {} # (user_id, has_schedule): {'name':name,'columns':{column_name:hours}} |
189 | 170 | for user_id, account_id, user_name, company_id, contract_id, hours in self.cr.fetchall(): | 170 | res_company = {} # (company_id, has_schedule): {'name':name, users:[user_ids], departments: [departmen_ids],} |
190 | 171 | if contract_id in contracts_with_schedule_by_id: | 171 | res_department = {} # (department_id, has_schedule): {'name':name, users:[user_ids]} |
191 | 172 | key = (user_id, True) | 172 | for department_id, user_id, account_id, user_name, company_id, contract_id, hours in self.cr.fetchall(): |
192 | 173 | else: | 173 | has_schedule = contract_id in contracts_with_schedule_by_id |
193 | 174 | key = (user_id, False) | 174 | key = (user_id, has_schedule) |
194 | 175 | if key not in res: | 175 | if key not in res: |
195 | 176 | res[key] = { | 176 | res[key] = { |
196 | 177 | 'name': user_name, | 177 | 'name': user_name, |
197 | @@ -179,14 +179,47 @@ | |||
198 | 179 | 'hours': {column_name:0.0 for column_name in column_names}, | 179 | 'hours': {column_name:0.0 for column_name in column_names}, |
199 | 180 | 'contracts': {}, # contract_id: contract | 180 | 'contracts': {}, # contract_id: contract |
200 | 181 | } | 181 | } |
202 | 182 | if only_total: | 182 | if only_total: |
203 | 183 | column_name = TOTAL | 183 | column_name = TOTAL |
204 | 184 | else: | 184 | else: |
205 | 185 | column_name = account_id_column_name_map.get(account_id, OTHER) | 185 | column_name = account_id_column_name_map.get(account_id, OTHER) |
206 | 186 | res[key]['hours'][column_name] += hours | 186 | res[key]['hours'][column_name] += hours |
208 | 187 | if contract_id in contracts_with_schedule_by_id: | 187 | if has_schedule: |
209 | 188 | res[key]['contracts'][contract_id] = contracts_with_schedule_by_id[contract_id] | 188 | res[key]['contracts'][contract_id] = contracts_with_schedule_by_id[contract_id] |
211 | 189 | 189 | ||
212 | 190 | if not data['group_by_company']: | ||
213 | 191 | company_id = (None, has_schedule) | ||
214 | 192 | if not data['group_by_department']: | ||
215 | 193 | department_id = (None, has_schedule) | ||
216 | 194 | if (company_id, has_schedule) not in res_company: | ||
217 | 195 | company_name = '' | ||
218 | 196 | if company_id: | ||
219 | 197 | company_name = self.pool.get("res.company").browse(self.cr, self.uid, company_id).name | ||
220 | 198 | res_company[(company_id, has_schedule)] = { | ||
221 | 199 | 'name': company_name, | ||
222 | 200 | 'users': [user_id], | ||
223 | 201 | 'departments': [department_id], | ||
224 | 202 | 'hours': {column_name:0.0 for column_name in column_names},} | ||
225 | 203 | else: | ||
226 | 204 | if user_id not in res_company[(company_id, has_schedule)]['users']: | ||
227 | 205 | res_company[(company_id, has_schedule)]['users'].append(user_id) | ||
228 | 206 | if department_id not in res_company[(company_id, has_schedule)]['departments']: | ||
229 | 207 | res_company[(company_id, has_schedule)]['departments'].append(department_id) | ||
230 | 208 | |||
231 | 209 | if (department_id, has_schedule) not in res_department: | ||
232 | 210 | department_name = '' | ||
233 | 211 | if department_id: | ||
234 | 212 | department_name = self.pool.get("hr.department").browse(self.cr, self.uid, department_id).name | ||
235 | 213 | res_department[(department_id, has_schedule)] = { | ||
236 | 214 | 'name': department_name, | ||
237 | 215 | 'users': [user_id], | ||
238 | 216 | 'hours': {column_name:0.0 for column_name in column_names},} | ||
239 | 217 | else: | ||
240 | 218 | if user_id not in res_department[(department_id, has_schedule)]['users']: | ||
241 | 219 | res_department[(department_id, has_schedule)]['users'].append(user_id) | ||
242 | 220 | res_department[(department_id, has_schedule)]['hours'][column_name] += hours | ||
243 | 221 | res_company[(company_id, has_schedule)]['hours'][column_name] += hours | ||
244 | 222 | |||
245 | 190 | # initialize totals | 223 | # initialize totals |
246 | 191 | users_without_contract = [] | 224 | users_without_contract = [] |
247 | 192 | with_fte = configuration.with_fte | 225 | with_fte = configuration.with_fte |
248 | @@ -205,35 +238,65 @@ | |||
249 | 205 | } | 238 | } |
250 | 206 | 239 | ||
251 | 207 | # row total, percentages and fte for each row | 240 | # row total, percentages and fte for each row |
254 | 208 | for (user_id, has_schedule), u in res.items(): | 241 | for (company_id, has_company_schedule), company in res_company.items(): |
255 | 209 | # row total | 242 | company_available_hours = 0.0 |
256 | 243 | if with_fte: | ||
257 | 244 | company['fte'] = 0.0 | ||
258 | 210 | if not only_total: | 245 | if not only_total: |
260 | 211 | u['hours'][TOTAL] = reduce(lambda x,y: x+y, u['hours'].values()) | 246 | company['hours'][TOTAL] = reduce(lambda x,y: x+y, company['hours'].values()) |
261 | 247 | for (department_id, has_department_schedule), department in res_department.items(): | ||
262 | 248 | if department_id in company['departments']: | ||
263 | 249 | department_available_hours = 0.0 | ||
264 | 250 | if with_fte: | ||
265 | 251 | department['fte'] = 0.0 | ||
266 | 252 | if not only_total: | ||
267 | 253 | department['hours'][TOTAL] = reduce(lambda x,y: x+y, department['hours'].values()) | ||
268 | 254 | for (user_id, has_schedule), u in res.items(): | ||
269 | 255 | if user_id in department['users'] and user_id in company['users']: | ||
270 | 256 | # row total | ||
271 | 257 | if not only_total: | ||
272 | 258 | u['hours'][TOTAL] = reduce(lambda x,y: x+y, u['hours'].values()) | ||
273 | 212 | 259 | ||
298 | 213 | if has_schedule: | 260 | if has_schedule: |
299 | 214 | # column totals | 261 | # column totals |
300 | 215 | for column_name in column_names: | 262 | for column_name in column_names: |
301 | 216 | res_total['hours'][column_name] += u['hours'][column_name] | 263 | res_total['hours'][column_name] += u['hours'][column_name] |
302 | 217 | # percentage | 264 | # percentage |
303 | 218 | available_hours = self.get_total_planned_working_hours(data['period_start'], data['period_end'], u['contracts'].values()) | 265 | available_hours = self.get_total_planned_working_hours(data['period_start'], data['period_end'], u['contracts'].values()) |
304 | 219 | total_available_hours += available_hours | 266 | total_available_hours += available_hours |
305 | 220 | u['pct'] = { column_name: hours/available_hours for column_name, hours in u['hours'].items() } | 267 | company_available_hours += available_hours |
306 | 221 | # fte | 268 | department_available_hours += available_hours |
307 | 222 | if with_fte: | 269 | u['pct'] = { column_name: hours/available_hours for column_name, hours in u['hours'].items() } |
308 | 223 | company = company_obj.browse(self.cr, self.uid, [u['company_id']])[0] | 270 | # fte |
309 | 224 | if company.fulltime_calendar_id: | 271 | if with_fte: |
310 | 225 | fte_available_hours = self.get_planned_working_hours(company.fulltime_calendar_id, data['period_start'], data['period_end']) | 272 | company_u = company_obj.browse(self.cr, self.uid, [u['company_id']])[0] |
311 | 226 | fte = available_hours / fte_available_hours | 273 | if company_u.fulltime_calendar_id: |
312 | 227 | res_total['fte'] += fte | 274 | fte_available_hours = self.get_planned_working_hours(company_u.fulltime_calendar_id, data['period_start'], data['period_end']) |
313 | 228 | u['fte'] = "%.1f" % fte | 275 | fte = available_hours / fte_available_hours |
314 | 229 | else: | 276 | res_total['fte'] += fte |
315 | 230 | u['fte'] = NA | 277 | company['fte'] += fte |
316 | 231 | fte_with_na = True | 278 | department['fte'] += fte |
317 | 232 | else: | 279 | u['fte'] = "%.1f" % fte |
318 | 233 | users_without_contract.append(u['name']) | 280 | else: |
319 | 234 | # column totals | 281 | u['fte'] = NA |
320 | 235 | for column_name in column_names: | 282 | fte_with_na = True |
321 | 236 | res_nc_total['hours'][column_name] += u['hours'][column_name] | 283 | else: |
322 | 284 | users_without_contract.append(u['name']) | ||
323 | 285 | # column totals | ||
324 | 286 | for column_name in column_names: | ||
325 | 287 | res_nc_total['hours'][column_name] += u['hours'][column_name] | ||
326 | 288 | if has_company_schedule and has_department_schedule: | ||
327 | 289 | department['pct'] = { column_name: hours/department_available_hours for column_name, hours in department['hours'].items() } | ||
328 | 290 | if with_fte and fte_with_na and not(department['fte']): | ||
329 | 291 | department['fte'] = NA | ||
330 | 292 | else: | ||
331 | 293 | department['fte'] = "%.1f" % department['fte'] | ||
332 | 294 | if has_company_schedule: | ||
333 | 295 | company['pct'] = { column_name: hours/company_available_hours for column_name, hours in company['hours'].items() } | ||
334 | 296 | if with_fte and fte_with_na and not(company['fte']): | ||
335 | 297 | company['fte'] = NA | ||
336 | 298 | else: | ||
337 | 299 | company['fte'] = "%.1f" % company['fte'] | ||
338 | 237 | 300 | ||
339 | 238 | # total average percentage | 301 | # total average percentage |
340 | 239 | if total_available_hours: | 302 | if total_available_hours: |
341 | @@ -249,6 +312,8 @@ | |||
342 | 249 | 312 | ||
343 | 250 | # set data in context for report | 313 | # set data in context for report |
344 | 251 | data['res'] = res | 314 | data['res'] = res |
345 | 315 | data['res_department'] = res_department | ||
346 | 316 | data['res_company'] = res_company | ||
347 | 252 | data['res_total'] = res_total | 317 | data['res_total'] = res_total |
348 | 253 | data['res_nc_total'] = res_nc_total | 318 | data['res_nc_total'] = res_nc_total |
349 | 254 | data['users_without_contract'] = users_without_contract | 319 | data['users_without_contract'] = users_without_contract |
350 | @@ -264,5 +329,5 @@ | |||
351 | 264 | 'hr.utilization.print', | 329 | 'hr.utilization.print', |
352 | 265 | rml='addons/hr_utilization/report/hr_utilization_report.mako', | 330 | rml='addons/hr_utilization/report/hr_utilization_report.mako', |
353 | 266 | parser=hr_utilization_report) | 331 | parser=hr_utilization_report) |
356 | 267 | 332 | ||
357 | 268 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | 333 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
358 | 269 | 334 | ||
359 | === modified file 'hr_utilization/wizard/hr_utilization_print.py' | |||
360 | --- hr_utilization/wizard/hr_utilization_print.py 2013-02-07 09:57:56 +0000 | |||
361 | +++ hr_utilization/wizard/hr_utilization_print.py 2013-06-11 12:25:39 +0000 | |||
362 | @@ -39,6 +39,8 @@ | |||
363 | 39 | 'configuration_id': fields.many2one('hr.utilization.configuration','Configuration', required=True), | 39 | 'configuration_id': fields.many2one('hr.utilization.configuration','Configuration', required=True), |
364 | 40 | 'period_start': fields.date("Period start", required=True), | 40 | 'period_start': fields.date("Period start", required=True), |
365 | 41 | 'period_end': fields.date("Period end", required=True), | 41 | 'period_end': fields.date("Period end", required=True), |
366 | 42 | 'group_by_company': fields.boolean('Group by company'), | ||
367 | 43 | 'group_by_department': fields.boolean('Group by department'), | ||
368 | 42 | } | 44 | } |
369 | 43 | 45 | ||
370 | 44 | def default_get(self, cr, uid, fields, context=None): | 46 | def default_get(self, cr, uid, fields, context=None): |
371 | @@ -60,7 +62,7 @@ | |||
372 | 60 | 62 | ||
373 | 61 | def print_report(self, cr, uid, ids, context=None): | 63 | def print_report(self, cr, uid, ids, context=None): |
374 | 62 | assert len(ids) == 1 | 64 | assert len(ids) == 1 |
376 | 63 | data = self.read(cr,uid,ids,["configuration_id","period_start","period_end"],context)[0] | 65 | data = self.read(cr,uid,ids,["configuration_id","period_start","period_end","group_by_department","group_by_company"],context)[0] |
377 | 64 | return {'type': 'ir.actions.report.xml', | 66 | return {'type': 'ir.actions.report.xml', |
378 | 65 | 'report_name': 'hr.utilization.report', | 67 | 'report_name': 'hr.utilization.report', |
379 | 66 | 'datas': data} | 68 | 'datas': data} |
380 | 67 | 69 | ||
381 | === modified file 'hr_utilization/wizard/hr_utilization_print.xml' | |||
382 | --- hr_utilization/wizard/hr_utilization_print.xml 2013-02-07 09:57:56 +0000 | |||
383 | +++ hr_utilization/wizard/hr_utilization_print.xml 2013-06-11 12:25:39 +0000 | |||
384 | @@ -11,6 +11,8 @@ | |||
385 | 11 | <field name="configuration_id" colspan="3"/> | 11 | <field name="configuration_id" colspan="3"/> |
386 | 12 | <field name="period_start"/> | 12 | <field name="period_start"/> |
387 | 13 | <field name="period_end"/> | 13 | <field name="period_end"/> |
388 | 14 | <field name="group_by_company"/> | ||
389 | 15 | <field name="group_by_department"/> | ||
390 | 14 | </group> | 16 | </group> |
391 | 15 | <footer> | 17 | <footer> |
392 | 16 | <button string="Print" name="print_report" type="object" class="oe_highlight"/> | 18 | <button string="Print" name="print_report" type="object" class="oe_highlight"/> |