[MERGE][IMP] hr_timesheet: remove unattainable reports; hr_attendance: replace reports by a graphview

bzr revid: sle@openerp.com-20140429125300-s6ce4vlua357itdq
This commit is contained in:
Simon Lejeune 2014-04-29 14:53:00 +02:00
commit bc23005658
27 changed files with 54 additions and 1441 deletions

View File

@ -39,8 +39,6 @@ actions(Sign in/Sign out) performed by them.
'security/ir.model.access.csv',
'hr_attendance_view.xml',
'hr_attendance_report.xml',
'wizard/hr_attendance_bymonth_view.xml',
'wizard/hr_attendance_byweek_view.xml',
'wizard/hr_attendance_error_view.xml',
'res_config_view.xml',
'views/report_attendanceerrors.xml',

View File

@ -20,10 +20,12 @@
##############################################################################
import time
from datetime import datetime
from openerp.osv import fields, osv
from openerp.tools.translate import _
class hr_action_reason(osv.osv):
_name = "hr.action.reason"
_description = "Action Reason"
@ -40,14 +42,32 @@ def _employee_get(obj, cr, uid, context=None):
ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid)], context=context)
return ids and ids[0] or False
class hr_attendance(osv.osv):
_name = "hr.attendance"
_description = "Attendance"
def _day_compute(self, cr, uid, ids, fieldnames, args, context=None):
res = dict.fromkeys(ids, '')
def _worked_hours_compute(self, cr, uid, ids, fieldnames, args, context=None):
"""For each hr.attendance record of action sign-in: assign 0.
For each hr.attendance record of action sign-out: assign number of hours since last sign-in.
"""
res = {}
for obj in self.browse(cr, uid, ids, context=context):
res[obj.id] = time.strftime('%Y-%m-%d', time.strptime(obj.name, '%Y-%m-%d %H:%M:%S'))
if obj.action == 'sign_in':
res[obj.id] = 0
elif obj.action == 'sign_out':
# Get the associated sign-in
last_signin_id = self.search(cr, uid, [
('employee_id', '=', obj.employee_id.id),
('name', '<', obj.name), ('action', '=', 'sign_in')
], limit=1, order='name DESC')
last_signin = self.browse(cr, uid, last_signin_id, context=context)[0]
# Compute time elapsed between sign-in and sign-out
last_signin_datetime = datetime.strptime(last_signin.name, '%Y-%m-%d %H:%M:%S')
signout_datetime = datetime.strptime(obj.name, '%Y-%m-%d %H:%M:%S')
workedhours_datetime = (signout_datetime - last_signin_datetime)
res[obj.id] = ((workedhours_datetime.seconds) / 60) / 60
return res
_columns = {
@ -55,7 +75,7 @@ class hr_attendance(osv.osv):
'action': fields.selection([('sign_in', 'Sign In'), ('sign_out', 'Sign Out'), ('action','Action')], 'Action', required=True),
'action_desc': fields.many2one("hr.action.reason", "Action Reason", domain="[('action_type', '=', action)]", help='Specifies the reason for Signing In/Signing Out in case of extra hours.'),
'employee_id': fields.many2one('hr.employee', "Employee", required=True, select=True),
'day': fields.function(_day_compute, type='char', string='Day', store=True, select=1, size=32),
'worked_hours': fields.function(_worked_hours_compute, type='float', string='Worked Hours', store=True),
}
_defaults = {
'name': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), #please don't remove the lambda, if you remove it then the current time will not change
@ -110,7 +130,7 @@ class hr_employee(osv.osv):
for res in cr.fetchall():
result[res[1]] = res[0] == 'sign_in' and 'present' or 'absent'
return result
def _last_sign(self, cr, uid, ids, name, args, context=None):
result = {}
if not ids:

View File

