Merge lp:~laetitia-gangloff/hr-timesheet/hr_attendance_analysis_externalise_contract_calendar into lp:~hr-core-editors/hr-timesheet/7.0
- hr_attendance_analysis_externalise_contract_calendar
- Merge into 7.0
Status: | Superseded |
---|---|
Proposed branch: | lp:~laetitia-gangloff/hr-timesheet/hr_attendance_analysis_externalise_contract_calendar |
Merge into: | lp:~hr-core-editors/hr-timesheet/7.0 |
Diff against target: |
458 lines (+140/-98) (has conflicts) 2 files modified
hr_attendance_analysis/hr_attendance.py (+69/-46) hr_attendance_analysis/wizard/print_calendar_report.py (+71/-52) Text conflict in hr_attendance_analysis/hr_attendance.py Text conflict in hr_attendance_analysis/wizard/print_calendar_report.py |
To merge this branch: | bzr merge lp:~laetitia-gangloff/hr-timesheet/hr_attendance_analysis_externalise_contract_calendar |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Pedro Manuel Baeza | Needs Resubmitting | ||
Guewen Baconnier @ Camptocamp | Needs Resubmitting | ||
Lorenzo Battistini (community) | Needs Fixing | ||
Review via email:
|
This proposal has been superseded by a proposal from 2013-11-19.
Commit message
Description of the change
In order to be able to use another calendar in some extension modules:
- rename get_active_
- update code to take account of this change (_get_attendanc
- externalise store part of column in _store_rules to easily extends it

Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |

Lorenzo Battistini (elbati) wrote : | # |
Looking at the whole code of
http://
line 235 is always False
- 54. By Laetitia Gangloff (Acsone)
-
hr_attendance_
analysis: externalise contract calendar

Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
Oh right !
and all following lines are shifted.
Thank you for your review. I corrected this mistake.

Lorenzo Battistini (elbati) wrote : | # |
There are conflicts.
Your last commit
http://
did a lot of changes
I suggest to revert to revision 53 and make the changes related to line 235 only.
Thanks
- 55. By Laetitia Gangloff (Acsone)
-
revert last commit

Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
There are still conflicts. Can you check ?

Pedro Manuel Baeza (pedro.baeza) wrote : | # |
This project is now hosted on https:/

Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
I think, the state of this mp/branch is not correct.
The purpose of this mp, is already in hr-timesheet project at revision 62.
What is the best pratice to remove the mp and the branch ?

Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
This one is set as Superseeded. Seems fine. No change needed.

Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
Super !
Thank you, I set the branch has abandonned.
Unmerged revisions
- 55. By Laetitia Gangloff (Acsone)
-
revert last commit
- 54. By Laetitia Gangloff (Acsone)
-
hr_attendance_
analysis: externalise contract calendar - 53. By Laetitia Gangloff (Acsone)
-
hr_attendance_
analysis: externalise contract calendar
Preview Diff
1 | === modified file 'hr_attendance_analysis/hr_attendance.py' | |||
2 | --- hr_attendance_analysis/hr_attendance.py 2013-08-30 10:27:51 +0000 | |||
3 | +++ hr_attendance_analysis/hr_attendance.py 2013-09-10 14:55:43 +0000 | |||
4 | @@ -127,7 +127,9 @@ | |||
5 | 127 | res.append((start_datetime, precision)) | 127 | res.append((start_datetime, precision)) |
6 | 128 | return res | 128 | return res |
7 | 129 | 129 | ||
9 | 130 | def get_active_contracts(self, cr, uid, employee_id, date=datetime.now().strftime('%Y-%m-%d')): | 130 | def get_reference_calendar(self, cr, uid, employee_id, date=None, context=None): |
10 | 131 | if date is None: | ||
11 | 132 | date = fields.date.context_today(self, cr, uid, context=context) | ||
12 | 131 | contract_pool = self.pool.get('hr.contract') | 133 | contract_pool = self.pool.get('hr.contract') |
13 | 132 | active_contract_ids= contract_pool.search(cr, uid, [ | 134 | active_contract_ids= contract_pool.search(cr, uid, [ |
14 | 133 | '&', | 135 | '&', |
15 | @@ -145,12 +147,24 @@ | |||
16 | 145 | '&', | 147 | '&', |
17 | 146 | ('trial_date_end', '!=', False), | 148 | ('trial_date_end', '!=', False), |
18 | 147 | ('trial_date_end', '>=', date), | 149 | ('trial_date_end', '>=', date), |
20 | 148 | ]) | 150 | ], context=context) |
21 | 149 | if len(active_contract_ids) > 1: | 151 | if len(active_contract_ids) > 1: |
22 | 152 | <<<<<<< TREE | ||
23 | 150 | employee = self.pool.get('hr.employee').browse(cr,uid,employee_id) | 153 | employee = self.pool.get('hr.employee').browse(cr,uid,employee_id) |
24 | 151 | raise orm.except_orm(_('Error'), _( | 154 | raise orm.except_orm(_('Error'), _( |
25 | 155 | ======= | ||
26 | 156 | employee = self.pool.get('hr.employee').browse(cr,uid,employee_id, context=context) | ||
27 | 157 | raise orm.except_orm(_('Error'), _( | ||
28 | 158 | >>>>>>> MERGE-SOURCE | ||
29 | 152 | 'Too many active contracts for employee %s' | 159 | 'Too many active contracts for employee %s' |
31 | 153 | ) % employee.name) | 160 | <<<<<<< TREE |
32 | 161 | ) % employee.name) | ||
33 | 162 | ======= | ||
34 | 163 | ) % employee.name) | ||
35 | 164 | if active_contract_ids: | ||
36 | 165 | contract = contract_pool.browse(cr, uid, active_contract_ids[0], context=context) | ||
37 | 166 | return contract.working_hours | ||
38 | 167 | >>>>>>> MERGE-SOURCE | ||
39 | 154 | return active_contract_ids | 168 | return active_contract_ids |
40 | 155 | 169 | ||
41 | 156 | def _ceil_rounding(self, rounding, datetime): | 170 | def _ceil_rounding(self, rounding, datetime): |
42 | @@ -165,10 +179,9 @@ | |||
43 | 165 | 179 | ||
44 | 166 | def _get_attendance_duration(self, cr, uid, ids, field_name, arg, context=None): | 180 | def _get_attendance_duration(self, cr, uid, ids, field_name, arg, context=None): |
45 | 167 | res = {} | 181 | res = {} |
46 | 168 | contract_pool = self.pool.get('hr.contract') | ||
47 | 169 | resource_pool = self.pool.get('resource.resource') | 182 | resource_pool = self.pool.get('resource.resource') |
48 | 170 | attendance_pool = self.pool.get('resource.calendar.attendance') | 183 | attendance_pool = self.pool.get('resource.calendar.attendance') |
50 | 171 | precision = self.pool.get('res.users').browse(cr, uid, uid).company_id.working_time_precision | 184 | precision = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.working_time_precision |
51 | 172 | # 2012.10.16 LF FIX : Get timezone from context | 185 | # 2012.10.16 LF FIX : Get timezone from context |
52 | 173 | active_tz = pytz.timezone(context.get("tz","UTC") if context else "UTC") | 186 | active_tz = pytz.timezone(context.get("tz","UTC") if context else "UTC") |
53 | 174 | str_now = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S') | 187 | str_now = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S') |
54 | @@ -176,7 +189,7 @@ | |||
55 | 176 | duration = 0.0 | 189 | duration = 0.0 |
56 | 177 | outside_calendar_duration = 0.0 | 190 | outside_calendar_duration = 0.0 |
57 | 178 | inside_calendar_duration = 0.0 | 191 | inside_calendar_duration = 0.0 |
59 | 179 | attendance = self.browse(cr, uid, attendance_id) | 192 | attendance = self.browse(cr, uid, attendance_id, context=context) |
60 | 180 | res[attendance.id] = {} | 193 | res[attendance.id] = {} |
61 | 181 | # 2012.10.16 LF FIX : Attendance in context timezone | 194 | # 2012.10.16 LF FIX : Attendance in context timezone |
62 | 182 | attendance_start = datetime.strptime( | 195 | attendance_start = datetime.strptime( |
63 | @@ -188,9 +201,9 @@ | |||
64 | 188 | if attendance.action == 'sign_in': | 201 | if attendance.action == 'sign_in': |
65 | 189 | next_attendance_ids = self.search(cr, uid, [ | 202 | next_attendance_ids = self.search(cr, uid, [ |
66 | 190 | ('employee_id', '=', attendance.employee_id.id), | 203 | ('employee_id', '=', attendance.employee_id.id), |
68 | 191 | ('name', '>', attendance.name)], order='name') | 204 | ('name', '>', attendance.name)], order='name', context=context) |
69 | 192 | if next_attendance_ids: | 205 | if next_attendance_ids: |
71 | 193 | next_attendance = self.browse(cr, uid, next_attendance_ids[0]) | 206 | next_attendance = self.browse(cr, uid, next_attendance_ids[0], context=context) |
72 | 194 | if next_attendance.action == 'sign_in': | 207 | if next_attendance.action == 'sign_in': |
73 | 195 | # 2012.10.16 LF FIX : Attendance in context timezone | 208 | # 2012.10.16 LF FIX : Attendance in context timezone |
74 | 196 | raise orm.except_orm(_('Error'), _( | 209 | raise orm.except_orm(_('Error'), _( |
75 | @@ -206,13 +219,14 @@ | |||
76 | 206 | duration = round(duration / precision) * precision | 219 | duration = round(duration / precision) * precision |
77 | 207 | res[attendance.id]['duration'] = duration | 220 | res[attendance.id]['duration'] = duration |
78 | 208 | res[attendance.id]['end_datetime'] = next_attendance_date | 221 | res[attendance.id]['end_datetime'] = next_attendance_date |
80 | 209 | # If contract is not specified: working days = 24/7 | 222 | # If calendar is not specified: working days = 24/7 |
81 | 210 | res[attendance.id]['inside_calendar_duration'] = duration | 223 | res[attendance.id]['inside_calendar_duration'] = duration |
82 | 211 | res[attendance.id]['outside_calendar_duration'] = 0.0 | 224 | res[attendance.id]['outside_calendar_duration'] = 0.0 |
83 | 212 | 225 | ||
86 | 213 | active_contract_ids = self.get_active_contracts( | 226 | reference_calendar = self.get_reference_calendar( |
87 | 214 | cr, uid, attendance.employee_id.id, date=str_now[:10]) | 227 | cr, uid, attendance.employee_id.id, date=str_now[:10], context=context) |
88 | 215 | 228 | ||
89 | 229 | <<<<<<< TREE | ||
90 | 216 | if active_contract_ids and next_attendance_ids: | 230 | if active_contract_ids and next_attendance_ids: |
91 | 217 | contract = contract_pool.browse(cr, uid, active_contract_ids[0]) | 231 | contract = contract_pool.browse(cr, uid, active_contract_ids[0]) |
92 | 218 | if contract.working_hours: | 232 | if contract.working_hours: |
93 | @@ -224,6 +238,23 @@ | |||
94 | 224 | rounded_stop_hour = self._floor_rounding( | 238 | rounded_stop_hour = self._floor_rounding( |
95 | 225 | float_attendance_rounding, attendance_stop) | 239 | float_attendance_rounding, attendance_stop) |
96 | 226 | 240 | ||
97 | 241 | ======= | ||
98 | 242 | if reference_calendar and next_attendance_ids: | ||
99 | 243 | # TODO applicare prima arrotondamento o tolleranza? | ||
100 | 244 | if reference_calendar.attendance_rounding: | ||
101 | 245 | float_attendance_rounding = float(reference_calendar.attendance_rounding) | ||
102 | 246 | rounded_start_hour = self._ceil_rounding( | ||
103 | 247 | float_attendance_rounding, attendance_start) | ||
104 | 248 | rounded_stop_hour = self._floor_rounding( | ||
105 | 249 | float_attendance_rounding, attendance_stop) | ||
106 | 250 | |||
107 | 251 | if abs(1- rounded_start_hour) < 0.01: # if shift == 1 hour | ||
108 | 252 | attendance_start = datetime(attendance_start.year, attendance_start.month, | ||
109 | 253 | attendance_start.day, attendance_start.hour + 1) | ||
110 | 254 | else: | ||
111 | 255 | attendance_start = datetime(attendance_start.year, attendance_start.month, | ||
112 | 256 | attendance_start.day, attendance_start.hour, int(round(rounded_start_hour * 60.0))) | ||
113 | 257 | >>>>>>> MERGE-SOURCE | ||
114 | 227 | if abs(1- rounded_start_hour) < 0.01: # if shift == 1 hour | 258 | if abs(1- rounded_start_hour) < 0.01: # if shift == 1 hour |
115 | 228 | attendance_start = datetime(attendance_start.year, attendance_start.month, | 259 | attendance_start = datetime(attendance_start.year, attendance_start.month, |
116 | 229 | attendance_start.day, attendance_start.hour + 1) | 260 | attendance_start.day, attendance_start.hour + 1) |
117 | @@ -243,7 +274,7 @@ | |||
118 | 243 | 274 | ||
119 | 244 | res[attendance.id]['inside_calendar_duration'] = 0.0 | 275 | res[attendance.id]['inside_calendar_duration'] = 0.0 |
120 | 245 | res[attendance.id]['outside_calendar_duration'] = 0.0 | 276 | res[attendance.id]['outside_calendar_duration'] = 0.0 |
122 | 246 | calendar_id = contract.working_hours.id | 277 | calendar_id = reference_calendar.id |
123 | 247 | intervals_within = 0 | 278 | intervals_within = 0 |
124 | 248 | 279 | ||
125 | 249 | # split attendance in intervals = precision | 280 | # split attendance in intervals = precision |
126 | @@ -273,7 +304,7 @@ | |||
127 | 273 | ('calendar_id','=',calendar_id), | 304 | ('calendar_id','=',calendar_id), |
128 | 274 | ('hour_to','>=',centered_attendance_hour), | 305 | ('hour_to','>=',centered_attendance_hour), |
129 | 275 | ('hour_from','<=',centered_attendance_hour), | 306 | ('hour_from','<=',centered_attendance_hour), |
131 | 276 | ]) | 307 | ], context=context) |
132 | 277 | if len(matched_schedule_ids) > 1: | 308 | if len(matched_schedule_ids) > 1: |
133 | 278 | raise orm.except_orm(_('Error'), | 309 | raise orm.except_orm(_('Error'), |
134 | 279 | _('Wrongly configured working schedule with id %s') % str(calendar_id)) | 310 | _('Wrongly configured working schedule with id %s') % str(calendar_id)) |
135 | @@ -281,7 +312,7 @@ | |||
136 | 281 | intervals_within += 1 | 312 | intervals_within += 1 |
137 | 282 | # sign in tolerance | 313 | # sign in tolerance |
138 | 283 | if intervals_within == 1: | 314 | if intervals_within == 1: |
140 | 284 | calendar_attendance = attendance_pool.browse(cr, uid, matched_schedule_ids[0]) | 315 | calendar_attendance = attendance_pool.browse(cr, uid, matched_schedule_ids[0], context=context) |
141 | 285 | attendance_start_hour = ( | 316 | attendance_start_hour = ( |
142 | 286 | attendance_start.hour + attendance_start.minute / 60.0 | 317 | attendance_start.hour + attendance_start.minute / 60.0 |
143 | 287 | + attendance_start.second / 60.0 / 60.0 | 318 | + attendance_start.second / 60.0 / 60.0 |
144 | @@ -302,7 +333,7 @@ | |||
145 | 302 | attendance_stop.hour + attendance_stop.minute / 60.0 | 333 | attendance_stop.hour + attendance_stop.minute / 60.0 |
146 | 303 | + attendance_stop.second / 60.0 / 60.0 | 334 | + attendance_stop.second / 60.0 / 60.0 |
147 | 304 | ) | 335 | ) |
149 | 305 | calendar_attendance = attendance_pool.browse(cr, uid, matched_schedule_ids[0]) | 336 | calendar_attendance = attendance_pool.browse(cr, uid, matched_schedule_ids[0], context=context) |
150 | 306 | if attendance_stop_hour <= ( | 337 | if attendance_stop_hour <= ( |
151 | 307 | calendar_attendance.hour_to and | 338 | calendar_attendance.hour_to and |
152 | 308 | (attendance_stop_hour - (calendar_attendance.hour_to - | 339 | (attendance_stop_hour - (calendar_attendance.hour_to - |
153 | @@ -321,13 +352,13 @@ | |||
154 | 321 | res[attendance.id]['inside_calendar_duration'], | 352 | res[attendance.id]['inside_calendar_duration'], |
155 | 322 | res[attendance.id]['duration']) | 353 | res[attendance.id]['duration']) |
156 | 323 | 354 | ||
158 | 324 | if contract.working_hours.overtime_rounding: | 355 | if reference_calendar.overtime_rounding: |
159 | 325 | if res[attendance.id]['outside_calendar_duration']: | 356 | if res[attendance.id]['outside_calendar_duration']: |
160 | 326 | overtime = res[attendance.id]['outside_calendar_duration'] | 357 | overtime = res[attendance.id]['outside_calendar_duration'] |
162 | 327 | if contract.working_hours.overtime_rounding_tolerance: | 358 | if reference_calendar.overtime_rounding_tolerance: |
163 | 328 | overtime = self.time_sum(overtime, | 359 | overtime = self.time_sum(overtime, |
166 | 329 | contract.working_hours.overtime_rounding_tolerance) | 360 | reference_calendar.overtime_rounding_tolerance) |
167 | 330 | float_overtime_rounding = float(contract.working_hours.overtime_rounding) | 361 | float_overtime_rounding = float(reference_calendar.overtime_rounding) |
168 | 331 | res[attendance.id]['outside_calendar_duration'] = math.floor( | 362 | res[attendance.id]['outside_calendar_duration'] = math.floor( |
169 | 332 | overtime * float_overtime_rounding) / float_overtime_rounding | 363 | overtime * float_overtime_rounding) / float_overtime_rounding |
170 | 333 | 364 | ||
171 | @@ -337,7 +368,7 @@ | |||
172 | 337 | attendance_ids = [] | 368 | attendance_ids = [] |
173 | 338 | attendance_pool = self.pool.get('hr.attendance') | 369 | attendance_pool = self.pool.get('hr.attendance') |
174 | 339 | for contract in self.pool.get('hr.contract').browse(cr, uid, ids, context=context): | 370 | for contract in self.pool.get('hr.contract').browse(cr, uid, ids, context=context): |
176 | 340 | att_ids = attendance_pool.search(cr, uid, [('employee_id', '=', contract.employee_id.id)]) | 371 | att_ids = attendance_pool.search(cr, uid, [('employee_id', '=', contract.employee_id.id)], context=context) |
177 | 341 | for att_id in att_ids: | 372 | for att_id in att_ids: |
178 | 342 | if att_id not in attendance_ids: | 373 | if att_id not in attendance_ids: |
179 | 343 | attendance_ids.append(att_id) | 374 | attendance_ids.append(att_id) |
180 | @@ -348,7 +379,7 @@ | |||
181 | 348 | attendance_pool = self.pool.get('hr.attendance') | 379 | attendance_pool = self.pool.get('hr.attendance') |
182 | 349 | contract_pool = self.pool.get('hr.contract') | 380 | contract_pool = self.pool.get('hr.contract') |
183 | 350 | for calendar in self.pool.get('resource.calendar').browse(cr, uid, ids, context=context): | 381 | for calendar in self.pool.get('resource.calendar').browse(cr, uid, ids, context=context): |
185 | 351 | contract_ids = contract_pool.search(cr, uid, [('working_hours', '=', calendar.id)]) | 382 | contract_ids = contract_pool.search(cr, uid, [('working_hours', '=', calendar.id)], context=context) |
186 | 352 | att_ids = attendance_pool._get_by_contracts(cr, uid, contract_ids, context=None) | 383 | att_ids = attendance_pool._get_by_contracts(cr, uid, contract_ids, context=None) |
187 | 353 | for att_id in att_ids: | 384 | for att_id in att_ids: |
188 | 354 | if att_id not in attendance_ids: | 385 | if att_id not in attendance_ids: |
189 | @@ -373,47 +404,39 @@ | |||
190 | 373 | elif attendance.action == 'sign_out': | 404 | elif attendance.action == 'sign_out': |
191 | 374 | previous_attendance_ids = self.search(cr, uid, [ | 405 | previous_attendance_ids = self.search(cr, uid, [ |
192 | 375 | ('employee_id', '=', attendance.employee_id.id), | 406 | ('employee_id', '=', attendance.employee_id.id), |
193 | 407 | <<<<<<< TREE | ||
194 | 376 | ('name', '<', attendance.name), | 408 | ('name', '<', attendance.name), |
195 | 377 | ('action', '=', 'sign_in'), | 409 | ('action', '=', 'sign_in'), |
196 | 378 | ], order='name') | 410 | ], order='name') |
197 | 411 | ======= | ||
198 | 412 | ('name', '<', attendance.name), | ||
199 | 413 | ('action', '=', 'sign_in'), | ||
200 | 414 | ], order='name', context=context) | ||
201 | 415 | >>>>>>> MERGE-SOURCE | ||
202 | 379 | if previous_attendance_ids and previous_attendance_ids[len(previous_attendance_ids) - 1] not in attendance_ids: | 416 | if previous_attendance_ids and previous_attendance_ids[len(previous_attendance_ids) - 1] not in attendance_ids: |
203 | 380 | attendance_ids.append(previous_attendance_ids[len(previous_attendance_ids) - 1]) | 417 | attendance_ids.append(previous_attendance_ids[len(previous_attendance_ids) - 1]) |
204 | 381 | return attendance_ids | 418 | return attendance_ids |
205 | 382 | 419 | ||
206 | 383 | _inherit = "hr.attendance" | 420 | _inherit = "hr.attendance" |
207 | 384 | 421 | ||
208 | 422 | _store_rules = { | ||
209 | 423 | 'hr.attendance': (_get_attendances, ['name', 'action', 'employee_id'], 20), | ||
210 | 424 | 'hr.contract': (_get_by_contracts, ['employee_id', 'date_start', 'date_end', 'trial_date_start', 'trial_date_end', 'working_hours'], 20), | ||
211 | 425 | 'resource.calendar': (_get_by_calendars, ['attendance_ids'], 20), | ||
212 | 426 | 'resource.calendar.attendance': (_get_by_calendar_attendances, ['dayofweek', 'date_from', 'hour_from', 'hour_to', 'calendar_id'], 20), | ||
213 | 427 | } | ||
214 | 428 | |||
215 | 385 | _columns = { | 429 | _columns = { |
216 | 386 | 'duration': fields.function(_get_attendance_duration, method=True, multi='duration', string="Attendance duration", | 430 | 'duration': fields.function(_get_attendance_duration, method=True, multi='duration', string="Attendance duration", |
224 | 387 | store={ | 431 | store=_store_rules), |
218 | 388 | 'hr.attendance': (_get_attendances, ['name', 'action', 'employee_id'], 20), | ||
219 | 389 | 'hr.contract': (_get_by_contracts, ['employee_id', 'date_start', 'date_end', 'trial_date_start', 'trial_date_end', 'working_hours'], 20), | ||
220 | 390 | 'resource.calendar': (_get_by_calendars, ['attendance_ids'], 20), | ||
221 | 391 | 'resource.calendar.attendance': (_get_by_calendar_attendances, ['dayofweek', 'date_from', 'hour_from', 'hour_to', 'calendar_id'], 20), | ||
222 | 392 | } | ||
223 | 393 | ), | ||
225 | 394 | 'end_datetime': fields.function(_get_attendance_duration, method=True, multi='duration', type="datetime", string="End date time", | 432 | 'end_datetime': fields.function(_get_attendance_duration, method=True, multi='duration', type="datetime", string="End date time", |
232 | 395 | store={ | 433 | store=_store_rules), |
227 | 396 | 'hr.attendance': (_get_attendances, ['name', 'action', 'employee_id'], 20), | ||
228 | 397 | 'hr.contract': (_get_by_contracts, ['employee_id', 'date_start', 'date_end', 'trial_date_start', 'trial_date_end', 'working_hours'], 20), | ||
229 | 398 | 'resource.calendar': (_get_by_calendars, ['attendance_ids'], 20), | ||
230 | 399 | 'resource.calendar.attendance': (_get_by_calendar_attendances, ['dayofweek', 'date_from', 'hour_from', 'hour_to', 'calendar_id'], 20), | ||
231 | 400 | }), | ||
233 | 401 | 'outside_calendar_duration': fields.function(_get_attendance_duration, method=True, multi='duration', | 434 | 'outside_calendar_duration': fields.function(_get_attendance_duration, method=True, multi='duration', |
234 | 402 | string="Overtime", | 435 | string="Overtime", |
241 | 403 | store={ | 436 | store=_store_rules), |
236 | 404 | 'hr.attendance': (_get_attendances, ['name', 'action', 'employee_id'], 20), | ||
237 | 405 | 'hr.contract': (_get_by_contracts, ['employee_id', 'date_start', 'date_end', 'trial_date_start', 'trial_date_end', 'working_hours'], 20), | ||
238 | 406 | 'resource.calendar': (_get_by_calendars, ['attendance_ids'], 20), | ||
239 | 407 | 'resource.calendar.attendance': (_get_by_calendar_attendances, ['dayofweek', 'date_from', 'hour_from', 'hour_to', 'calendar_id'], 20), | ||
240 | 408 | }), | ||
242 | 409 | 'inside_calendar_duration': fields.function(_get_attendance_duration, method=True, multi='duration', | 437 | 'inside_calendar_duration': fields.function(_get_attendance_duration, method=True, multi='duration', |
243 | 410 | string="Duration within working schedule", | 438 | string="Duration within working schedule", |
250 | 411 | store={ | 439 | store=_store_rules), |
245 | 412 | 'hr.attendance': (_get_attendances, ['name', 'action', 'employee_id'], 20), | ||
246 | 413 | 'hr.contract': (_get_by_contracts, ['employee_id', 'date_start', 'date_end', 'trial_date_start', 'trial_date_end', 'working_hours'], 20), | ||
247 | 414 | 'resource.calendar': (_get_by_calendars, ['attendance_ids'], 20), | ||
248 | 415 | 'resource.calendar.attendance': (_get_by_calendar_attendances, ['dayofweek', 'date_from', 'hour_from', 'hour_to', 'calendar_id'], 20), | ||
249 | 416 | }), | ||
251 | 417 | } | 440 | } |
252 | 418 | 441 | ||
253 | 419 | 442 | ||
254 | 420 | 443 | ||
255 | === modified file 'hr_attendance_analysis/wizard/print_calendar_report.py' | |||
256 | --- hr_attendance_analysis/wizard/print_calendar_report.py 2013-07-16 07:39:48 +0000 | |||
257 | +++ hr_attendance_analysis/wizard/print_calendar_report.py 2013-09-10 14:55:43 +0000 | |||
258 | @@ -55,7 +55,7 @@ | |||
259 | 55 | 'year': lambda * a: datetime.now().year, | 55 | 'year': lambda * a: datetime.now().year, |
260 | 56 | 'from_date': lambda * a: (datetime.now()-timedelta(30)).strftime('%Y-%m-%d'), | 56 | 'from_date': lambda * a: (datetime.now()-timedelta(30)).strftime('%Y-%m-%d'), |
261 | 57 | 'to_date': lambda * a: datetime.now().strftime('%Y-%m-%d'), | 57 | 'to_date': lambda * a: datetime.now().strftime('%Y-%m-%d'), |
263 | 58 | 'employee_ids': lambda s, cr, uid, c: s.pool.get('hr.employee').search(cr, uid, []), | 58 | 'employee_ids': lambda s, cr, uid, c: s.pool.get('hr.employee').search(cr, uid, [], context=None), |
264 | 59 | } | 59 | } |
265 | 60 | 60 | ||
266 | 61 | _name = "attendance_analysis.wizard.calendar_report" | 61 | _name = "attendance_analysis.wizard.calendar_report" |
267 | @@ -74,12 +74,11 @@ | |||
268 | 74 | if context is None: | 74 | if context is None: |
269 | 75 | context = {} | 75 | context = {} |
270 | 76 | attendance_pool = self.pool.get('hr.attendance') | 76 | attendance_pool = self.pool.get('hr.attendance') |
271 | 77 | contract_pool = self.pool.get('hr.contract') | ||
272 | 78 | holidays_pool = self.pool.get('hr.holidays') | 77 | holidays_pool = self.pool.get('hr.holidays') |
273 | 79 | 78 | ||
274 | 80 | days_by_employee = {} | 79 | days_by_employee = {} |
275 | 81 | 80 | ||
277 | 82 | form = self.read(cr, uid, ids)[0] | 81 | form = self.read(cr, uid, ids, context=context)[0] |
278 | 83 | from_date = datetime.strptime(form['from_date'], '%Y-%m-%d') | 82 | from_date = datetime.strptime(form['from_date'], '%Y-%m-%d') |
279 | 84 | to_date = datetime.strptime(form['to_date'], '%Y-%m-%d') | 83 | to_date = datetime.strptime(form['to_date'], '%Y-%m-%d') |
280 | 85 | if from_date > to_date: | 84 | if from_date > to_date: |
281 | @@ -97,7 +96,7 @@ | |||
282 | 97 | current_total_attendances = 0.0 | 96 | current_total_attendances = 0.0 |
283 | 98 | current_total_overtime = 0.0 | 97 | current_total_overtime = 0.0 |
284 | 99 | current_total_leaves = 0.0 | 98 | current_total_leaves = 0.0 |
286 | 100 | current_total_due = 24.0 # If contract is not specified: working days = 24/7 | 99 | current_total_due = 24.0 # If calendar is not specified: working days = 24/7 |
287 | 101 | current_total_inside_calendar = 0.0 | 100 | current_total_inside_calendar = 0.0 |
288 | 102 | str_current_date = current_date.strftime('%Y-%m-%d') | 101 | str_current_date = current_date.strftime('%Y-%m-%d') |
289 | 103 | days_by_employee[employee_id][str_current_date] = { | 102 | days_by_employee[employee_id][str_current_date] = { |
290 | @@ -121,9 +120,9 @@ | |||
291 | 121 | ('name','>=',str_current_date_beginning), | 120 | ('name','>=',str_current_date_beginning), |
292 | 122 | ('name','<=',str_current_date_end), | 121 | ('name','<=',str_current_date_end), |
293 | 123 | ('action','=','sign_in'), | 122 | ('action','=','sign_in'), |
295 | 124 | ]) | 123 | ], context=context) |
296 | 125 | # computing attendance totals | 124 | # computing attendance totals |
298 | 126 | for attendance in attendance_pool.browse(cr, uid, attendance_ids): | 125 | for attendance in attendance_pool.browse(cr, uid, attendance_ids, context=context): |
299 | 127 | current_total_attendances = attendance_pool.time_sum( | 126 | current_total_attendances = attendance_pool.time_sum( |
300 | 128 | current_total_attendances,attendance.duration) | 127 | current_total_attendances,attendance.duration) |
301 | 129 | current_total_overtime = attendance_pool.time_sum(current_total_overtime, | 128 | current_total_overtime = attendance_pool.time_sum(current_total_overtime, |
302 | @@ -135,7 +134,7 @@ | |||
303 | 135 | #printing up to 4 attendances | 134 | #printing up to 4 attendances |
304 | 136 | if len(attendance_ids) < 5: | 135 | if len(attendance_ids) < 5: |
305 | 137 | count = 1 | 136 | count = 1 |
307 | 138 | for attendance in sorted(attendance_pool.browse(cr, uid, attendance_ids), | 137 | for attendance in sorted(attendance_pool.browse(cr, uid, attendance_ids, context=context), |
308 | 139 | key=lambda x: x['name']): | 138 | key=lambda x: x['name']): |
309 | 140 | days_by_employee[employee_id][str_current_date][ | 139 | days_by_employee[employee_id][str_current_date][ |
310 | 141 | 'signin_'+str(count)] = attendance.name[11:16] | 140 | 'signin_'+str(count)] = attendance.name[11:16] |
311 | @@ -152,9 +151,10 @@ | |||
312 | 152 | 'overtime' | 151 | 'overtime' |
313 | 153 | ] = current_total_overtime | 152 | ] = current_total_overtime |
314 | 154 | 153 | ||
317 | 155 | active_contract_ids = attendance_pool.get_active_contracts( | 154 | reference_calendar = attendance_pool.get_reference_calendar( |
318 | 156 | cr, uid, int(employee_id), date=str_current_date) | 155 | cr, uid, int(employee_id), date=str_current_date, context=context) |
319 | 157 | # computing due total | 156 | # computing due total |
320 | 157 | <<<<<<< TREE | ||
321 | 158 | if active_contract_ids: | 158 | if active_contract_ids: |
322 | 159 | contract = contract_pool.browse(cr, uid, active_contract_ids[0]) | 159 | contract = contract_pool.browse(cr, uid, active_contract_ids[0]) |
323 | 160 | if contract.working_hours and contract.working_hours.attendance_ids: | 160 | if contract.working_hours and contract.working_hours.attendance_ids: |
324 | @@ -178,6 +178,29 @@ | |||
325 | 178 | current_total_due = attendance_pool.time_sum(current_total_due, | 178 | current_total_due = attendance_pool.time_sum(current_total_due, |
326 | 179 | calendar_attendance_duration) | 179 | calendar_attendance_duration) |
327 | 180 | 180 | ||
328 | 181 | ======= | ||
329 | 182 | if reference_calendar and reference_calendar.attendance_ids: | ||
330 | 183 | current_total_due = 0.0 | ||
331 | 184 | for calendar_attendance in reference_calendar.attendance_ids: | ||
332 | 185 | if (( | ||
333 | 186 | not calendar_attendance.dayofweek | ||
334 | 187 | or int(calendar_attendance.dayofweek) == current_date.weekday() | ||
335 | 188 | ) | ||
336 | 189 | and ( | ||
337 | 190 | not calendar_attendance.date_from or | ||
338 | 191 | datetime.strptime(calendar_attendance.date_from,'%Y-%m-%d') | ||
339 | 192 | <= current_date | ||
340 | 193 | )): | ||
341 | 194 | calendar_attendance_duration = attendance_pool.time_difference( | ||
342 | 195 | calendar_attendance.hour_from, calendar_attendance.hour_to) | ||
343 | 196 | if calendar_attendance_duration < 0: | ||
344 | 197 | raise orm.except_orm(_('Error'), | ||
345 | 198 | _("%s: 'Work to' is < 'Work from'") | ||
346 | 199 | % calendar_attendance.name) | ||
347 | 200 | current_total_due = attendance_pool.time_sum(current_total_due, | ||
348 | 201 | calendar_attendance_duration) | ||
349 | 202 | |||
350 | 203 | >>>>>>> MERGE-SOURCE | ||
351 | 181 | days_by_employee[employee_id][str_current_date]['due'] = current_total_due | 204 | days_by_employee[employee_id][str_current_date]['due'] = current_total_due |
352 | 182 | 205 | ||
353 | 183 | # computing leaves | 206 | # computing leaves |
354 | @@ -200,8 +223,8 @@ | |||
355 | 200 | ('date_to', '>', str_current_date_end), | 223 | ('date_to', '>', str_current_date_end), |
356 | 201 | ('state', '=', 'validate'), | 224 | ('state', '=', 'validate'), |
357 | 202 | ('employee_id', '=', int(employee_id)), | 225 | ('employee_id', '=', int(employee_id)), |
360 | 203 | ]) | 226 | ], context=context) |
361 | 204 | for holiday in holidays_pool.browse(cr, uid, holidays_ids): | 227 | for holiday in holidays_pool.browse(cr, uid, holidays_ids, context=context): |
362 | 205 | date_from = datetime.strptime(holiday.date_from, '%Y-%m-%d %H:%M:%S') | 228 | date_from = datetime.strptime(holiday.date_from, '%Y-%m-%d %H:%M:%S') |
363 | 206 | date_to = datetime.strptime(holiday.date_to, '%Y-%m-%d %H:%M:%S') | 229 | date_to = datetime.strptime(holiday.date_to, '%Y-%m-%d %H:%M:%S') |
364 | 207 | # if beginned before today | 230 | # if beginned before today |
365 | @@ -230,17 +253,15 @@ | |||
366 | 230 | ] = attendance_pool.time_difference( | 253 | ] = attendance_pool.time_difference( |
367 | 231 | current_total_inside_calendar, due_minus_leaves) | 254 | current_total_inside_calendar, due_minus_leaves) |
368 | 232 | 255 | ||
380 | 233 | if active_contract_ids: | 256 | if reference_calendar and reference_calendar.leave_rounding: |
381 | 234 | contract = contract_pool.browse(cr, uid, active_contract_ids[0]) | 257 | float_rounding = float(reference_calendar.leave_rounding) |
382 | 235 | if contract.working_hours and contract.working_hours.leave_rounding: | 258 | days_by_employee[employee_id][str_current_date][ |
383 | 236 | float_rounding = float(contract.working_hours.leave_rounding) | 259 | 'negative' |
384 | 237 | days_by_employee[employee_id][str_current_date][ | 260 | ] = math.floor( |
385 | 238 | 'negative' | 261 | days_by_employee[employee_id][str_current_date]['negative'] * |
386 | 239 | ] = math.floor( | 262 | float_rounding |
387 | 240 | days_by_employee[employee_id][str_current_date]['negative'] * | 263 | ) / float_rounding |
388 | 241 | float_rounding | 264 | |
378 | 242 | ) / float_rounding | ||
379 | 243 | |||
389 | 244 | day_count += 1 | 265 | day_count += 1 |
390 | 245 | 266 | ||
391 | 246 | totals_by_employee = {} | 267 | totals_by_employee = {} |
392 | @@ -272,36 +293,34 @@ | |||
393 | 272 | days_by_employee[employee_id][str_date]['due']) | 293 | days_by_employee[employee_id][str_date]['due']) |
394 | 273 | 294 | ||
395 | 274 | # computing overtime types | 295 | # computing overtime types |
426 | 275 | active_contract_ids = attendance_pool.get_active_contracts( | 296 | reference_calendar = attendance_pool.get_reference_calendar( |
427 | 276 | cr, uid, int(employee_id), date=str_date) | 297 | cr, uid, int(employee_id), date=str_date, context=context) |
428 | 277 | if active_contract_ids: | 298 | if reference_calendar and reference_calendar.overtime_type_ids: |
429 | 278 | contract = contract_pool.browse(cr, uid, active_contract_ids[0]) | 299 | sorted_types = sorted( |
430 | 279 | if contract.working_hours and contract.working_hours.overtime_type_ids: | 300 | reference_calendar.overtime_type_ids, |
431 | 280 | sorted_types = sorted( | 301 | key=lambda k: k.sequence) |
432 | 281 | contract.working_hours.overtime_type_ids, | 302 | current_overtime = days_by_employee[employee_id][ |
433 | 282 | key=lambda k: k.sequence) | 303 | str_date]['overtime'] |
434 | 283 | current_overtime = days_by_employee[employee_id][ | 304 | for overtime_type in sorted_types: |
435 | 284 | str_date]['overtime'] | 305 | if not totals_by_employee[employee_id]['total_types'].get( |
436 | 285 | for overtime_type in sorted_types: | 306 | overtime_type.name, False): |
437 | 286 | if not totals_by_employee[employee_id]['total_types'].get( | 307 | totals_by_employee[employee_id]['total_types'][ |
438 | 287 | overtime_type.name, False): | 308 | overtime_type.name] = 0.0 |
439 | 288 | totals_by_employee[employee_id]['total_types'][ | 309 | if current_overtime: |
440 | 289 | overtime_type.name] = 0.0 | 310 | if current_overtime <= overtime_type.limit or not overtime_type.limit: |
441 | 290 | if current_overtime: | 311 | totals_by_employee[employee_id]['total_types'][ |
442 | 291 | if current_overtime <= overtime_type.limit or not overtime_type.limit: | 312 | overtime_type.name] = attendance_pool.time_sum( |
443 | 292 | totals_by_employee[employee_id]['total_types'][ | 313 | totals_by_employee[employee_id] |
444 | 293 | overtime_type.name] = attendance_pool.time_sum( | 314 | ['total_types'][overtime_type.name], |
445 | 294 | totals_by_employee[employee_id] | 315 | current_overtime) |
446 | 295 | ['total_types'][overtime_type.name], | 316 | current_overtime = 0.0 |
447 | 296 | current_overtime) | 317 | else: |
448 | 297 | current_overtime = 0.0 | 318 | totals_by_employee[employee_id]['total_types'][ |
449 | 298 | else: | 319 | overtime_type.name] = attendance_pool.time_sum( |
450 | 299 | totals_by_employee[employee_id]['total_types'][ | 320 | totals_by_employee[employee_id]['total_types'] |
451 | 300 | overtime_type.name] = attendance_pool.time_sum( | 321 | [overtime_type.name], overtime_type.limit) |
452 | 301 | totals_by_employee[employee_id]['total_types'] | 322 | current_overtime = attendance_pool.time_difference(overtime_type.limit, |
453 | 302 | [overtime_type.name], overtime_type.limit) | 323 | current_overtime) |
424 | 303 | current_overtime = attendance_pool.time_difference(overtime_type.limit, | ||
425 | 304 | current_overtime) | ||
454 | 305 | 324 | ||
455 | 306 | days_by_employee[employee_id][str_date][ | 325 | days_by_employee[employee_id][str_date][ |
456 | 307 | 'attendances' | 326 | 'attendances' |
457 | 308 | 327 | ||
458 | === modified file 'timesheet_task/project_task.py' |
LGTM