From 5780d1032bdc0ef15f76a15d81e6aa9baae4419d Mon Sep 17 00:00:00 2001 From: Lionel Sausin Date: Mon, 2 Feb 2009 19:25:43 +0100 Subject: [PATCH 1/2] Moved the attendance reports and wizard from the "hr" module to "hr_attendence". Pulled back the weekly attendance report from the 4.2 branch Removed theorical workhours and holiday workhours from the reports to make sure they can be printed even if only "hr" and "hr_attendance" are installed bzr revid: ls@numerigraphe.fr-20090202182543-km4x5yp27d74ksk8 --- addons/hr/__terp__.py | 1 - addons/hr/hr_wizard.xml | 13 -- addons/hr/report/__init__.py | 26 --- addons/hr/report/bymonth.py | 163 ---------------- addons/hr/report/siso.xml | 13 -- addons/hr/report/siso.xsl | 67 ------- addons/hr/wizard/__init__.py | 30 --- addons/hr/wizard/sign_in_out.py | 182 ------------------ addons/hr_attendance/hr_attendance_wizard.xml | 3 + addons/hr_attendance/report/__init__.py | 2 + addons/hr_attendance/report/bymonth.py | 102 ++++++++++ .../{hr => hr_attendance}/report/bymonth.xsl | 8 - addons/hr_attendance/wizard/__init__.py | 2 + .../wizard/print_bymonth.py | 0 .../wizard/print_byweek.py | 0 15 files changed, 109 insertions(+), 503 deletions(-) delete mode 100644 addons/hr/hr_wizard.xml delete mode 100644 addons/hr/report/__init__.py delete mode 100644 addons/hr/report/bymonth.py delete mode 100644 addons/hr/report/siso.xml delete mode 100644 addons/hr/report/siso.xsl delete mode 100644 addons/hr/wizard/__init__.py delete mode 100644 addons/hr/wizard/sign_in_out.py create mode 100644 addons/hr_attendance/report/bymonth.py rename addons/{hr => hr_attendance}/report/bymonth.xsl (88%) rename addons/{hr => hr_attendance}/wizard/print_bymonth.py (100%) rename addons/{hr => hr_attendance}/wizard/print_byweek.py (100%) diff --git a/addons/hr/__terp__.py b/addons/hr/__terp__.py index 2a82c2ba01f..efdd3d961af 100644 --- a/addons/hr/__terp__.py +++ b/addons/hr/__terp__.py @@ -43,7 +43,6 @@ 'security/hr_security.xml', 'security/ir.model.access.csv', 'hr_view.xml', - 'hr_wizard.xml', 'hr_department_view.xml', 'process/hr_process.xml' ], diff --git a/addons/hr/hr_wizard.xml b/addons/hr/hr_wizard.xml deleted file mode 100644 index 8b3c3e1c619..00000000000 --- a/addons/hr/hr_wizard.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/addons/hr/report/__init__.py b/addons/hr/report/__init__.py deleted file mode 100644 index d0d51700266..00000000000 --- a/addons/hr/report/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved -# $Id$ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -############################################################################## - -import bymonth - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/hr/report/bymonth.py b/addons/hr/report/bymonth.py deleted file mode 100644 index a926db0fcd4..00000000000 --- a/addons/hr/report/bymonth.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved -# $Id$ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -############################################################################## - -from mx import DateTime -from mx.DateTime import now -import time - -import netsvc -import pooler - -from report.interface import report_rml -from report.interface import toxml - -one_day = DateTime.RelativeDateTime(days=1) -month2name = [0,'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] - -def hour2str(h): - hours = int(h) - minutes = int(round((h - hours) * 60, 0)) - return '%02dh%02d' % (hours, minutes) - -class report_custom(report_rml): - def create_xml(self, cr, uid, ids, datas, context): - service = netsvc.LocalService('object_proxy') - - month = DateTime.DateTime(datas['form']['year'], datas['form']['month'], 1) - - user_xml = ['%s' % month2name[month.month], '%s' % month.year] - - # Public holidays - jf_sql = """select hol.date_from, hol.date_to from hr_holidays as hol, hr_holidays_status as stat - where hol.holiday_status = stat.id and stat.name = 'Public holidays' """ - cr.execute(jf_sql) - jfs = [] - jfs = [(DateTime.strptime(l['date_from'], '%Y-%m-%d %H:%M:%S'), DateTime.strptime(l['date_to'], '%Y-%m-%d %H:%M:%S')) for l in cr.dictfetchall()] - - for employee_id in ids: - emp = service.execute(cr.dbname, uid, 'hr.employee', 'read', [employee_id])[0] - stop, days_xml = False, [] - user_repr = ''' - - %s - %s - %s - %%s - - ''' % (toxml(emp['name']),emp['regime'],emp['holiday_max']) - today, tomor = month, month + one_day - while today.month == month.month: - #### Work hour calculation - sql = ''' - select action, att.name - from hr_employee as emp inner join hr_attendance as att - on emp.id = att.employee_id - where att.name between '%s' and '%s' and emp.id = %s - order by att.name - ''' - cr.execute(sql, (today, tomor, employee_id)) - attendences = cr.dictfetchall() - wh = 0 - if attendences and attendences[0]['action'] == 'sign_out': - attendences.insert(0, {'name': today.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_in'}) - if attendences and attendences[-1]['action'] == 'sign_in': - attendences.append({'name' : tomor.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_out'}) - for att in attendences: - dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') - if att['action'] == 'sign_out': - wh += (dt - ldt).hours - ldt = dt - - #### Theoretical workhour calculation - sql = ''' - select t.hour_from, t.hour_to - from hr_timesheet as t - inner join (hr_timesheet_group as g inner join hr_timesheet_employee_rel as rel - on rel.tgroup_id = g.id and rel.emp_id = %s) - on t.tgroup_id = g.id - where dayofweek = '%s' - and date_from = (select max(date_from) - from hr_timesheet inner join (hr_timesheet_employee_rel - inner join hr_timesheet_group - on hr_timesheet_group.id = hr_timesheet_employee_rel.tgroup_id - and hr_timesheet_employee_rel.emp_id = %s) - on hr_timesheet.tgroup_id = hr_timesheet_group.id - where dayofweek = '%s' and date_from <= '%s') - order by date_from desc - ''' - isPH = False - for jf_start, jf_end in jfs: - if jf_start <= today <= jf_end: - isPH = True - break - if isPH: - twh = 0 - else: - cr.execute(sql, (emp['id'], today.day_of_week, emp['id'], today.day_of_week, today)) - ths = cr.dictfetchall() - twh = reduce(lambda x,y:x+(DateTime.strptime(y['hour_to'], '%H:%M:%S') - DateTime.strptime(y['hour_from'], '%H:%M:%S')).hours,ths, 0) - - #### Holiday calculation - hh = 0 - sql = ''' - select hol.date_from, hol.date_to, stat.name as status - from hr_employee as emp - inner join (hr_holidays as hol left join hr_holidays_status as stat - on hol.holiday_status = stat.id) - on emp.id = hol.employee_id - where ((hol.date_from <= '%s' and hol.date_to >= '%s') - or (hol.date_from < '%s' and hol.date_to >= '%s') - or (hol.date_from > '%s' and hol.date_to < '%s')) - and emp.id = %s - order by hol.date_from - ''' - cr.execute(sql, (today, today, tomor, tomor, today, tomor, employee_id)) - holidays = cr.dictfetchall() - for hol in holidays: - df = DateTime.strptime(hol['date_from'], '%Y-%m-%d %H:%M:%S') - dt = DateTime.strptime(hol['date_to'], '%Y-%m-%d %H:%M:%S') - if (df.year, df.month, df.day) <= (today.year, today.month, today.day) <= (dt.year, dt.month, dt.day): - if (df.year, df.month, df.day) == (dt.year, dt.month, dt.day): - hh += (dt - df).hours - else: - hh = twh - - # Week xml representation - twh, wh, hh = map(hour2str, (twh, wh, hh)) - today_xml = '%s%s%s' % ((today - month).days+1, twh, wh, hh) - days_xml.append(today_xml) - today, tomor = tomor, tomor + one_day - - user_xml.append(user_repr % '\n'.join(days_xml)) - - xml = ''' - - %s - - ''' % '\n'.join(user_xml) - - return xml - -report_custom('report.hr.timesheet.bymonth', 'hr.employee', '', 'addons/hr/report/bymonth.xsl') - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/hr/report/siso.xml b/addons/hr/report/siso.xml deleted file mode 100644 index 5aab609fbe4..00000000000 --- a/addons/hr/report/siso.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - -
- - - - - - - - diff --git a/addons/hr/report/siso.xsl b/addons/hr/report/siso.xsl deleted file mode 100644 index 96cfc70c133..00000000000 --- a/addons/hr/report/siso.xsl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - a4_normal - - - - - - - - - - - - - - - - - - - - - - - - - Name: - - - - Address: - - - - - - Date - Action - Hour - - - - - - - - - - - - - - - - - - - - - diff --git a/addons/hr/wizard/__init__.py b/addons/hr/wizard/__init__.py deleted file mode 100644 index d2537d8dbda..00000000000 --- a/addons/hr/wizard/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved -# $Id$ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -############################################################################## - -#from print_byweek import wiz_byweek -#from print_bymonth import wiz_bymonth - - - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/hr/wizard/sign_in_out.py b/addons/hr/wizard/sign_in_out.py deleted file mode 100644 index e434aff68f9..00000000000 --- a/addons/hr/wizard/sign_in_out.py +++ /dev/null @@ -1,182 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved -# $Id$ -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -############################################################################## - -import wizard -import netsvc -import time -from tools.translate import _ - -si_so_form =''' -
- - - -''' - -si_so_fields = { - 'name' : {'string' : "Employee's name", 'type':'char', 'required':True, 'readonly':True}, - 'state' : {'string' : "Current state", 'type' : 'char', 'required' : True, 'readonly': True}, -} - -si_form = ''' -
- - -''' - -si_fields = { - 'success' : {'string' : "Sign in's status", 'type' : 'char', 'required' : True, 'readonly' : True}, -} - -so_form = ''' -
- - -''' - -so_fields = { - 'success' : {'string' : "Sign out's status", 'type' : 'char', 'required' : True, 'readonly' : True}, -} - -def _get_empid(self, cr, uid, data, context): - service = netsvc.LocalService('object_proxy') - emp_id = service.execute(cr.dbname, uid, 'hr.employee', 'search', [('user_id', '=', uid)]) - if emp_id: - employee = service.execute(cr.dbname, uid, 'hr.employee', 'read', emp_id)[0] - return {'name': employee['name'], 'state': employee['state'], 'emp_id': emp_id[0]} - return {} - -def _sign_in(self, cr, uid, data, context): - service = netsvc.LocalService('object_proxy') - emp_id = data['form']['emp_id'] - if 'last_time' in data['form'] : - if data['form']['last_time'] > time.strftime('%Y-%m-%d'): - raise wizard.except_wizard(_('UserError'), _('The sign-out date must be in the past')) - return {'success': False} - service.execute(cr.dbname, uid, 'hr.attendance', 'create', { - 'name': data['form']['last_time'], - 'action': 'sign_out', - 'employee_id': emp_id - }) - try: - success = service.execute(cr.dbname, uid, 'hr.employee', 'sign_in', [emp_id]) - except: - raise wizard.except_wizard(_('UserError'), _('A sign-in must be right after a sign-out !')) - return {'success': success} - -def _sign_out(self, cr, uid, data, context): - service = netsvc.LocalService('object_proxy') - emp_id = data['form']['emp_id'] - if 'last_time' in data['form'] : - if data['form']['last_time'] > time.strftime('%Y-%m-%d'): - raise wizard.except_wizard(_('UserError'), _('The Sign-in date must be in the past')) - return {'success': False} - service.execute(cr.dbname, uid, 'hr.attendance', 'create', {'name':data['form']['last_time'], 'action':'sign_in', 'employee_id':emp_id}) - try: - success = service.execute(cr.dbname, uid, 'hr.employee', 'sign_out', [emp_id]) - except: - raise wizard.except_wizard(_('UserError'), _('A sign-out must be right after a sign-in !')) - - return {'success' : success} - -so_ask_form =''' - - - - -''' - -so_ask_fields = { - 'name' : {'string' : "Employee's name", 'type':'char', 'required':True, 'readonly':True}, - 'last_time' : {'string' : "Your last sign out", 'type' : 'datetime', 'required' : True}, -} - -def _si_check(self, cr, uid, data, context): - states = {True : 'si', False: 'si_ask_so'} - service = netsvc.LocalService('object_proxy') - emp_id = data['form']['emp_id'] - att_id = service.execute(cr.dbname, uid, 'hr.attendance', 'search', [('employee_id', '=', emp_id)], limit=1, order='name desc') - last_att = service.execute(cr.dbname, uid, 'hr.attendance', 'read', att_id) - if last_att: - last_att = last_att[0] - cond = not last_att or last_att['action'] == 'sign_out' - return states[cond] - -si_ask_form =''' -
- - - -''' - -si_ask_fields = { - 'name' : {'string' : "Employee's name", 'type':'char', 'required':True, 'readonly':True}, - 'last_time' : {'string' : "Your last sign in", 'type' : 'datetime', 'required' : True}, -} - -def _so_check(self, cr, uid, data, context): - states = {True : 'so', False: 'so_ask_si'} - service = netsvc.LocalService('object_proxy') - emp_id = data['form']['emp_id'] - att_id = service.execute(cr.dbname, uid, 'hr.attendance', 'search', [('employee_id', '=', emp_id)], limit=1, order='name desc') - last_att = service.execute(cr.dbname, uid, 'hr.attendance', 'read', att_id) - if last_att: - last_att = last_att[0] - cond = last_att and last_att['action'] == 'sign_in' - return states[cond] - -class wiz_si_so(wizard.interface): - states = { - 'init' : { - 'actions' : [_get_empid], - 'result' : {'type' : 'form', 'arch' : si_so_form, 'fields' : si_so_fields, 'state' : [('end', 'Cancel'),('si_test', 'Sign in'),('so_test', 'Sign out')] } - }, - 'si_test' : { - 'actions' : [], - 'result' : {'type' : 'choice', 'next_state': _si_check} - }, - 'si_ask_so' : { - 'actions' : [], - 'result' : {'type' : 'form', 'arch' : so_ask_form, 'fields' : so_ask_fields, 'state' : [('end', 'Cancel'),('si', 'Sign in') ] } - }, - 'si' : { - 'actions' : [_sign_in], - 'result' : {'type' : 'state', 'state':'end'} - }, - 'so_test' : { - 'actions' : [], - 'result' : {'type' : 'choice', 'next_state': _so_check } - }, - 'so_ask_si' : { - 'actions' : [], - 'result' : {'type' : 'form', 'arch' : si_ask_form, 'fields' : si_ask_fields, 'state' : [('end', 'Cancel'),('so', 'Sign out')] } - }, - 'so' : { - 'actions' : [_sign_out], - 'result' : {'type' : 'state', 'state':'end'} - }, - } -wiz_si_so('hr.si_so') - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/hr_attendance/hr_attendance_wizard.xml b/addons/hr_attendance/hr_attendance_wizard.xml index 27dbe068edb..0c9e256ae45 100644 --- a/addons/hr_attendance/hr_attendance_wizard.xml +++ b/addons/hr_attendance/hr_attendance_wizard.xml @@ -5,6 +5,9 @@ + + + diff --git a/addons/hr_attendance/report/__init__.py b/addons/hr_attendance/report/__init__.py index 28f8b1e16aa..84f891d3c1b 100644 --- a/addons/hr_attendance/report/__init__.py +++ b/addons/hr_attendance/report/__init__.py @@ -20,5 +20,7 @@ # ############################################################################## import attendance_errors +import bymonth +import timesheet # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr_attendance/report/bymonth.py b/addons/hr_attendance/report/bymonth.py new file mode 100644 index 00000000000..bce9bd4d3ce --- /dev/null +++ b/addons/hr_attendance/report/bymonth.py @@ -0,0 +1,102 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved +# $Id$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +from mx import DateTime +from mx.DateTime import now +import time + +import netsvc +import pooler + +from report.interface import report_rml +from report.interface import toxml + +one_day = DateTime.RelativeDateTime(days=1) +month2name = [0,'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] + +def hour2str(h): + hours = int(h) + minutes = int(round((h - hours) * 60, 0)) + return '%02dh%02d' % (hours, minutes) + +class report_custom(report_rml): + def create_xml(self, cr, uid, ids, datas, context): + service = netsvc.LocalService('object_proxy') + + month = DateTime.DateTime(datas['form']['year'], datas['form']['month'], 1) + + user_xml = ['%s' % month2name[month.month], '%s' % month.year] + + for employee_id in ids: + emp = service.execute(cr.dbname, uid, 'hr.employee', 'read', [employee_id])[0] + stop, days_xml = False, [] + user_repr = ''' + + %s + %%s + + ''' % (toxml(emp['name'])) + today, tomor = month, month + one_day + while today.month == month.month: + #### Work hour calculation + sql = ''' + select action, att.name + from hr_employee as emp inner join hr_attendance as att + on emp.id = att.employee_id + where att.name between %s and %s and emp.id = %s + order by att.name + ''' + cr.execute(sql, (today, tomor, employee_id)) + attendences = cr.dictfetchall() + wh = 0 + # Fake sign ins/outs at week ends, to take attendances across week ends into account + if attendences and attendences[0]['action'] == 'sign_out': + attendences.insert(0, {'name': today.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_in'}) + if attendences and attendences[-1]['action'] == 'sign_in': + attendences.append({'name' : tomor.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_out'}) + # sum up the attendances' durations + for att in attendences: + dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') + if att['action'] == 'sign_out': + wh += (dt - ldt).hours + ldt = dt + + # Week xml representation + wh = hour2str(wh) + today_xml = '%s' % ((today - month).days+1, wh) + days_xml.append(today_xml) + today, tomor = tomor, tomor + one_day + + user_xml.append(user_repr % '\n'.join(days_xml)) + + xml = ''' + + %s + + ''' % '\n'.join(user_xml) + + return xml + +report_custom('report.hr.timesheet.bymonth', 'hr.employee', '', 'addons/hr_attendance/report/bymonth.xsl') + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/hr/report/bymonth.xsl b/addons/hr_attendance/report/bymonth.xsl similarity index 88% rename from addons/hr/report/bymonth.xsl rename to addons/hr_attendance/report/bymonth.xsl index 8d5ae74f8cc..133602f1558 100644 --- a/addons/hr/report/bymonth.xsl +++ b/addons/hr_attendance/report/bymonth.xsl @@ -85,16 +85,8 @@ - By week: h - Holidays: - - Theoretical - - - - Worked diff --git a/addons/hr_attendance/wizard/__init__.py b/addons/hr_attendance/wizard/__init__.py index 7e8f0f7f43c..f6ce627cbf9 100644 --- a/addons/hr_attendance/wizard/__init__.py +++ b/addons/hr_attendance/wizard/__init__.py @@ -21,5 +21,7 @@ ############################################################################## import sign_in_out import print_attendance_error +from print_byweek import wiz_byweek +from print_bymonth import wiz_bymonth # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr/wizard/print_bymonth.py b/addons/hr_attendance/wizard/print_bymonth.py similarity index 100% rename from addons/hr/wizard/print_bymonth.py rename to addons/hr_attendance/wizard/print_bymonth.py diff --git a/addons/hr/wizard/print_byweek.py b/addons/hr_attendance/wizard/print_byweek.py similarity index 100% rename from addons/hr/wizard/print_byweek.py rename to addons/hr_attendance/wizard/print_byweek.py From ef1e57f3c88510d85072116d78954b9c62348b84 Mon Sep 17 00:00:00 2001 From: Lionel Sausin Date: Wed, 4 Feb 2009 09:23:39 +0100 Subject: [PATCH 2/2] Added report files taken from the 4.2 branch and simplified to fit hr_attendance (forgot them in last commit, sorry). bzr revid: ls@numerigraphe.fr-20090204082339-10md4llzje3qph23 --- addons/hr_attendance/report/timesheet.py | 128 +++++++++++++++++++++ addons/hr_attendance/report/timesheet.xsl | 131 ++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 addons/hr_attendance/report/timesheet.py create mode 100644 addons/hr_attendance/report/timesheet.xsl diff --git a/addons/hr_attendance/report/timesheet.py b/addons/hr_attendance/report/timesheet.py new file mode 100644 index 00000000000..a3a370bcb99 --- /dev/null +++ b/addons/hr_attendance/report/timesheet.py @@ -0,0 +1,128 @@ +############################################################################## +# +# Copyright (c) 2005 TINY SPRL. (http://tiny.be) All Rights Reserved. +# Fabien Pinckaers +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +from mx import DateTime +from mx.DateTime import now + +import netsvc +import pooler + +from report.interface import report_rml +from report.interface import toxml + +one_week = DateTime.RelativeDateTime(days=7) +num2day = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] + +def to_hour(h): + return int(h), int(round((h - int(h)) * 60, 0)) + +class report_custom(report_rml): + def create_xml(self, cr, uid, ids, datas, context): + service = netsvc.LocalService('object_proxy') + + start_date = DateTime.strptime(datas['form']['init_date'], '%Y-%m-%d') + print "XXX start_date %s" % start_date + end_date = DateTime.strptime(datas['form']['end_date'], '%Y-%m-%d') + print "XXX end_date %s" % end_date + first_monday = start_date - DateTime.RelativeDateTime(days=start_date.day_of_week) + print "XXX first_monday %s" % first_monday + last_monday = end_date + DateTime.RelativeDateTime(days=7 - end_date.day_of_week) + print "XXX last_monday %s" % last_monday + + if last_monday < first_monday: + first_monday, last_monday = last_monday, first_monday + + user_xml = [] + + for employee_id in ids: + print "XXX employee_id %s" % employee_id + emp = service.execute(cr.dbname, uid, 'hr.employee', 'read', [employee_id], ['id', 'name'])[0] + monday, n_monday = first_monday, first_monday + one_week + stop, week_xml = False, [] + user_repr = ''' + + %s + %%s + + ''' % toxml(emp['name']) + while monday != last_monday: + #### Work hour calculation + sql = ''' + select action, att.name + from hr_employee as emp inner join hr_attendance as att + on emp.id = att.employee_id + where att.name between %s and %s and emp.id = %s + order by att.name + ''' + for idx in range(7): + print sql % (monday, monday + DateTime.RelativeDateTime(days=idx+1), employee_id) + cr.execute(sql, (monday, monday + DateTime.RelativeDateTime(days=idx+1), employee_id)) + attendances = cr.dictfetchall() + print "attendances %s" %attendances + week_wh = {} + # Fake sign ins/outs at week ends, to take attendances across week ends into account + # XXX this is wrong for the first sign-in ever and the last sign out to this date + if attendances and attendances[0]['action'] == 'sign_out': + attendances.insert(0, {'name': monday.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_in'}) + if attendances and attendances[-1]['action'] == 'sign_in': + attendances.append({'name' : n_monday.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_out'}) + # sum up the attendances' durations + for att in attendances: + dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S') + if att['action'] == 'sign_out': + week_wh[ldt.day_of_week] = week_wh.get(ldt.day_of_week, 0) + (dt - ldt).hours + ldt = dt + + # Week xml representation + week_repr = ['', '%s' % monday.strftime('%Y-%m-%d'), '%s' % n_monday.strftime('%Y-%m-%d')] + for idx in range(7): + week_repr.append('<%s>' % num2day[idx]) + if idx in week_wh: + week_repr.append('%sh%02d' % to_hour(week_wh[idx])) + week_repr.append('' % num2day[idx]) + week_repr.append('') + week_repr.append('%sh%02d' % to_hour(reduce(lambda x,y:x+y, week_wh.values(), 0))) + week_repr.append('') + week_repr.append('') + print "XXX week_repr %s" % week_repr + if len(week_repr) > 21: # 21 = minimal length of week_repr + week_xml.append('\n'.join(week_repr)) + + monday, n_monday = n_monday, n_monday + one_week + user_xml.append(user_repr % '\n'.join(week_xml)) + + xml = ''' + + %s + + ''' % '\n'.join(user_xml) + print "XXX xml %s" % xml + return self.post_process_xml_data(cr, uid, xml, context) + +report_custom('report.hr.timesheet.allweeks', 'hr.employee', '', 'addons/hr_attendance/report/timesheet.xsl') +# vim:noexpandtab:tw=0 diff --git a/addons/hr_attendance/report/timesheet.xsl b/addons/hr_attendance/report/timesheet.xsl new file mode 100644 index 00000000000..f815c0880fc --- /dev/null +++ b/addons/hr_attendance/report/timesheet.xsl @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name: + + + + + + Mon + Tue + Wed + Thu + Fri + Sat + Sun + Tot + + + + + Week: + + from to + + + Worked hours + + + + + + 0 + + + + + + + + 0 + + + + + + + + 0 + + + + + + + + 0 + + + + + + + + 0 + + + + + + + + 0 + + + + + + + + 0 + + + + + + + + + +