1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
23 from datetime import datetime
24 from dateutil.relativedelta import relativedelta
27 from report.interface import report_rml
28 from report.interface import toxml
31 one_week = relativedelta(days=7)
32 num2day = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
35 return int(h), int(round((h - int(h)) * 60, 0))
37 class report_custom(report_rml):
39 def create_xml(self, cr, uid, ids, datas, context=None):
40 obj_emp = pooler.get_pool(cr.dbname).get('hr.employee')
42 start_date = datetime.strptime(datas['form']['init_date'], '%Y-%m-%d')
43 end_date = datetime.strptime(datas['form']['end_date'], '%Y-%m-%d')
44 first_monday = start_date - relativedelta(days=start_date.date().weekday())
45 last_monday = end_date + relativedelta(days=7 - end_date.date().weekday())
47 if last_monday < first_monday:
48 first_monday, last_monday = last_monday, first_monday
52 for employee_id in ids:
53 emp = obj_emp.read(cr, uid, [employee_id], ['id', 'name'])[0]
54 monday, n_monday = first_monday, first_monday + one_week
55 stop, week_xml = False, []
61 ''' % tools.ustr(toxml(emp['name']))
62 while monday != last_monday:
63 #### Work hour calculation
65 select action, att.name
66 from hr_employee as emp inner join hr_attendance as att
67 on emp.id = att.employee_id
68 where att.name between %s and %s and emp.id = %s
72 cr.execute(sql, (monday.strftime('%Y-%m-%d %H:%M:%S'), (monday + relativedelta(days=idx+1)).strftime('%Y-%m-%d %H:%M:%S'), employee_id))
73 attendances = cr.dictfetchall()
75 # Fake sign ins/outs at week ends, to take attendances across week ends into account
76 # XXX this is wrong for the first sign-in ever and the last sign out to this date
77 if attendances and attendances[0]['action'] == 'sign_out':
78 attendances.insert(0, {'name': monday.strftime('%Y-%m-%d %H:%M:%S'), 'action': 'sign_in'})
79 if attendances and attendances[-1]['action'] == 'sign_in':
80 attendances.append({'name': n_monday.strftime('%Y-%m-%d %H:%M:%S'), 'action': 'sign_out'})
81 # sum up the attendances' durations
83 for att in attendances:
84 dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
85 if ldt and att['action'] == 'sign_out':
86 week_wh[ldt.date().weekday()] = week_wh.get(ldt.date().weekday(), 0) + (float((dt - ldt).seconds)/3600)
90 # Week xml representation
91 week_repr = ['<week>', '<weekstart>%s</weekstart>' % monday.strftime('%Y-%m-%d'), '<weekend>%s</weekend>' % n_monday.strftime('%Y-%m-%d')]
93 week_repr.append('<%s>' % num2day[idx])
95 week_repr.append('<workhours>%sh%02d</workhours>' % to_hour(week_wh[idx]))
96 week_repr.append('</%s>' % num2day[idx])
97 week_repr.append('<total>')
98 week_repr.append('<worked>%sh%02d</worked>' % to_hour(reduce(lambda x,y:x+y, week_wh.values(), 0)))
99 week_repr.append('</total>')
100 week_repr.append('</week>')
101 if len(week_repr) > 21: # 21 = minimal length of week_repr
102 week_xml.append('\n'.join(week_repr))
104 monday, n_monday = n_monday, n_monday + one_week
105 user_xml.append(user_repr % '\n'.join(week_xml))
107 xml = '''<?xml version="1.0" encoding="UTF-8" ?>
111 ''' % '\n'.join(user_xml)
112 return self.post_process_xml_data(cr, uid, xml, context)
114 report_custom('report.hr.attendance.allweeks', 'hr.employee', '', 'addons/hr_attendance/report/timesheet.xsl')
115 # vim:noexpandtab:tw=0