@ -40,7 +40,6 @@
<field name="employee_id"/>
<field name="name"/>
<field name="action"/>
<field name="day" invisible="1"/>
</tree>
</field>
</record>
@ -53,17 +52,30 @@
<field name="name" string="Attendance"/>
<field name="action"/>
<filter icon="terp-go-today" string="Today" name="today" domain="[('name','&gt;=',current_date),('name','&lt;=',current_date)]" />
<filter string="Current Month" domain="[('name','&gt;=', datetime.datetime.now().strftime('%Y-%m-01'))]" />
<separator/>
<filter icon="terp-stock_align_left_24" string="My Attendance" domain="[('employee_id.user_id.id', '=', uid)]" />
<field name="employee_id"/>
<group expand="0" string="Group By...">
<filter name="employee" string="Employee" icon="terp-personal" domain="[]" context="{'group_by':'employee_id'}"/>
<filter string="Day" icon="terp-go-today" domain="[]" context="{'group_by':'day'}"/>
<filter name="name" string="Date" icon="terp-personal" domain="[]" context="{'group_by':'name'}"/>
</group>
</search>
</field>
</record>
<record id="view_hr_attendance_graph" model="ir.ui.view">
<field name="name">hr.attendance.graph</field>
<field name="model">hr.attendance</field>
<field name="arch" type="xml">
<graph string="Attendance" type="pivot">
<field name="employee_id" type="row"/>
<field name="name" type="col"/>
<field name="worked_hours" type="measure"/>
</graph>
</field>
</record>
<record id="open_view_attendance" model="ir.actions.act_window">
<field name="name">Attendances</field>
<field name="res_model">hr.attendance</field>
@ -74,12 +86,27 @@
<field name="help">The Time Tracking functionality aims to manage employee attendances from Sign in/Sign out actions. You can also link this feature to an attendance device using OpenERP's web service features.</field>
</record>
<record id="action_hr_attendance_graph" model="ir.actions.act_window">
<field name="name">Attendance Analysis</field>
<field name="res_model">hr.attendance</field>
<field name="view_type">form</field>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_hr_attendance_graph"/>
</record>
<menuitem id="menu_hr_time_tracking" name="Time Tracking" parent="hr.menu_hr_root" sequence="5" groups="base.group_user,base.group_hr_user,base.group_hr_manager"/>
<menuitem id="menu_hr_attendance" name="Attendances" parent="hr.menu_hr_root" sequence="10" groups="base.group_hr_attendance"/>
<menuitem action="open_view_attendance" id="menu_open_view_attendance" parent="menu_hr_attendance" sequence="20" groups="base.group_hr_attendance"/>
<menuitem
action="action_hr_attendance_graph"
id="menu_hr_attendance_graph"
parent="hr.menu_hr_reporting"
sequence="3"
/>
<record id="edit_attendance_reason" model="ir.ui.view">
<field name="name">hr.action.reason.form</field>
<field name="model">hr.action.reason</field>

View File

@ -20,7 +20,5 @@
##############################################################################
import attendance_errors
import attendance_by_month
import timesheet
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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:

View File

@ -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>

View File

@ -1,36 +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:template name="first_page_graphics_corporation">
<!--logo-->
<fill color="black"/>
<stroke color="black"/>
<setFont name="DejaVuSans" size="8"/>
<drawString x="1.3cm" y="19.5cm"><xsl:value-of select="//report/header/date"/></drawString>
<setFont name="DejaVuSans-Bold" size="10"/>
<drawString x="13.8cm" y="19.5cm"><xsl:value-of select="//report/header/company"/></drawString>
<stroke color="#000000"/>
<lines>1.3cm 19.3cm 28.5cm 19.3cm</lines>
</xsl:template>
<xsl:template name="other_pages_graphics_corporation">
<!--logo-->
<fill color="black"/>
<stroke color="black"/>
<setFont name="DejaVuSans" size="8"/>
<drawString x="1.3cm" y="19.5cm"><xsl:value-of select="//report/header/date"/></drawString>
<setFont name="DejaVuSans-Bold" size="10"/>
<drawString x="27.8cm" y="19.5cm"><xsl:value-of select="//report/header/company"/></drawString>
<stroke color="#000000"/>
<lines>1.3cm 19.3cm 28.5cm 19.3cm</lines>
</xsl:template>
<xsl:template name="first_page_frames">
<frame id="col1" x1="2.0cm" y1="2.5cm" width="24.7cm" height="17cm"/>
</xsl:template>
<xsl:template name="other_pages_frames">
<frame id="col1" x1="2.0cm" y1="2.5cm" width="24.7cm" height="17cm"/>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,37 +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:template name="first_page_graphics_report"/>
<xsl:template name="other_pages_graphics_report"/>
<xsl:template name="rml">
<document filename="example.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_page">
<pageGraphics>
<xsl:call-template name="first_page_graphics_corporation"/>
</pageGraphics>
<xsl:call-template name="first_page_frames"/>
</pageTemplate>
<pageTemplate id="other_pages">
<pageGraphics>
<xsl:call-template name="other_pages_graphics_corporation"/>
</pageGraphics>
<xsl:call-template name="other_pages_frames"/>
</pageTemplate>
</template>
<stylesheet>
<xsl:call-template name="stylesheet"/>
</stylesheet>
<story>
<xsl:call-template name="story"/>
</story>
</document>
</xsl:template>
</xsl:stylesheet>

