From 5780d1032bdc0ef15f76a15d81e6aa9baae4419d Mon Sep 17 00:00:00 2001 From: Lionel Sausin Date: Mon, 2 Feb 2009 19:25:43 +0100 Subject: [PATCH] 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