[REM] hr_attendance: removed attendance by week/month reports, rml and wizards
bzr revid: sle@openerp.com-20140424092639-nlzxtx17jaa2w9p7
This commit is contained in:
parent
fc2dd8983d
commit
5eb2f28bb9
|
@ -39,8 +39,6 @@ actions(Sign in/Sign out) performed by them.
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'hr_attendance_view.xml',
|
'hr_attendance_view.xml',
|
||||||
'hr_attendance_report.xml',
|
'hr_attendance_report.xml',
|
||||||
'wizard/hr_attendance_bymonth_view.xml',
|
|
||||||
'wizard/hr_attendance_byweek_view.xml',
|
|
||||||
'wizard/hr_attendance_error_view.xml',
|
'wizard/hr_attendance_error_view.xml',
|
||||||
'res_config_view.xml',
|
'res_config_view.xml',
|
||||||
'views/report_attendanceerrors.xml',
|
'views/report_attendanceerrors.xml',
|
||||||
|
|
|
@ -25,6 +25,7 @@ from datetime import datetime
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
|
||||||
class hr_action_reason(osv.osv):
|
class hr_action_reason(osv.osv):
|
||||||
_name = "hr.action.reason"
|
_name = "hr.action.reason"
|
||||||
_description = "Action Reason"
|
_description = "Action Reason"
|
||||||
|
@ -41,6 +42,7 @@ def _employee_get(obj, cr, uid, context=None):
|
||||||
ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
|
ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
|
||||||
return ids and ids[0] or False
|
return ids and ids[0] or False
|
||||||
|
|
||||||
|
|
||||||
class hr_attendance(osv.osv):
|
class hr_attendance(osv.osv):
|
||||||
_name = "hr.attendance"
|
_name = "hr.attendance"
|
||||||
_description = "Attendance"
|
_description = "Attendance"
|
||||||
|
|
|
@ -20,7 +20,5 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import attendance_errors
|
import attendance_errors
|
||||||
import attendance_by_month
|
|
||||||
import timesheet
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -1,196 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
import time
|
|
||||||
|
|
||||||
import openerp
|
|
||||||
from openerp.report import report_sxw
|
|
||||||
from openerp.report.interface import report_rml
|
|
||||||
from openerp.report.interface import toxml
|
|
||||||
from openerp.tools import to_xml, ustr
|
|
||||||
from openerp.tools.translate import _
|
|
||||||
|
|
||||||
one_day = relativedelta(days=1)
|
|
||||||
month2name = [0, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
|
||||||
|
|
||||||
def hour2str(h):
|
|
||||||
hours = int(h)
|
|
||||||
minutes = int(round((h - hours) * 60, 0))
|
|
||||||
return '%02dh%02d' % (hours, minutes)
|
|
||||||
|
|
||||||
def lengthmonth(year, month):
|
|
||||||
if month == 2 and ((year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0))):
|
|
||||||
return 29
|
|
||||||
return [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
|
|
||||||
|
|
||||||
class report_custom(report_rml):
|
|
||||||
|
|
||||||
def create_xml(self, cr, uid, ids, datas, context=None):
|
|
||||||
registry = openerp.registry(cr.dbname)
|
|
||||||
obj_emp = registry['hr.employee']
|
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
month = datetime(datas['form']['year'], datas['form']['month'], 1)
|
|
||||||
emp_ids = datas['active_ids']
|
|
||||||
user_xml = ['<month>%s</month>' % _(month2name[month.month]), '<year>%s</year>' % month.year]
|
|
||||||
if emp_ids:
|
|
||||||
for emp in obj_emp.read(cr, uid, emp_ids, ['name']):
|
|
||||||
stop, days_xml = False, []
|
|
||||||
total_wh = 0.0
|
|
||||||
user_repr = '''
|
|
||||||
<user>
|
|
||||||
<name>%s</name>
|
|
||||||
%%s
|
|
||||||
</user>
|
|
||||||
''' % (ustr(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.strftime('%Y-%m-%d %H:%M:%S'), tomor.strftime('%Y-%m-%d %H:%M:%S'), emp['id']))
|
|
||||||
attendences = cr.dictfetchall()
|
|
||||||
wh = 0.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
|
|
||||||
ldt = None
|
|
||||||
for att in attendences:
|
|
||||||
dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
|
|
||||||
if ldt and att['action'] == 'sign_out':
|
|
||||||
if dt.date() > ldt.date():
|
|
||||||
dt = ldt
|
|
||||||
wh += (float((dt - ldt).seconds)/60/60)
|
|
||||||
else:
|
|
||||||
ldt = dt
|
|
||||||
# Week xml representation
|
|
||||||
total_wh += wh
|
|
||||||
wh = hour2str(wh)
|
|
||||||
today_xml = '<day num="%s"><wh>%s</wh></day>' % ((today - month).days+1, (wh))
|
|
||||||
dy=(today - month).days+1
|
|
||||||
days_xml.append(today_xml)
|
|
||||||
today, tomor = tomor, tomor + one_day
|
|
||||||
total_wh = hour2str(total_wh)
|
|
||||||
today_xml = '<day num="Total"><wh>%s</wh></day>' % (total_wh)
|
|
||||||
days_xml.append(today_xml)
|
|
||||||
user_xml.append(user_repr % '\n'.join(days_xml))
|
|
||||||
|
|
||||||
rpt_obj = obj_emp
|
|
||||||
rml_obj=report_sxw.rml_parse(cr, uid, rpt_obj._name,context)
|
|
||||||
header_xml = '''
|
|
||||||
<header>
|
|
||||||
<date>%s</date>
|
|
||||||
<company>%s</company>
|
|
||||||
</header>
|
|
||||||
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),to_xml(registry['res.users'].browse(cr,uid,uid).company_id.name))
|
|
||||||
|
|
||||||
first_date = str(month)
|
|
||||||
som = datetime.strptime(first_date, '%Y-%m-%d %H:%M:%S')
|
|
||||||
eom = som + timedelta(int(dy)-1)
|
|
||||||
day_diff=eom-som
|
|
||||||
date_xml=[]
|
|
||||||
cell=1
|
|
||||||
date_xml.append('<days>')
|
|
||||||
if day_diff.days>=30:
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som.replace(day=x).strftime('%a')),x-som.day+1) for x in range(som.day, lengthmonth(som.year, som.month)+1)]
|
|
||||||
else:
|
|
||||||
if day_diff.days>=(lengthmonth(som.year, som.month)-som.day):
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som.replace(day=x).strftime('%a')),x-som.day+1) for x in range(som.day, lengthmonth(som.year, som.month)+1)]
|
|
||||||
else:
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som.replace(day=x).strftime('%a')),x-som.day+1) for x in range(som.day, eom.day+1)]
|
|
||||||
cell=x-som.day+1
|
|
||||||
day_diff1=day_diff.days-cell+1
|
|
||||||
width_dict={}
|
|
||||||
month_dict={}
|
|
||||||
i=1
|
|
||||||
j=1
|
|
||||||
year=som.year
|
|
||||||
month=som.month
|
|
||||||
month_dict[j]=som.strftime('%B')
|
|
||||||
width_dict[j]=cell
|
|
||||||
|
|
||||||
while day_diff1>0:
|
|
||||||
if month+i<=12:
|
|
||||||
if day_diff1 > lengthmonth(year,i+month): # Not on 30 else you have problems when entering 01-01-2009 for example
|
|
||||||
som1=datetime.date(year,month+i,1)
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som1.replace(day=x).strftime('%a')),cell+x) for x in range(1, lengthmonth(year,i+month)+1)]
|
|
||||||
i=i+1
|
|
||||||
j=j+1
|
|
||||||
month_dict[j]=som1.strftime('%B')
|
|
||||||
cell=cell+x
|
|
||||||
width_dict[j]=x
|
|
||||||
else:
|
|
||||||
som1=datetime.date(year,month+i,1)
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som1.replace(day=x).strftime('%a')),cell+x) for x in range(1, eom.day+1)]
|
|
||||||
i=i+1
|
|
||||||
j=j+1
|
|
||||||
month_dict[j]=som1.strftime('%B')
|
|
||||||
cell=cell+x
|
|
||||||
width_dict[j]=x
|
|
||||||
day_diff1=day_diff1-x
|
|
||||||
else:
|
|
||||||
years=year+1
|
|
||||||
year=years
|
|
||||||
month=0
|
|
||||||
i=1
|
|
||||||
if day_diff1>=30:
|
|
||||||
som1=datetime.date(years,i,1)
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som1.replace(day=x).strftime('%a')),cell+x) for x in range(1, lengthmonth(years,i)+1)]
|
|
||||||
i=i+1
|
|
||||||
j=j+1
|
|
||||||
month_dict[j]=som1.strftime('%B')
|
|
||||||
cell=cell+x
|
|
||||||
width_dict[j]=x
|
|
||||||
else:
|
|
||||||
som1=datetime.date(years,i,1)
|
|
||||||
i=i+1
|
|
||||||
j=j+1
|
|
||||||
month_dict[j]=som1.strftime('%B')
|
|
||||||
date_xml += ['<dayy number="%d" name="%s" cell="%d"/>' % (x, _(som1.replace(day=x).strftime('%a')),cell+x) for x in range(1, eom.day+1)]
|
|
||||||
cell=cell+x
|
|
||||||
width_dict[j]=x
|
|
||||||
day_diff1=day_diff1-x
|
|
||||||
date_xml += ['<dayy name="Total" cell="Total"/>']
|
|
||||||
date_xml.append('</days>')
|
|
||||||
date_xml.append('<cols>3.5cm%s,1.2cm</cols>\n' % (',0.74cm' * (int(dy))))
|
|
||||||
xml = '''<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<report>
|
|
||||||
%s
|
|
||||||
<title>%s</title>
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
</report>
|
|
||||||
''' % (header_xml,_('Attendances by Month'),'\n'.join(user_xml),date_xml)
|
|
||||||
return xml
|
|
||||||
|
|
||||||
report_custom('report.hr.attendance.bymonth', 'hr.employee', '', 'addons/hr_attendance/report/bymonth.xsl')
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
|
@ -1,81 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xsl:stylesheet version="1.0"
|
|
||||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
||||||
xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
|
||||||
|
|
||||||
<xsl:import href="hr_custom_default.xsl"/>
|
|
||||||
<xsl:import href="hr_custom_rml.xsl"/>
|
|
||||||
|
|
||||||
<xsl:template match="/">
|
|
||||||
<xsl:call-template name="rml" />
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template name="stylesheet">
|
|
||||||
<paraStyle name="title" fontName="Helvetica-Bold" fontSize="15.0" leading="17" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
|
|
||||||
<paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="14.0" leading="17" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
|
|
||||||
<paraStyle name="name" fontName="Helvetica" textColor="green" fontSize="7"/>
|
|
||||||
<paraStyle name="normal" fontName="Helvetica" fontSize="6"/>
|
|
||||||
<blockTableStyle id="week">
|
|
||||||
<blockFont name="Helvetica-BoldOblique" size="6" alignment="center" start="0,0" stop="-1,1"/>
|
|
||||||
<blockFont name="Helvetica" size="5" alignment="center" start="0,1" stop="-1,-1"/>
|
|
||||||
<blockBackground colorName="#AAAAAA" start="1,0" stop="-1,1"/>
|
|
||||||
<lineStyle kind="LINEABOVE" colorName="black" start="0,0" stop="-1,0" />
|
|
||||||
<lineStyle kind="LINEBEFORE" colorName="black" start="0,0" stop="-1,-1"/>
|
|
||||||
<lineStyle kind="LINEAFTER" colorName="black" start="-1,0" stop="-1,-1"/>
|
|
||||||
<lineStyle kind="LINEBELOW" colorName="black" start="0,0" stop="-1,-1"/>
|
|
||||||
<blockValign value="TOP"/>
|
|
||||||
</blockTableStyle>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template name="story">
|
|
||||||
<spacer length="1cm" />
|
|
||||||
<xsl:apply-templates select="report/title"/>
|
|
||||||
<spacer length="1cm" />
|
|
||||||
<blockTable>
|
|
||||||
<xsl:attribute name="style">week</xsl:attribute>
|
|
||||||
<xsl:attribute name="colWidths"><xsl:value-of select="report/cols" /></xsl:attribute>
|
|
||||||
<tr>
|
|
||||||
<td><xsl:value-of select="/report/year" /></td>
|
|
||||||
<xsl:for-each select="report/days/dayy">
|
|
||||||
<td>
|
|
||||||
<xsl:value-of select="attribute::name" />
|
|
||||||
</td>
|
|
||||||
</xsl:for-each>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><xsl:value-of select="/report/month" /></td>
|
|
||||||
<xsl:for-each select="report/days/dayy">
|
|
||||||
<td>
|
|
||||||
<xsl:value-of select="attribute::number" />
|
|
||||||
</td>
|
|
||||||
</xsl:for-each>
|
|
||||||
</tr>
|
|
||||||
<xsl:apply-templates select="report/user"/>
|
|
||||||
</blockTable>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="title">
|
|
||||||
<para style="title">
|
|
||||||
<xsl:value-of select="."/>
|
|
||||||
</para>
|
|
||||||
<spacer length="1cm"/>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="user">
|
|
||||||
<!-- <tr></tr>-->
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<para style="name"><xsl:value-of select="name" /></para>
|
|
||||||
</td>
|
|
||||||
<xsl:for-each select="day">
|
|
||||||
<td><xsl:value-of select="wh" /></td>
|
|
||||||
</xsl:for-each>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<!-- <tr>-->
|
|
||||||
<!-- <td>Worked</td>-->
|
|
||||||
<!-- -->
|
|
||||||
<!-- </tr>-->
|
|
||||||
</xsl:template>
|
|
||||||
</xsl:stylesheet>
|
|
|
@ -1,127 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
import time
|
|
||||||
|
|
||||||
import openerp
|
|
||||||
from openerp import tools
|
|
||||||
from openerp.report import report_sxw
|
|
||||||
from openerp.report.interface import report_rml, toxml
|
|
||||||
from openerp.tools.translate import _
|
|
||||||
|
|
||||||
one_week = relativedelta(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=None):
|
|
||||||
registry = openerp.registry(cr.dbname)
|
|
||||||
obj_emp = registry['hr.employee']
|
|
||||||
|
|
||||||
emp_ids = datas['active_ids']
|
|
||||||
start_date = datetime.strptime(datas['form']['init_date'], '%Y-%m-%d')
|
|
||||||
end_date = datetime.strptime(datas['form']['end_date'], '%Y-%m-%d')
|
|
||||||
first_monday = start_date - relativedelta(days=start_date.date().weekday())
|
|
||||||
last_monday = end_date + relativedelta(days=7 - end_date.date().weekday())
|
|
||||||
|
|
||||||
if last_monday < first_monday:
|
|
||||||
first_monday, last_monday = last_monday, first_monday
|
|
||||||
|
|
||||||
rpt_obj = obj_emp
|
|
||||||
rml_obj=report_sxw.rml_parse(cr, uid, rpt_obj._name,context)
|
|
||||||
header_xml = '''
|
|
||||||
<header>
|
|
||||||
<date>%s</date>
|
|
||||||
<company>%s</company>
|
|
||||||
</header>
|
|
||||||
''' % (str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")),registry['res.users'].browse(cr,uid,uid).company_id.name)
|
|
||||||
user_xml = []
|
|
||||||
for employee_id in emp_ids:
|
|
||||||
emp = obj_emp.read(cr, uid, [employee_id], ['id', 'name'])[0]
|
|
||||||
monday, n_monday = first_monday, first_monday + one_week
|
|
||||||
stop, week_xml = False, []
|
|
||||||
user_repr = '''
|
|
||||||
<user>
|
|
||||||
<name>%s</name>
|
|
||||||
%%s
|
|
||||||
</user>
|
|
||||||
''' % tools.ustr(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):
|
|
||||||
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))
|
|
||||||
attendances = cr.dictfetchall()
|
|
||||||
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
|
|
||||||
ldt = None
|
|
||||||
for att in attendances:
|
|
||||||
dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
|
|
||||||
if ldt and att['action'] == 'sign_out':
|
|
||||||
week_wh[ldt.date().weekday()] = week_wh.get(ldt.date().weekday(), 0) + (float((dt - ldt).seconds)/3600)
|
|
||||||
else:
|
|
||||||
ldt = dt
|
|
||||||
|
|
||||||
# Week xml representation
|
|
||||||
week_repr = ['<week>', '<weekstart>%s</weekstart>' % monday.strftime('%Y-%m-%d'), '<weekend>%s</weekend>' % (n_monday - relativedelta(days=1)).strftime('%Y-%m-%d')]
|
|
||||||
for idx in range(7):
|
|
||||||
week_repr.append('<%s>' % num2day[idx])
|
|
||||||
if idx in week_wh:
|
|
||||||
week_repr.append('<workhours>%sh%02d</workhours>' % to_hour(week_wh[idx]))
|
|
||||||
week_repr.append('</%s>' % num2day[idx])
|
|
||||||
week_repr.append('<total>')
|
|
||||||
week_repr.append('<worked>%sh%02d</worked>' % to_hour(reduce(lambda x,y:x+y, week_wh.values(), 0)))
|
|
||||||
week_repr.append('</total>')
|
|
||||||
week_repr.append('</week>')
|
|
||||||
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 = '''<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<report>
|
|
||||||
%s
|
|
||||||
<title>%s</title>
|
|
||||||
%s
|
|
||||||
</report>
|
|
||||||
''' % (header_xml,_('Attendances by Week'),'\n'.join(user_xml))
|
|
||||||
xml = tools.ustr(xml).encode('utf8')
|
|
||||||
return self.post_process_xml_data(cr, uid, xml, context)
|
|
||||||
|
|
||||||
report_custom('report.hr.attendance.allweeks', 'hr.employee', '', 'addons/hr_attendance/report/timesheet.xsl')
|
|
||||||
# vim:noexpandtab:tw=0
|
|
|
@ -1,155 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xsl:stylesheet version="1.0"
|
|
||||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
||||||
xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
|
||||||
|
|
||||||
<xsl:import href="hr_custom_default.xsl"/>
|
|
||||||
<xsl:import href="hr_custom_rml.xsl"/>
|
|
||||||
|
|
||||||
<xsl:template match="/">
|
|
||||||
<xsl:call-template name="rml" />
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template name="stylesheet">
|
|
||||||
<document filename="timesheet.pdf">
|
|
||||||
<template pageSize="29.7cm,21cm" leftMargin="2.0cm" rightMargin="2.0cm" topMargin="2.0cm" bottomMargin="2.0cm" title="Timesheets" author="Generated by Open ERP, Fabien Pinckaers" allowSplitting="20">
|
|
||||||
<pageTemplate id="first">
|
|
||||||
<pageGraphics>
|
|
||||||
<drawRightString x="19.0cm" y="26.0cm"><xsl:value-of select="date"/></drawRightString>
|
|
||||||
</pageGraphics>
|
|
||||||
<frame id="col1" x1="2.0cm" y1="2.5cm" width="22.7cm" height="18cm"/>
|
|
||||||
</pageTemplate>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<stylesheet>
|
|
||||||
<paraStyle name="title" fontName="Helvetica-Bold" fontSize="15.0" leading="17" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
|
|
||||||
<paraStyle name="emp" fontSize="13.0"/>
|
|
||||||
<blockTableStyle id="week">
|
|
||||||
<blockFont name="Helvetica" size="9" start="0,0" stop="-1,-1"/>
|
|
||||||
<blockFont name="Helvetica-BoldOblique" size="12" start="0,0" stop="0,0"/>
|
|
||||||
<blockBackground colorName="lightgrey" start="1,0" stop="-1,0"/>
|
|
||||||
<blockFont name="Helvetica-BoldOblique" start="-1,0" stop="-1,-1"/>
|
|
||||||
<lineStyle kind="LINEABOVE" colorName="black" start="0,0" stop="-1,0" />
|
|
||||||
<lineStyle kind="LINEBEFORE" colorName="black" start="0,0" stop="-1,-1"/>
|
|
||||||
<lineStyle kind="LINEAFTER" colorName="black" start="-1,0" stop="-1,-1"/>
|
|
||||||
<lineStyle kind="LINEBELOW" colorName="black" start="0,0" stop="-1,-1"/>
|
|
||||||
<blockValign value="TOP"/>
|
|
||||||
</blockTableStyle>
|
|
||||||
</stylesheet>
|
|
||||||
|
|
||||||
<story>
|
|
||||||
<xsl:call-template name="story"/>
|
|
||||||
</story>
|
|
||||||
</document>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template name="story">
|
|
||||||
<spacer length="1cm" />
|
|
||||||
<xsl:apply-templates select="report/title"/>
|
|
||||||
<xsl:apply-templates select="report/user"/>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="title">
|
|
||||||
<para style="title">
|
|
||||||
<xsl:value-of select="."/>
|
|
||||||
</para>
|
|
||||||
<spacer length="1cm"/>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="user">
|
|
||||||
<spacer length="1cm" />
|
|
||||||
<para style="emp">
|
|
||||||
<b>Employee: </b>
|
|
||||||
<i><xsl:value-of select="name" /></i>
|
|
||||||
</para>
|
|
||||||
<spacer length="0.5cm" />
|
|
||||||
<xsl:for-each select="week">
|
|
||||||
<blockTable colWidths="8cm,2cm,2cm,2cm,2cm,2cm,2cm,2cm,2cm" style="week">
|
|
||||||
<tr>
|
|
||||||
<td>From <xsl:value-of select="weekstart" /> to <xsl:value-of select="weekend" /></td>
|
|
||||||
<td>Mon</td>
|
|
||||||
<td>Tue</td>
|
|
||||||
<td>Wed</td>
|
|
||||||
<td>Thu</td>
|
|
||||||
<td>Fri</td>
|
|
||||||
<td>Sat</td>
|
|
||||||
<td>Sun</td>
|
|
||||||
<td>Total</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Worked hours</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Monday/workhours">
|
|
||||||
<xsl:value-of select="Monday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Tuesday/workhours">
|
|
||||||
<xsl:value-of select="Tuesday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Wednesday/workhours">
|
|
||||||
<xsl:value-of select="Wednesday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Thursday/workhours">
|
|
||||||
<xsl:value-of select="Thursday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Friday/workhours">
|
|
||||||
<xsl:value-of select="Friday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Saturday/workhours">
|
|
||||||
<xsl:value-of select="Saturday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="Sunday/workhours">
|
|
||||||
<xsl:value-of select="Sunday/workhours" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>0h00</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<xsl:value-of select="total/worked" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</blockTable>
|
|
||||||
<xsl:if test="position() != last()">
|
|
||||||
<blockTable colWidths="24cm" style="week">
|
|
||||||
<tr>
|
|
||||||
<td colspan="6"></td>
|
|
||||||
</tr>
|
|
||||||
</blockTable>
|
|
||||||
</xsl:if>
|
|
||||||
</xsl:for-each>
|
|
||||||
<xsl:if test="position() != last()">
|
|
||||||
<pageBreak/>
|
|
||||||
</xsl:if>
|
|
||||||
</xsl:template>
|
|
||||||
</xsl:stylesheet>
|
|
|
@ -1,11 +1,3 @@
|
||||||
-
|
|
||||||
Print the HR Attendance Report By Month through the wizard
|
|
||||||
-
|
|
||||||
!python {model: hr.employee}: |
|
|
||||||
from openerp.tools import test_reports
|
|
||||||
ctx = {'model': 'hr.employee','active_ids': [ref('hr.employee_fp'),ref('hr.employee_qdp'),ref('hr.employee_al')]}
|
|
||||||
data_dict = {}
|
|
||||||
test_reports.try_report_action(cr, uid, 'action_hr_attendance_month',wiz_data=data_dict, context=ctx, our_module='hr_attendance')
|
|
||||||
-
|
-
|
||||||
Print HR Attendance Error Report through the wizard
|
Print HR Attendance Error Report through the wizard
|
||||||
-
|
-
|
||||||
|
|
|
@ -20,7 +20,5 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import hr_attendance_error
|
import hr_attendance_error
|
||||||
import hr_attendance_byweek
|
|
||||||
import hr_attendance_bymonth
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
###############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
from openerp.osv import osv, fields
|
|
||||||
|
|
||||||
class hr_attendance_bymonth(osv.osv_memory):
|
|
||||||
_name = 'hr.attendance.month'
|
|
||||||
_description = 'Print Monthly Attendance Report'
|
|
||||||
_columns = {
|
|
||||||
'month': fields.selection([(1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')], 'Month', required=True),
|
|
||||||
'year': fields.integer('Year', required=True)
|
|
||||||
}
|
|
||||||
_defaults = {
|
|
||||||
'month': lambda *a: time.gmtime()[1],
|
|
||||||
'year': lambda *a: time.gmtime()[0],
|
|
||||||
}
|
|
||||||
|
|
||||||
def print_report(self, cr, uid, ids, context=None):
|
|
||||||
datas = {
|
|
||||||
'ids': [],
|
|
||||||
'active_ids': context['active_ids'],
|
|
||||||
'model': 'hr.employee',
|
|
||||||
'form': self.read(cr, uid, ids)[0]
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
'type': 'ir.actions.report.xml',
|
|
||||||
'report_name': 'hr.attendance.bymonth',
|
|
||||||
'datas': datas,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
<record id="view_hr_attendance_month" model="ir.ui.view">
|
|
||||||
<field name="name">Attendances Report Monthly</field>
|
|
||||||
<field name="model">hr.attendance.month</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<form string="Print Attendance Report Monthly" version="7.0">
|
|
||||||
<group col="4">
|
|
||||||
<field name="month"/>
|
|
||||||
<field name="year"/>
|
|
||||||
</group>
|
|
||||||
<footer>
|
|
||||||
<button name="print_report" string="Print" type="object" class="oe_highlight"/>
|
|
||||||
or
|
|
||||||
<button string="Cancel" class="oe_link" special="cancel" />
|
|
||||||
</footer>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="action_hr_attendance_month" model="ir.actions.act_window">
|
|
||||||
<field name="name">Attendances By Month</field>
|
|
||||||
<field name="type">ir.actions.act_window</field>
|
|
||||||
<field name="res_model">hr.attendance.month</field>
|
|
||||||
<field name="view_type">form</field>
|
|
||||||
<field name="view_mode">form</field>
|
|
||||||
<field name="target">new</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record model="ir.values" id="hr_attendance_month_values">
|
|
||||||
<field name="model_id" ref="hr.model_hr_employee" />
|
|
||||||
<field name="name">Attendances By Month</field>
|
|
||||||
<field name="key2">client_print_multi</field>
|
|
||||||
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_hr_attendance_month'))" />
|
|
||||||
<field name="key">action</field>
|
|
||||||
<field name="model">hr.employee</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
|
@ -1,53 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
|
|
||||||
from openerp.osv import fields, osv
|
|
||||||
|
|
||||||
class hr_attendance_byweek(osv.osv_memory):
|
|
||||||
_name = 'hr.attendance.week'
|
|
||||||
_description = 'Print Week Attendance Report'
|
|
||||||
_columns = {
|
|
||||||
'init_date': fields.date('Starting Date', required=True),
|
|
||||||
'end_date': fields.date('Ending Date', required=True)
|
|
||||||
}
|
|
||||||
_defaults = {
|
|
||||||
'init_date': (datetime.today() - relativedelta(days=datetime.date(datetime.today()).weekday())).strftime('%Y-%m-%d'),
|
|
||||||
'end_date': (datetime.today() + relativedelta(days=6 - datetime.date(datetime.today()).weekday())).strftime('%Y-%m-%d'),
|
|
||||||
}
|
|
||||||
|
|
||||||
def print_report(self, cr, uid, ids, context=None):
|
|
||||||
datas = {
|
|
||||||
'ids': [],
|
|
||||||
'active_ids': context['active_ids'],
|
|
||||||
'model': 'hr.employee',
|
|
||||||
'form': self.read(cr, uid, ids)[0]
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
'type': 'ir.actions.report.xml',
|
|
||||||
'report_name': 'hr.attendance.allweeks',
|
|
||||||
'datas': datas,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
|
@ -1,41 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
<record id="view_hr_attendance_week" model="ir.ui.view">
|
|
||||||
<field name="name">Attendances Report Weekly</field>
|
|
||||||
<field name="model">hr.attendance.week</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<form string="Print Attendance Report Weekly" version="7.0">
|
|
||||||
<group>
|
|
||||||
<field name="init_date"/>
|
|
||||||
<field name="end_date"/>
|
|
||||||
</group>
|
|
||||||
<footer>
|
|
||||||
<button name="print_report" string="Print" type="object" class="oe_highlight"/>
|
|
||||||
or
|
|
||||||
<button string="Cancel" class="oe_link" special="cancel" />
|
|
||||||
</footer>
|
|
||||||
</form>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record id="action_hr_attendance_week" model="ir.actions.act_window">
|
|
||||||
<field name="name">Attendances By Week</field>
|
|
||||||
<field name="type">ir.actions.act_window</field>
|
|
||||||
<field name="res_model">hr.attendance.week</field>
|
|
||||||
<field name="view_type">form</field>
|
|
||||||
<field name="view_mode">form</field>
|
|
||||||
<field name="target">new</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<record model="ir.values" id="hr_attendance_week_values">
|
|
||||||
<field name="model_id" ref="hr.model_hr_employee" />
|
|
||||||
<field name="name">Attendances By Week</field>
|
|
||||||
<field name="key2">client_print_multi</field>
|
|
||||||
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_hr_attendance_week'))" />
|
|
||||||
<field name="key">action</field>
|
|
||||||
<field name="model">hr.employee</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
Loading…
Reference in New Issue