Port module hr_holidays_usability to v8

This commit is contained in:
Alexis de Lattre
2015-06-10 19:00:37 +02:00
parent ac91927ea1
commit 21f657616b
8 changed files with 1107 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
HR Holidays Usability
=====================
This module adds what I consider the minimum usability level for the holiday management module in Odoo:
* By default, if you only use the official *hr_holidays* module, there the number of days is not automatically computed from the start date and end date. This module fixes it : it counts the number of days following a computation method that is defined on the object hr.holiday.status. It also replaces the datetime field for start/end dates by a date field plus a selection field to indicated morning/noon/evening.
* It depends on the OCA module *hr_public_holidays* to easily define the bank holidays per country. It takes those bank holidays into account when counting the number of days.
* It sends an email to the manager when the employee submits a holiday requests (with the employee in Cc) and it sends an email to the employee (with the manager in Cc) when the holiday request is validated/refused.
Known issues / Roadmap
======================
* Port to v8
Credits
=======
Contributors
------------
* Alexis de Lattre <alexis.delattre@akretion.com>

View File

@@ -0,0 +1,23 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# HR Holidays Usability module for Odoo
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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 . import hr_holidays

View File

@@ -0,0 +1,39 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# HR Holidays Usability module for Odoo
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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/>.
#
##############################################################################
{
'name': 'HR Holidays Usability',
'version': '0.1',
'category': 'Human Resources',
'license': 'AGPL-3',
'summary': 'Better usability for the management of holidays',
'description': '',
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['hr_holidays', 'hr_public_holidays'],
'data': [
'hr_holidays_view.xml',
'hr_holidays_mail.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,262 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# HR Holidays Usability module for Odoo
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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 openerp import models, fields, api, _
from openerp.exceptions import ValidationError
from datetime import datetime
from dateutil.relativedelta import relativedelta
import pytz
import logging
logger = logging.getLogger(__name__)
class HrHolidaysStatus(models.Model):
_inherit = 'hr.holidays.status'
vacation_compute_method = fields.Selection([
('worked', u'Jours ouvrés'),
('business', u'Jours ouvrables'),
# TODO find proper English translation
], string='Vacation Compute Method', required=True,
default='worked')
class HrHolidays(models.Model):
_inherit = 'hr.holidays'
_order = 'type desc, date_from desc'
# by default : type desc, date_from asc
# Idea :
# For allocation (type = add), we don't change anything:
# The user writes in the field number_of_days_temp and
# number_of_days = number_of_days_temp
# For leave (type = remove), we don't let users enter the number of days,
# we compute it for them
# -> new computed field "number_of_days_remove' that compute the number
# of days depending on the computation method defined on 'type'
# Redefine the field 'number_of_days' to take into accout
# 'number_of_days_remove' when type == remove (= number_of_days_remove * -1)
# change date time fields by date + selection morning/noon
# How do we set the dates :
# from : premier jour d'absence (et non dernier jour de présence)
# + time : morning/noon
# to : date de fin de congés (et non date de retour au travail)
# + time : noon/evening
# which computation methods on the 'hr.holidays.status':
# 1) jours ouvrés (sans compter les jours fériés)
# 2) jours ouvrables (quid des jours fériés ???) :
# il faut compter les samedis sauf les samedis fériés.
# Cas particulier : quand la personne prend le vendredi aprèm,
# il faut compter 1j (et non 0.5 ni 1.5)
# 3) malade : on compte tous les jours -> ptet pas nécessaire pour le moment
# 1 for 'unpaid leaves' + repos compensateur + congés conventionnels + maladie
# 1 or 2 for normal holidays
@api.one
@api.depends(
'vacation_date_from', 'vacation_time_from', 'vacation_date_to',
'vacation_time_to', 'number_of_days_temp', 'type', 'holiday_type',
'holiday_status_id.vacation_compute_method')
def _compute_number_of_days(self):
# depend on the holiday_status_id
hhpo = self.env['hr.holidays.public']
days = 0.0
if (
self.type == 'remove' and
self.holiday_type == 'employee' and
self.vacation_date_from and
self.vacation_time_from and
self.vacation_date_to and
self.vacation_time_to):
if self.holiday_status_id.vacation_compute_method == 'business':
business = True
else:
business = False
date_dt = start_date_dt = fields.Date.from_string(
self.vacation_date_from)
end_date_dt = fields.Date.from_string(
self.vacation_date_to)
while True:
# REGULAR COMPUTATION
# if it's a bank holidays, don't count
if hhpo.is_public_holiday(date_dt, self.employee_id.id):
logger.info(
"%s is a bank holiday, don't count", date_dt)
# it it's a saturday/sunday
elif date_dt.weekday() in (5, 6):
logger.info(
"%s is a saturday/sunday, don't count", date_dt)
else:
days += 1.0
# special case for friday when compute_method = business
if (
business and
date_dt.weekday() == 4 and
not hhpo.is_public_holiday(
date_dt + relativedelta(days=1),
self.employee_id.id)):
days += 1.0
# PARTICULAR CASE OF THE FIRST DAY
if date_dt == start_date_dt:
if self.vacation_time_from == 'noon':
if (
business and
date_dt.weekday() == 4 and
not hhpo.is_public_holiday(
date_dt + relativedelta(days=1),
self.employee_id.id)):
days -= 1.0 # result = 2 - 1 = 1
else:
days -= 0.5
# PARTICULAR CASE OF THE LAST DAY
if date_dt == end_date_dt:
if self.vacation_time_to == 'noon':
if (
business and
date_dt.weekday() == 4 and
not hhpo.is_public_holiday(
date_dt + relativedelta(days=1),
self.employee_id.id)):
days -= 1.5 # 2 - 1.5 = 0.5
else:
days -= 0.5
break
date_dt += relativedelta(days=1)
self.number_of_days_remove = days
# PASTE
if self.type == 'remove':
# read number_of_days_remove instead of number_of_days_temp
number_of_days = -days
else:
# for allocations, we read the native field number_of_days_temp
number_of_days = self.number_of_days_temp
self.number_of_days = number_of_days
vacation_date_from = fields.Date(
string='First Day of Vacation', track_visibility='onchange',
help="Enter the first day of vacation. For example, if "
"you leave one full calendar week, the first day of vacation "
"is Monday morning (and not Friday of the week before)")
vacation_time_from = fields.Selection([
('morning', 'Morning'),
('noon', 'Noon'),
], string="Start of Vacation", track_visibility='onchange',
default='morning',
help="For example, if you leave one full calendar week, "
"the first day of vacation is Monday Morning")
vacation_date_to = fields.Date(
string='Last Day of Vacation', track_visibility='onchange',
help="Enter the last day of vacation. For example, if you "
"leave one full calendar week, the last day of vacation is "
"Friday evening (and not Monday of the week after)")
vacation_time_to = fields.Selection([
('noon', 'Noon'),
('evening', 'Evening'),
], string="End of Vacation", track_visibility='onchange',
default='evening',
help="For example, if you leave one full calendar week, "
"the end of vacation is Friday Evening")
number_of_days_remove = fields.Float(
compute='_compute_number_of_days',
string="Number of Days of Vacation", readonly=True)
# number_of_days is a native field that I inherit
number_of_days = fields.Float(compute='_compute_number_of_days')
@api.one
@api.constrains(
'vacation_date_from', 'vacation_date_to', 'holiday_type', 'type')
def _check_vacation_dates(self):
hhpo = self.env['hr.holidays.public']
if self.type == 'remove':
if self.vacation_date_from > self.vacation_date_to:
raise ValidationError(
_('The first day cannot be after the last day !'))
elif (
self.vacation_date_from == self.vacation_date_to and
self.vacation_time_from == self.vacation_time_to):
raise ValidationError(
_("The start of vacation is exactly the "
"same as the end !"))
date_from_dt = fields.Date.from_string(
self.vacation_date_from)
if date_from_dt.weekday() in (5, 6):
raise ValidationError(
_("The first day of vacation cannot be a "
"saturday or sunday !"))
date_to_dt = fields.Date.from_string(
self.vacation_date_to)
if date_to_dt.weekday() in (5, 6):
raise ValidationError(
_("The last day of Vacation cannot be a "
"saturday or sunday !"))
if hhpo.is_public_holiday(date_from_dt, self.employee_id.id):
raise ValidationError(
_("The first day of vacation cannot be a "
"bank holiday !"))
if hhpo.is_public_holiday(date_to_dt, self.employee_id.id):
raise ValidationError(
_("The last day of vacation cannot be a "
"bank holiday !"))
@api.onchange('vacation_date_from', 'vacation_time_from')
def vacation_from(self):
hour = 0 # = morning
if self.vacation_time_from and self.vacation_time_from == 'noon':
hour = 12 # noon, LOCAL TIME
datetime_str = False
if self.vacation_date_from:
date_dt = fields.Date.from_string(self.vacation_date_from)
if self._context.get('tz'):
localtz = pytz.timezone(self._context['tz'])
else:
localtz = pytz.utc
datetime_dt = localtz.localize(datetime(
date_dt.year, date_dt.month, date_dt.day, hour, 0, 0))
# we give to odoo a datetime in UTC
datetime_str = fields.Datetime.to_string(
datetime_dt.astimezone(pytz.utc))
self.date_from = datetime_str
@api.onchange('vacation_date_to', 'vacation_time_to')
def vacation_to(self):
hour = 23 # = evening
if self.vacation_time_to and self.vacation_time_to == 'noon':
hour = 14 # Noon, LOCAL TIME
datetime_str = False
if self.vacation_date_to:
date_dt = fields.Date.from_string(self.vacation_date_to)
if self._context.get('tz'):
localtz = pytz.timezone(self._context['tz'])
else:
localtz = pytz.utc
datetime_dt = localtz.localize(datetime(
date_dt.year, date_dt.month, date_dt.day, hour, 0, 0))
# we give to odoo a datetime in UTC
datetime_str = fields.Datetime.to_string(
datetime_dt.astimezone(pytz.utc))
self.date_to = datetime_str

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="ir_actions_server_hr_holidays_confirm_mail" model="ir.actions.server">
<field name="name">Auto-email confirmed leave</field>
<field name="code">context.update({
'wkf_tracker': 'submitted',
'dbname': cr.dbname,
})
template_id=self.pool.get('ir.model.data').get_object_reference(cr, uid, 'hr_holidays_usability', 'email_template_hr_holidays')[1]
self.pool.get('email.template').send_mail(cr, uid, template_id, object.id, force_send=True, context=context)</field>
<field name="state">code</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="hr_holidays.model_hr_holidays"/>
<field name="condition">True</field>
</record>
<record id="ir_actions_server_hr_holidays_validate_mail" model="ir.actions.server">
<field name="name">Auto-email validated leave</field>
<field name="code">context.update({
'wkf_tracker': 'validated',
'dbname': cr.dbname,
})
template_id=self.pool.get('ir.model.data').get_object_reference(cr, uid, 'hr_holidays_usability', 'email_template_hr_holidays')[1]
self.pool.get('email.template').send_mail(cr, uid, template_id, object.id, force_send=True, context=context)</field>
<field name="state">code</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="hr_holidays.model_hr_holidays"/>
<field name="condition">True</field>
</record>
<record id="ir_actions_server_hr_holidays_refuse_mail" model="ir.actions.server">
<field name="name">Auto-email refused leave</field>
<field name="code">context.update({
'wkf_tracker': 'refused',
'dbname': cr.dbname,
})
template_id=self.pool.get('ir.model.data').get_object_reference(cr, uid, 'hr_holidays_usability', 'email_template_hr_holidays')[1]
self.pool.get('email.template').send_mail(cr, uid, template_id, object.id, force_send=True, context=context)</field>
<field name="state">code</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="hr_holidays.model_hr_holidays"/>
<field name="condition">True</field>
</record>
<record id="hr_holidays.act_confirm" model="workflow.activity">
<field name="action_id" ref="ir_actions_server_hr_holidays_confirm_mail"/>
</record>
<record id="hr_holidays.act_validate" model="workflow.activity">
<field name="action_id" ref="ir_actions_server_hr_holidays_validate_mail"/>
</record>
<record id="hr_holidays.act_refuse" model="workflow.activity">
<field name="action_id" ref="ir_actions_server_hr_holidays_refuse_mail"/>
</record>
<record id="email_template_hr_holidays" model="email.template">
<field name="name">Holidays email template</field>
<field name="model_id" ref="hr_holidays.model_hr_holidays"/>
<field name="email_from">${user.company_id.email}</field>
<field name="email_to">${object.employee_id.parent_id.user_id.email or ''}</field>
<field name="email_cc">${object.employee_id.user_id.email or ''}</field>
<field name="reply_to">${user.email or ''}</field>
<field name="subject">${ctx.get('dbname') and 'prod' not in ctx.get('dbname') and '[TEST]' or ''}[${object.type == 'remove' and 'Leave' or 'Allocation'} ${ctx.get('wkf_tracker')}] ${object.name or ''} - ${object.employee_id.name or ''}</field>
<field name="auto_delete" eval="False"/>
<field name="lang">${user.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
% if ctx.get('dbname') and 'prod' not in ctx.get('dbname'):
<p>WARNING : THIS IS A TEST E-MAIL sent from a test OpenERP database (${ctx.get('dbname')}). Do not take into account !</p>
% endif
<p>The following ${object.type == 'remove' and 'leave request' or 'ALLOCATION request (i.e. credit of days, not debit !)'} has been ${ctx.get('wkf_tracker') or 'ERROR'} today in OpenERP by ${user.name or ''} :</p>
<ul>
<li>Employee : ${object.employee_id.name or ''}</li>
% if object.employee_id.parent_id:
<li>Employee's manager : ${object.employee_id.parent_id.name or ''}</li>
% endif
% if object.type == 'remove':
<li>Start date : ${object.vacation_date_from or ''} ${object.vacation_time_from or ''}</li>
<li>End date : ${object.vacation_date_to or ''} ${object.vacation_time_to or ''}</li>
% endif
<li>Number of days : ${object.number_of_days or '0'}</li>
<li>Leave type : ${object.holiday_status_id.name or ''}</li>
<li>Description : ${object.name or ''}</li>
% if object.notes:
<li>Notes : ${object.notes or ''}</li>
% endif
</ul>
% if ctx.get('wkf_tracker') == 'submitted':
% if object.type == 'remove':
<p>To validate or refuse it, go to the menu Human Resources > Leaves > Leave requests to approve.</p>
% else:
<p>To validate or refuse it, go to the menu Human Resources > Leaves > Allocation requests.</p>
% endif
% endif
<p>
-- <br/>
Automatic e-mail sent by OpenERP. Do not reply.<br/>
Database : ${ctx.get('dbname')}<br/>
</p>
</div>
]]></field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Beware that, in v8, the form view hr_holidays.allocation_company_new
is not used any more (even if it's defined in the XML ; the form view
hr_holidays.edit_holiday_new is used for both leaves and allocation -->
<record id="edit_holiday_new" model="ir.ui.view">
<field name="name">hr_holidays_usability.leave_request_form</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays.edit_holiday_new"/>
<field name="arch" type="xml">
<field name="date_from" position="attributes">
<attribute name="attrs">{}</attribute>
</field>
<field name="date_to" position="attributes">
<attribute name="attrs">{}</attribute>
</field>
<xpath expr="//field[@name='date_from']/.." position="attributes">
<attribute name="attrs">{}</attribute>
<attribute name="invisible">1</attribute>
</xpath>
<field name="number_of_days_temp" position="attributes">
<attribute name="attrs">{'invisible': [('type', '=', 'remove')]}</attribute>
</field>
<field name="number_of_days_temp" position="after">
<field name="number_of_days_remove" class="oe_inline" attrs="{'invisible': [('type', '=', 'add')]}"/>
</field>
<field name="holiday_status_id" position="after">
<field name="vacation_date_from" attrs="{'required': [('type', '=', 'remove')], 'invisible': [('type', '=', 'add')]}"/>
<field name="vacation_time_from" attrs="{'required': [('type', '=', 'remove')], 'invisible': [('type', '=', 'add')]}"/>
<field name="vacation_date_to" attrs="{'required': [('type', '=', 'remove')], 'invisible': [('type', '=', 'add')]}"/>
<field name="vacation_time_to" attrs="{'required': [('type', '=', 'remove')], 'invisible': [('type', '=', 'add')]}"/>
</field>
</field>
</record>
<record id="view_holiday" model="ir.ui.view">
<field name="name">hr_holidays_usability.leave_request_tree</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays.view_holiday"/>
<field name="arch" type="xml">
<field name="number_of_days" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<field name="number_of_days" position="after">
<field name="number_of_days_remove"/>
</field>
<field name="date_from" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<field name="date_from" position="after">
<field name="vacation_date_from"/>
<field name="vacation_time_from"/>
</field>
<field name="date_to" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<field name="date_to" position="after">
<field name="vacation_date_to"/>
<field name="vacation_time_to"/>
</field>
<field name="holiday_status_id" position="attributes">
<attribute name="invisible">0</attribute>
</field>
</field>
</record>
<record id="edit_holiday_status_form" model="ir.ui.view">
<field name="name">hr_holidays_usability.hr.holidays.status.form</field>
<field name="model">hr.holidays.status</field>
<field name="inherit_id" ref="hr_holidays.edit_holiday_status_form"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="vacation_compute_method"/>
</field>
</field>
</record>
<record id="view_holiday_status_normal_tree" model="ir.ui.view">
<field name="name">hr_holidays_usability.hr.holidays.status.normal.tree</field>
<field name="model">hr.holidays.status</field>
<field name="inherit_id" ref="hr_holidays.view_holiday_status_normal_tree"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="vacation_compute_method"/>
</field>
</field>
</record>
<!-- On the leave requests, put tree view by default instead of calendar -->
<record id="hr_holidays.action_open_ask_holidays_calendar" model="ir.actions.act_window.view">
<field name="sequence" eval="5"/>
</record>
<record id="resource_calendar_leaves_cal_first_action" model="ir.actions.act_window">
<field name="name">Leaves Calendar</field>
<field name="res_model">resource.calendar.leaves</field>
<field name="view_mode">calendar,tree,form</field>
</record>
<!-- Warning: when you have mrp installed, there is an ACL that gives write/create access to MRP Users on resource.calendar.leaves You should inherit this ACL with XMLID mrp.access_resource_calendar_leaves_user to give only read access:
mrp.access_resource_calendar_leaves_user,only read access to manufacuting user,resource.model_resource_calendar_leaves,mrp.group_mrp_user,1,0,0,0
-->
<menuitem id="resource_calendar_leaves_cal_first_menu"
action="resource_calendar_leaves_cal_first_action"
parent="hr_holidays.menu_open_ask_holidays" sequence="100"/>
<record id="hr_holidays.menu_open_company_allocation" model="ir.ui.menu">
<field name="groups_id" eval="[(4, ref('base.group_hr_user'))]"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,288 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * hr_holidays_usability
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-18 21:36+0000\n"
"PO-Revision-Date: 2015-05-18 21:36+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: hr_holidays_usability
#: model:email.template,body_html:hr_holidays_usability.email_template_hr_holidays
msgid "\n"
"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; \">\n"
"\n"
"% if ctx.get('dbname') and 'prod' not in ctx.get('dbname'):\n"
"<p>WARNING : THIS IS A TEST E-MAIL sent from a test OpenERP database (${ctx.get('dbname')}). Do not take into account !</p>\n"
"\n"
"% endif\n"
"<p>La ${object.type == 'remove' and 'demande' or \"demande d'ATTRIBUTION\"} de congé a été ${ctx.get('wkf_tracker') or 'ERROR'} aujourd'hui dans OpenERP par ${user.name or ''} :</p>\n"
"\n"
"<ul>\n"
"<li>Employé : ${object.employee_id.name or ''}</li>\n"
"% if object.employee_id.parent_id:\n"
"<li>Manager : ${object.employee_id.parent_id.name or ''}</li>\n"
"% endif\n"
"% if object.type == 'remove':\n"
"<li>Début : ${object.vacation_date_from or ''}\n"
"% if object.vacation_time_from == 'morning':\n"
"au matin\n"
"% elif object.vacation_time_from == 'noon':\n"
"midi\n"
"% endif\n"
"</li>\n"
"<li>Fin : ${object.vacation_date_to or ''}\n"
"% if object.vacation_time_to == 'noon':\n"
"midi\n"
"% elif object.vacation_time_to == 'evening':\n"
"au soir\n"
"% endif\n"
"</li>\n"
"% endif\n"
"<li>Nombre de jours : ${object.number_of_days_temp or '0'}</li>\n"
"<li>Type de congé : ${object.holiday_status_id.name or ''}</li>\n"
"<li>Description : ${object.name or ''}</li>\n"
"% if object.notes:\n"
"<li>Notes : ${object.notes or ''}</li>\n"
"% endif\n"
"</ul>\n"
"\n"
"% if ctx.get('wkf_tracker') == 'soumise':\n"
"% if object.type == 'remove':\n"
"<p>Pour la valider ou la refuser, allez dans le menu Ressources humaines > Congés > Demandes de congé à valider.</p>\n"
"% else:\n"
"<p>Pour la valider ou la refuser, allez dans le menu Ressources humaines > Congés > Demandes d'attribution de congés à valider.</p>\n"
"% endif\n"
"% endif\n"
"<p>\n"
"-- <br/>\n"
"Mail envoyé automatiquement par OpenERP. Ne pas répondre.<br/>\n"
"Base de donnée : ${ctx.get('dbname')}<br/>\n"
"</p>\n"
"</div>\n"
""
msgstr "\n"
"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; \">\n"
"\n"
"% if ctx.get('dbname') and 'prod' not in ctx.get('dbname'):\n"
"<p>WARNING : THIS IS A TEST E-MAIL sent from a test OpenERP database (${ctx.get('dbname')}). Do not take into account !</p>\n"
"\n"
"% endif\n"
"<p>La ${object.type == 'remove' and 'demande' or \"demande d'ATTRIBUTION\"} de congé a été ${ctx.get('wkf_tracker') or 'ERROR'} aujourd'hui dans OpenERP par ${user.name or ''} :</p>\n"
"\n"
"<ul>\n"
"<li>Employé : ${object.employee_id.name or ''}</li>\n"
"% if object.employee_id.parent_id:\n"
"<li>Manager : ${object.employee_id.parent_id.name or ''}</li>\n"
"% endif\n"
"% if object.type == 'remove':\n"
"<li>Début : ${object.vacation_date_from or ''}\n"
"% if object.vacation_time_from == 'morning':\n"
"au matin\n"
"% elif object.vacation_time_from == 'noon':\n"
"midi\n"
"% endif\n"
"</li>\n"
"<li>Fin : ${object.vacation_date_to or ''}\n"
"% if object.vacation_time_to == 'noon':\n"
"midi\n"
"% elif object.vacation_time_to == 'evening':\n"
"au soir\n"
"% endif\n"
"</li>\n"
"% endif\n"
"<li>Nombre de jours : ${object.number_of_days_temp or '0'}</li>\n"
"<li>Type de congé : ${object.holiday_status_id.name or ''}</li>\n"
"<li>Description : ${object.name or ''}</li>\n"
"% if object.notes:\n"
"<li>Notes : ${object.notes or ''}</li>\n"
"% endif\n"
"</ul>\n"
"\n"
"% if ctx.get('wkf_tracker') == 'soumise':\n"
"% if object.type == 'remove':\n"
"<p>Pour la valider ou la refuser, allez dans le menu Ressources humaines > Congés > Demandes de congé à valider.</p>\n"
"% else:\n"
"<p>Pour la valider ou la refuser, allez dans le menu Ressources humaines > Congés > Demandes d'attribution de congés à valider.</p>\n"
"% endif\n"
"% endif\n"
"<p>\n"
"-- <br/>\n"
"Mail envoyé automatiquement par OpenERP. Ne pas répondre.<br/>\n"
"Base de donnée : ${ctx.get('dbname')}<br/>\n"
"</p>\n"
"</div>\n"
""
#. module: hr_holidays_usability
#: model:email.template,subject:hr_holidays_usability.email_template_hr_holidays
msgid "${ctx.get('dbname') and 'prod' not in ctx.get('dbname') and '[TEST]' or ''}[${object.type == 'remove' and 'Demande' or 'Attribution'} de congé ${ctx.get('wkf_tracker')}] ${object.name or ''} - ${object.employee_id.name or ''}"
msgstr "${ctx.get('dbname') and 'prod' not in ctx.get('dbname') and '[TEST]' or ''}[${object.type == 'remove' and 'Demande' or 'Attribution'} de congé ${ctx.get('wkf_tracker')}] ${object.name or ''} - ${object.employee_id.name or ''}"
#. module: hr_holidays_usability
#: model:ir.actions.server,name:hr_holidays_usability.ir_actions_server_hr_holidays_confirm_mail
msgid "Auto-email confirmed leave"
msgstr "Auto-email confirmed leave"
#. module: hr_holidays_usability
#: model:ir.actions.server,name:hr_holidays_usability.ir_actions_server_hr_holidays_refuse_mail
msgid "Auto-email refused leave"
msgstr "Auto-email refused leave"
#. module: hr_holidays_usability
#: model:ir.actions.server,name:hr_holidays_usability.ir_actions_server_hr_holidays_validate_mail
msgid "Auto-email validated leave"
msgstr "Auto-email validated leave"
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_time_to:0
msgid "End of Vacation"
msgstr "Fin du congé"
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_date_from:0
msgid "Enter the first day of vacation. For example, if you leave one full calendar week, the first day of vacation is Monday morning (and not Friday of the week before)"
msgstr "Entrez le premier jour de congé. Par exemple, si vous partez en congé pendant une semaine calendaire, le premier jour de congé est le lundi matin (et non le vendredi de la semaine précédente)"
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_date_to:0
msgid "Enter the last day of vacation. For example, if you leave one full calendar week, the last day of vacation is Friday evening (and not Monday of the week after)"
msgstr "Entrez le dernier jour de congé. Par exemple, si vous partez en congé pendant une semaine calendaire, le dernier jour de congé est le vendredi soir (et non le lundi matin de la semaine suivante)"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:196
#: code:addons/hr_holidays_usability/hr_holidays.py:202
#: code:addons/hr_holidays_usability/hr_holidays.py:209
#: code:addons/hr_holidays_usability/hr_holidays.py:216
#: code:addons/hr_holidays_usability/hr_holidays.py:222
#: code:addons/hr_holidays_usability/hr_holidays.py:228
#, python-format
msgid "Error:"
msgstr "Erreur :"
#. module: hr_holidays_usability
#: selection:hr.holidays,vacation_time_to:0
msgid "Evening"
msgstr "Soir"
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_date_from:0
msgid "First Day of Vacation"
msgstr "Premier jour de congé"
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_time_to:0
msgid "For example, if you leave one full calendar week, the end of vacation is Friday Evening"
msgstr "Par exemple, si vous partez en congé pendant une semaine calendaire, le dernier jour de congé est le vendredi soir"
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_time_from:0
msgid "For example, if you leave one full calendar week, the first day of vacation is Monday Morning"
msgstr "Par exemple, si vous partez en congé pendant une semaine calendaire, le premier jour de congé est le lundi matin"
#. module: hr_holidays_usability
#: selection:hr.holidays.status,vacation_compute_method:0
msgid "Jours ouvrables"
msgstr "Jours ouvrables"
#. module: hr_holidays_usability
#: selection:hr.holidays.status,vacation_compute_method:0
msgid "Jours ouvrés"
msgstr "Jours ouvrés"
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_date_to:0
msgid "Last Day of Vacation"
msgstr "Dernier jour de congé"
#. module: hr_holidays_usability
#: model:ir.model,name:hr_holidays_usability.model_hr_holidays
msgid "Leave"
msgstr "Congé"
#. module: hr_holidays_usability
#: model:ir.model,name:hr_holidays_usability.model_hr_holidays_status
msgid "Leave Type"
msgstr "Type de congé"
#. module: hr_holidays_usability
#: model:ir.actions.act_window,name:hr_holidays_usability.resource_calendar_leaves_cal_first_action
#: model:ir.ui.menu,name:hr_holidays_usability.resource_calendar_leaves_cal_first_menu
msgid "Leaves Calendar"
msgstr "Calendrier des absences"
#. module: hr_holidays_usability
#: selection:hr.holidays,vacation_time_from:0
msgid "Morning"
msgstr "Matin"
#. module: hr_holidays_usability
#: selection:hr.holidays,vacation_time_from:0
#: selection:hr.holidays,vacation_time_to:0
msgid "Noon"
msgstr "Midi"
#. module: hr_holidays_usability
#: field:hr.holidays,number_of_days_remove:0
msgid "Number of Days of Vacation"
msgstr "Nombre de jours de congé"
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_time_from:0
msgid "Start of Vacation"
msgstr "Début du congé"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:197
#, python-format
msgid "The first day cannot be after the last day !"
msgstr "Le premier jour de congé ne peut pas être postérieur au dernier jour de congé !"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:223
#, python-format
msgid "The first day of vacation cannot be a bank holiday !"
msgstr "Le premier jour de congé ne peut pas être un jour férié !"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:210
#, python-format
msgid "The first day of vacation cannot be a saturday or sunday !"
msgstr "Le premier jour de congé ne peut pas être un Samedi ou un Dimanche !"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:217
#, python-format
msgid "The last day of Vacation cannot be a saturday or sunday !"
msgstr "Le dernier jour de congé ne peut pas être un Samedi ou un Dimanche !"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:229
#, python-format
msgid "The last day of vacation cannot be a bank holiday !"
msgstr "Le dernier jour de congé ne peut pas être un jour férié !"
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:203
#, python-format
msgid "The start of vacation is exactly the same as the end !"
msgstr "Le début du congé est égal à la fin du congé !"
#. module: hr_holidays_usability
#: field:hr.holidays.status,vacation_compute_method:0
msgid "Vacation Compute Method"
msgstr "Méthode de calcul des jours de congé"
#. module: hr_holidays_usability
#: constraint:hr.holidays:0
msgid "error msg in raise"
msgstr "error msg in raise"

View File

@@ -0,0 +1,237 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * hr_holidays_usability
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-18 21:35+0000\n"
"PO-Revision-Date: 2015-05-18 21:35+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: hr_holidays_usability
#: model:email.template,body_html:hr_holidays_usability.email_template_hr_holidays
msgid "\n"
"<div style=\"font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; \">\n"
"\n"
"% if ctx.get('dbname') and 'prod' not in ctx.get('dbname'):\n"
"<p>WARNING : THIS IS A TEST E-MAIL sent from a test OpenERP database (${ctx.get('dbname')}). Do not take into account !</p>\n"
"\n"
"% endif\n"
"<p>La ${object.type == 'remove' and 'demande' or \"demande d'ATTRIBUTION\"} de congé a été ${ctx.get('wkf_tracker') or 'ERROR'} aujourd'hui dans OpenERP par ${user.name or ''} :</p>\n"
"\n"
"<ul>\n"
"<li>Employé : ${object.employee_id.name or ''}</li>\n"
"% if object.employee_id.parent_id:\n"
"<li>Manager : ${object.employee_id.parent_id.name or ''}</li>\n"
"% endif\n"
"% if object.type == 'remove':\n"
"<li>Début : ${object.vacation_date_from or ''}\n"
"% if object.vacation_time_from == 'morning':\n"
"au matin\n"
"% elif object.vacation_time_from == 'noon':\n"
"midi\n"
"% endif\n"
"</li>\n"
"<li>Fin : ${object.vacation_date_to or ''}\n"
"% if object.vacation_time_to == 'noon':\n"
"midi\n"
"% elif object.vacation_time_to == 'evening':\n"
"au soir\n"
"% endif\n"
"</li>\n"
"% endif\n"
"<li>Nombre de jours : ${object.number_of_days_temp or '0'}</li>\n"
"<li>Type de congé : ${object.holiday_status_id.name or ''}</li>\n"
"<li>Description : ${object.name or ''}</li>\n"
"% if object.notes:\n"
"<li>Notes : ${object.notes or ''}</li>\n"
"% endif\n"
"</ul>\n"
"\n"
"% if ctx.get('wkf_tracker') == 'soumise':\n"
"% if object.type == 'remove':\n"
"<p>Pour la valider ou la refuser, allez dans le menu Ressources humaines > Congés > Demandes de congé à valider.</p>\n"
"% else:\n"
"<p>Pour la valider ou la refuser, allez dans le menu Ressources humaines > Congés > Demandes d'attribution de congés à valider.</p>\n"
"% endif\n"
"% endif\n"
"<p>\n"
"-- <br/>\n"
"Mail envoyé automatiquement par OpenERP. Ne pas répondre.<br/>\n"
"Base de donnée : ${ctx.get('dbname')}<br/>\n"
"</p>\n"
"</div>\n"
""
msgstr ""
#. module: hr_holidays_usability
#: model:email.template,subject:hr_holidays_usability.email_template_hr_holidays
msgid "${ctx.get('dbname') and 'prod' not in ctx.get('dbname') and '[TEST]' or ''}[${object.type == 'remove' and 'Demande' or 'Attribution'} de congé ${ctx.get('wkf_tracker')}] ${object.name or ''} - ${object.employee_id.name or ''}"
msgstr ""
#. module: hr_holidays_usability
#: model:ir.actions.server,name:hr_holidays_usability.ir_actions_server_hr_holidays_confirm_mail
msgid "Auto-email confirmed leave"
msgstr ""
#. module: hr_holidays_usability
#: model:ir.actions.server,name:hr_holidays_usability.ir_actions_server_hr_holidays_refuse_mail
msgid "Auto-email refused leave"
msgstr ""
#. module: hr_holidays_usability
#: model:ir.actions.server,name:hr_holidays_usability.ir_actions_server_hr_holidays_validate_mail
msgid "Auto-email validated leave"
msgstr ""
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_time_to:0
msgid "End of Vacation"
msgstr ""
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_date_from:0
msgid "Enter the first day of vacation. For example, if you leave one full calendar week, the first day of vacation is Monday morning (and not Friday of the week before)"
msgstr ""
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_date_to:0
msgid "Enter the last day of vacation. For example, if you leave one full calendar week, the last day of vacation is Friday evening (and not Monday of the week after)"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:196
#: code:addons/hr_holidays_usability/hr_holidays.py:202
#: code:addons/hr_holidays_usability/hr_holidays.py:209
#: code:addons/hr_holidays_usability/hr_holidays.py:216
#: code:addons/hr_holidays_usability/hr_holidays.py:222
#: code:addons/hr_holidays_usability/hr_holidays.py:228
#, python-format
msgid "Error:"
msgstr ""
#. module: hr_holidays_usability
#: selection:hr.holidays,vacation_time_to:0
msgid "Evening"
msgstr ""
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_date_from:0
msgid "First Day of Vacation"
msgstr ""
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_time_to:0
msgid "For example, if you leave one full calendar week, the end of vacation is Friday Evening"
msgstr ""
#. module: hr_holidays_usability
#: help:hr.holidays,vacation_time_from:0
msgid "For example, if you leave one full calendar week, the first day of vacation is Monday Morning"
msgstr ""
#. module: hr_holidays_usability
#: selection:hr.holidays.status,vacation_compute_method:0
msgid "Jours ouvrables"
msgstr ""
#. module: hr_holidays_usability
#: selection:hr.holidays.status,vacation_compute_method:0
msgid "Jours ouvrés"
msgstr ""
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_date_to:0
msgid "Last Day of Vacation"
msgstr ""
#. module: hr_holidays_usability
#: model:ir.model,name:hr_holidays_usability.model_hr_holidays
msgid "Leave"
msgstr ""
#. module: hr_holidays_usability
#: model:ir.model,name:hr_holidays_usability.model_hr_holidays_status
msgid "Leave Type"
msgstr ""
#. module: hr_holidays_usability
#: model:ir.actions.act_window,name:hr_holidays_usability.resource_calendar_leaves_cal_first_action
#: model:ir.ui.menu,name:hr_holidays_usability.resource_calendar_leaves_cal_first_menu
msgid "Leaves Calendar"
msgstr ""
#. module: hr_holidays_usability
#: selection:hr.holidays,vacation_time_from:0
msgid "Morning"
msgstr ""
#. module: hr_holidays_usability
#: selection:hr.holidays,vacation_time_from:0
#: selection:hr.holidays,vacation_time_to:0
msgid "Noon"
msgstr ""
#. module: hr_holidays_usability
#: field:hr.holidays,number_of_days_remove:0
msgid "Number of Days of Vacation"
msgstr ""
#. module: hr_holidays_usability
#: field:hr.holidays,vacation_time_from:0
msgid "Start of Vacation"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:197
#, python-format
msgid "The first day cannot be after the last day !"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:223
#, python-format
msgid "The first day of vacation cannot be a bank holiday !"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:210
#, python-format
msgid "The first day of vacation cannot be a saturday or sunday !"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:217
#, python-format
msgid "The last day of Vacation cannot be a saturday or sunday !"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:229
#, python-format
msgid "The last day of vacation cannot be a bank holiday !"
msgstr ""
#. module: hr_holidays_usability
#: code:addons/hr_holidays_usability/hr_holidays.py:203
#, python-format
msgid "The start of vacation is exactly the same as the end !"
msgstr ""
#. module: hr_holidays_usability
#: field:hr.holidays.status,vacation_compute_method:0
msgid "Vacation Compute Method"
msgstr ""
#. module: hr_holidays_usability
#: constraint:hr.holidays:0
msgid "error msg in raise"
msgstr ""