View File

@ -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

View File

@ -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>

View File

@ -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
-

View File

@ -20,7 +20,5 @@
##############################################################################
import hr_attendance_error
import hr_attendance_byweek
import hr_attendance_bymonth
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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:

View File

@ -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>

View File

@ -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:

View File

@ -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>

View File

@ -21,7 +21,6 @@
import hr_timesheet
import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -46,8 +46,6 @@ up a management by affair.
'security/ir.model.access.csv',
'security/hr_timesheet_security.xml',
'hr_timesheet_view.xml',
'hr_timesheet_report.xml',
'hr_timesheet_wizard.xml',
'process/hr_timesheet_process.xml',
'wizard/hr_timesheet_sign_in_out_view.xml',
'hr_timesheet_installer.xml',

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<report auto="False" id="report_user_timesheet" menu="False" model="hr.employee" name="hr.analytical.timesheet" string="Employee timesheet" xsl="hr_timesheet/report/user_timesheet.xsl"/>
<report auto="False" id="report_users_timesheet" menu="False" model="hr.employee" name="hr.analytical.timesheet_users" string="Employees Timesheet" xsl="hr_timesheet/report/users_timesheet.xsl"/>
</data>
</openerp>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
</data>
</openerp>

View File

@ -1,26 +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 user_timesheet
import users_timesheet
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,36 +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:template name="first_page_graphics_corporation">
<!--logo-->
<fill color="black"/>
<stroke color="black"/>
<setFont name="DejaVuSans" size="8"/>
<drawString x="1.3cm" y="19.5cm"><xsl:value-of select="//report/header/date"/></drawString>
<setFont name="DejaVuSans-Bold" size="10"/>
<drawString x="13.8cm" y="19.5cm"><xsl:value-of select="//report/header/company"/></drawString>
<stroke color="#000000"/>
<lines>1.3cm 19.3cm 28.5cm 19.3cm</lines>
</xsl:template>
<xsl:template name="other_pages_graphics_corporation">
<!--logo-->
<fill color="black"/>
<stroke color="black"/>
<setFont name="DejaVuSans" size="8"/>
<drawString x="1.3cm" y="19.5cm"><xsl:value-of select="//report/header/date"/></drawString>
<setFont name="DejaVuSans-Bold" size="10"/>
<drawString x="27.8cm" y="19.5cm"><xsl:value-of select="//report/header/company"/></drawString>
<stroke color="#000000"/>
<lines>1.3cm 19.3cm 28.5cm 19.3cm</lines>
</xsl:template>
<xsl:template name="first_page_frames">
<frame id="col1" x1="2.0cm" y1="2.5cm" width="24.7cm" height="17cm"/>
</xsl:template>
<xsl:template name="other_pages_frames">
<frame id="col1" x1="2.0cm" y1="2.5cm" width="24.7cm" height="17cm"/>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,37 +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:template name="first_page_graphics_report"/>
<xsl:template name="other_pages_graphics_report"/>
<xsl:template name="rml">
<document filename="example.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_page">
<pageGraphics>
<xsl:call-template name="first_page_graphics_corporation"/>
</pageGraphics>
<xsl:call-template name="first_page_frames"/>
</pageTemplate>
<pageTemplate id="other_pages">
<pageGraphics>
<xsl:call-template name="other_pages_graphics_corporation"/>
</pageGraphics>
<xsl:call-template name="other_pages_frames"/>
</pageTemplate>
</template>
<stylesheet>
<xsl:call-template name="stylesheet"/>
</stylesheet>
<story>
<xsl:call-template name="story"/>
</story>
</document>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,124 +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 datetime
import time
import openerp
from openerp.report.interface import report_rml
from openerp.report.interface import toxml
from openerp.tools.translate import _
from openerp.report import report_sxw
from openerp.tools import ustr
from openerp.tools import to_xml
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 get_month_name(self, cr, uid, month, context=None):
_months = {1:_("January"), 2:_("February"), 3:_("March"), 4:_("April"), 5:_("May"), 6:_("June"), 7:_("July"), 8:_("August"), 9:_("September"), 10:_("October"), 11:_("November"), 12:_("December")}
return _months[month]
def get_weekday_name(self, cr, uid, weekday, context=None):
_weekdays = {1:_('Mon'), 2:_('Tue'), 3:_('Wed'), 4:_('Thu'), 5:_('Fri'), 6:_('Sat'), 7:_('Sun')}
return _weekdays[weekday]
def create_xml(self, cr, uid, ids, data, context):
registry = openerp.registry(cr.dbname)
# Get the user id from the selected employee record
emp_id = data['form']['employee_id']
emp_obj = registry['hr.employee']
user_id = emp_obj.browse(cr, uid, emp_id).user_id.id
empl_name = emp_obj.browse(cr, uid, emp_id).name
# Computing the dates (start of month: som, and end of month: eom)
som = datetime.date(data['form']['year'], data['form']['month'], 1)
eom = som + datetime.timedelta(lengthmonth(som.year, som.month))
date_xml = ['<date month="%s" year="%d" />' % (self.get_month_name(cr, uid, som.month, context=context), som.year), '<days>']
date_xml += ['<day number="%d" name="%s" weekday="%d" />' % (x, self.get_weekday_name(cr, uid, som.replace(day=x).weekday()+1, context=context), som.replace(day=x).weekday()+1) for x in range(1, lengthmonth(som.year, som.month)+1)]
date_xml.append('</days>')
date_xml.append('<cols>2.5cm%s,2cm</cols>\n' % (',0.7cm' * lengthmonth(som.year, som.month)))
# Sum attendence by account, then by day
accounts = {}
header_xml = ''
if user_id:
# Computing the attendence by analytical account
cr.execute(
"select line.date, (unit_amount / unit.factor) as amount, account_id, account.name "\
"from account_analytic_line as line, hr_analytic_timesheet as hr, "\
"account_analytic_account as account, product_uom as unit "\
"where hr.line_id=line.id and line.account_id=account.id "\
"and product_uom_id = unit.id "\
"and line.user_id=%s and line.date >= %s and line.date < %s "
"order by line.date",
(user_id, som.strftime('%Y-%m-%d'), eom.strftime('%Y-%m-%d')))
for presence in cr.dictfetchall():
day = int(presence['date'][-2:])
account = accounts.setdefault((presence['account_id'], presence['name']), {})
account[day] = account.get(day, 0.0) + presence['amount']
xml = '''
<time-element date="%s">
<amount>%.2f</amount>
</time-element>
'''
rpt_obj = registry['hr.employee']
rml_obj = report_sxw.rml_parse(cr, uid, rpt_obj._name,context)
if user_id:
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,user_id).company_id.name))
account_xml = []
for account, telems in accounts.iteritems():
aid, aname = account
aname = registry['account.analytic.account'].name_get(cr, uid, [aid], context)
aname = aname[0][1]
account_xml.append('<account id="%d" name="%s">' % (aid, toxml(aname)))
account_xml.append('\n'.join([xml % (day, amount) for day, amount in telems.iteritems()]))
account_xml.append('</account>')
# Computing the xml
xml = '''<?xml version="1.0" encoding="UTF-8" ?>
<report>
%s
<employee>%s</employee>
%s
</report>
''' % (header_xml, ustr(toxml(empl_name)), '\n'.join(date_xml) + '\n'.join(account_xml))
return xml
report_custom('report.hr.analytical.timesheet', 'hr.employee', '', 'addons/hr_timesheet/report/user_timesheet.xsl')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,123 +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="custom_default.xsl"/>
<xsl:import href="custom_rml.xsl"/>
<xsl:template match="/">
<xsl:call-template name="rml"/>
</xsl:template>
<xsl:template name="stylesheet">
<paraStyle name="normal" fontName="Helvetica" fontSize="6" alignment="left" />
<paraStyle name="normal-title" fontName="Helvetica" fontSize="6" />
<paraStyle name="title" fontName="Helvetica" fontSize="18" alignment="center" />
<paraStyle name="employee" fontName="Helvetica-Oblique" fontSize="10" textColor="blue" />
<paraStyle name="glande" textColor="red" fontSize="7" fontName="Helvetica"/>
<paraStyle name="normal_people" textColor="green" fontSize="7" fontName="Helvetica"/>
<paraStyle name="esclave" textColor="purple" fontSize="7" fontName="Helvetica"/>
<blockTableStyle id="month">
<blockAlignment value="CENTER" start="1,0" stop="-1,-1" />
<blockFont name="Helvetica" size="8" start="0,0" stop="-1,1"/>
<blockFont name="Helvetica" size="6" start="0,2" stop="-2,-2"/>
<blockFont name="Helvetica-BoldOblique" size="8" start="0,-1" stop="-1,-1"/>
<blockBackground colorName="#AAAAAA" start="1,0" stop="-2,1"/>
<xsl:for-each select="/report/days/day[@weekday=6 or @weekday=7]">
<xsl:variable name="col" select="attribute::number" />
<blockBackground>
<xsl:attribute name="colorName">lightgrey</xsl:attribute>
<xsl:attribute name="start">
<xsl:value-of select="$col" />
<xsl:text>,0</xsl:text>
</xsl:attribute>
<xsl:attribute name="stop">
<xsl:value-of select="$col" />
<xsl:text>,-1</xsl:text>
</xsl:attribute>
</blockBackground>
</xsl:for-each>
<lineStyle kind="LINEABOVE" colorName="black" start="0,0" stop="-1,-1" />
<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,-1" stop="-1,-1"/>
<blockValign value="TOP"/>
</blockTableStyle>
</xsl:template>
<xsl:template name="story">
<spacer length="1cm" />
<para style="title" t="1">Timesheet by Employee</para>
<spacer length="1cm" />
<para style="employee"><xsl:value-of select="/report/employee" /></para>
<spacer length="1cm" />
<blockTable>
<xsl:attribute name="style">month</xsl:attribute>
<xsl:attribute name="colWidths"><xsl:value-of select="report/cols" /></xsl:attribute>
<tr>
<td><xsl:value-of select="report/date/attribute::year" /></td>
<xsl:for-each select="report/days/day">
<td>
<xsl:value-of select="attribute::name" />
</td>
</xsl:for-each>
<td></td>
</tr>
<tr>
<td><xsl:value-of select="report/date/attribute::month" /></td>
<xsl:for-each select="report/days/day">
<td>
<xsl:value-of select="attribute::number" />
</td>
</xsl:for-each>
<td t="1">Total</td>
</tr>
<xsl:apply-templates select="report/account"/>
<tr>
<td t="1">Sum</td>
<xsl:for-each select="report/days/day">
<xsl:variable name="today" select="attribute::number" />
<td>
<para style="normal">
<xsl:choose>
<xsl:when test="sum(//time-element[@date=$today]) &lt; 7.5">
<xsl:attribute name="style">glande</xsl:attribute>
</xsl:when>
<xsl:when test="sum(//time-element[@date=$today]) &lt; 8.5 and sum(//time-element[@date=$today]) &gt;= 7.5">
<xsl:attribute name="style">normal_people</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="style">esclave</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="format-number(sum(//time-element[@date=$today]),'##.##')" />
</para>
</td>
</xsl:for-each>
<td>
<xsl:value-of select="format-number(sum(//time-element),'##.##')" />
</td>
</tr>
</blockTable>
</xsl:template>
<xsl:template match="account">
<xsl:variable name="aid" select="attribute::id" />
<tr>
<td>
<para style="normal-title"><xsl:value-of select="attribute::name" /></para>
</td>
<xsl:for-each select="/report/days/day">
<xsl:variable name="today" select="attribute::number" />
<td>
<para style="normal"><xsl:value-of select="//account[@id=$aid]/time-element[@date=$today]" /></para>
</td>
</xsl:for-each>
<td>
<para style="normal"><xsl:value-of select="format-number(sum(//account[@id=$aid]/time-element),'##.##')" /></para>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,123 +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 datetime
import time
import openerp
from openerp.report.interface import report_rml
from openerp.report.interface import toxml
from openerp.tools.translate import _
from openerp.report import report_sxw
from openerp.tools import ustr
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]
def emp_create_xml(cr, id, som, eom, emp):
# Computing the attendence by analytical account
cr.execute(
"select line.date, (unit_amount / unit.factor) as amount "\
"from account_analytic_line as line, hr_analytic_timesheet as hr, "\
"product_uom as unit "\
"where hr.line_id=line.id "\
"and product_uom_id = unit.id "\
"and line.user_id=%s and line.date >= %s and line.date < %s "
"order by line.date",
(id, som.strftime('%Y-%m-%d'), eom.strftime('%Y-%m-%d')))
# Sum by day
month = {}
for presence in cr.dictfetchall():
day = int(presence['date'][-2:])
month[day] = month.get(day, 0.0) + presence['amount']
xml = '''
<time-element date="%s">
<amount>%.2f</amount>
</time-element>
'''
time_xml = ([xml % (day, amount) for day, amount in month.iteritems()])
# Computing the xml
xml = '''
<employee id="%d" name="%s">
%s
</employee>
''' % (id, toxml(emp), '\n'.join(time_xml))
return xml
class report_custom(report_rml):
def get_month_name(self, cr, uid, month, context=None):
_months = {1:_("January"), 2:_("February"), 3:_("March"), 4:_("April"), 5:_("May"), 6:_("June"), 7:_("July"), 8:_("August"), 9:_("September"), 10:_("October"), 11:_("November"), 12:_("December")}
return _months[month]
def get_weekday_name(self, cr, uid, weekday, context=None):
_weekdays = {1:_('Mon'), 2:_('Tue'), 3:_('Wed'), 4:_('Thu'), 5:_('Fri'), 6:_('Sat'), 7:_('Sun')}
return _weekdays[weekday]
def create_xml(self, cr, uid, ids, data, context):
registry = openerp.registry(cr.dbname)
# Computing the dates (start of month: som, and end of month: eom)
som = datetime.date(data['form']['year'], data['form']['month'], 1)
eom = som + datetime.timedelta(lengthmonth(som.year, som.month))
date_xml = ['<date month="%s" year="%d" />' % (self.get_month_name(cr, uid, som.month, context=context), som.year), '<days>']
date_xml += ['<day number="%d" name="%s" weekday="%d" />' % (x, self.get_weekday_name(cr, uid, som.replace(day=x).weekday()+1, context=context), som.replace(day=x).weekday()+1) for x in range(1, lengthmonth(som.year, som.month)+1)]
date_xml.append('</days>')
date_xml.append('<cols>2.5cm%s,2cm</cols>\n' % (',0.7cm' * lengthmonth(som.year, som.month)))
emp_xml=''
emp_obj = registry['hr.employee']
for id in data['form']['employee_ids']:
user = emp_obj.browse(cr, uid, id).user_id.id
empl_name = emp_obj.browse(cr, uid, id).name
if user:
emp_xml += emp_create_xml(cr, user, som, eom, empl_name)
# Computing the xml
#Without this, report don't show non-ascii characters (TO CHECK)
date_xml = '\n'.join(date_xml)
rpt_obj = emp_obj
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")),toxml(registry['res.users'].browse(cr,uid,uid).company_id.name))
xml='''<?xml version="1.0" encoding="UTF-8" ?>
<report>
%s
%s
%s
</report>
''' % (header_xml,date_xml, ustr(emp_xml))
return xml
report_custom('report.hr.analytical.timesheet_users', 'hr.employee', '', 'addons/hr_timesheet/report/users_timesheet.xsl')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,114 +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="custom_default.xsl"/>
<xsl:import href="custom_rml.xsl"/>
<xsl:template match="/">
<xsl:call-template name="rml" />
</xsl:template>
<xsl:template name="stylesheet">
<paraStyle name="normal" fontName="Helvetica" fontSize="6" alignment="center" />
<paraStyle name="normal-title" fontName="Helvetica" fontSize="6" />
<paraStyle name="title" fontName="Helvetica" fontSize="18" alignment="center" />
<paraStyle name="employee" fontName="Helvetica-Oblique" fontSize="10" textColor="blue" />
<paraStyle name="glande" textColor="red" fontSize="7" fontName="Helvetica"/>
<paraStyle name="normal_people" textColor="green" fontSize="7" fontName="Helvetica"/>
<paraStyle name="esclave" textColor="purple" fontSize="7" fontName="Helvetica"/>
<blockTableStyle id="month">
<blockAlignment value="CENTER" start="1,0" stop="-1,-1" />
<blockFont name="Helvetica" size="8" start="0,0" stop="-1,1"/>
<blockFont name="Helvetica" size="6" start="0,2" stop="-2,-2"/>
<blockFont name="Helvetica-BoldOblique" size="8" start="0,-1" stop="-1,-1"/>
<blockBackground colorName="#AAAAAA" start="1,0" stop="-2,1"/>
<xsl:for-each select="/report/days/day[@weekday=6 or @weekday=7]">
<xsl:variable name="col" select="attribute::number" />
<blockBackground>
<xsl:attribute name="colorName">lightgrey</xsl:attribute>
<xsl:attribute name="start">
<xsl:value-of select="$col" />
<xsl:text>,0</xsl:text>
</xsl:attribute>
<xsl:attribute name="stop">
<xsl:value-of select="$col" />
<xsl:text>,-1</xsl:text>
</xsl:attribute>
</blockBackground>
</xsl:for-each>
<lineStyle kind="LINEABOVE" colorName="black" start="0,0" stop="-1,-1" />
<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,-1" stop="-1,-1"/>
<blockValign value="TOP"/>
</blockTableStyle>
</xsl:template>
<xsl:template name="story">
<spacer length="1cm" />
<para style="title" t="1">Employees Timesheet</para>
<spacer length="1.5cm" />
<blockTable>
<xsl:attribute name="style">month</xsl:attribute>
<xsl:attribute name="colWidths"><xsl:value-of select="report/cols" /></xsl:attribute>
<tr>
<td><xsl:value-of select="report/date/attribute::year" /></td>
<xsl:for-each select="report/days/day">
<td>
<xsl:value-of select="attribute::name" />
</td>
</xsl:for-each>
<td></td>
</tr>
<tr>
<td><xsl:value-of select="report/date/attribute::month" /></td>
<xsl:for-each select="report/days/day">
<td>
<xsl:value-of select="attribute::number" />
</td>
</xsl:for-each>
<td t="1">Total</td>
</tr>
<xsl:apply-templates select="report/employee"/>
<xsl:for-each select="report/employee">
<xsl:variable name="id" select="attribute::id"/>
<tr>
<td><xsl:value-of select="attribute::name"/></td>
<xsl:for-each select="//report/days/day">
<xsl:variable name="today" select="attribute::number" />
<td>
<para>
<xsl:choose>
<xsl:when test="sum(//employee[@id=$id]/time-element[@date=$today]) &lt; 7.5">
<xsl:attribute name="style">glande</xsl:attribute>
</xsl:when>
<xsl:when test="sum(//employee[@id=$id]/time-element[@date=$today]) &lt; 8.5 and sum(//time-element[@date=$today]) &gt;= 7.5">
<xsl:attribute name="style">normal_people</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="style">esclave</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="format-number(sum(//employee[@id=$id]/time-element[@date=$today]), '##.##')" />
</para>
</td>
</xsl:for-each>
<td>
<xsl:value-of select="format-number(sum(//employee[@id=$id]/time-element),'##.##')"/>
</td>
</tr>
</xsl:for-each>
<tr>
<td t="1">Total</td>
<xsl:for-each select="report/days/day">
<xsl:variable name="today" select="attribute::number"/>
<td><xsl:value-of select="format-number(sum(//time-element[@date=$today]),'##.##')"/></td>
</xsl:for-each>
<td><xsl:value-of select="format-number(sum(//time-element),'##.##')"/></td>
</tr>
</blockTable>
</xsl:template>
</xsl:stylesheet>