hr_holidays_usability: add support for emails

Many small fixes and improvements
This commit is contained in:
Alexis de Lattre
2017-06-06 16:27:44 +02:00
parent d55b01ca7b
commit e5221d6a96
7 changed files with 56 additions and 21 deletions

View File

@@ -34,7 +34,7 @@ class HrEmployee(models.Model):
_inherit = 'hr.employee' _inherit = 'hr.employee'
holiday_exclude_mass_allocation = fields.Boolean( holiday_exclude_mass_allocation = fields.Boolean(
string='Exclude from Mass Holiday Attribution') string='Exclude from Mass Holiday Allocation')
class HrHolidays(models.Model): class HrHolidays(models.Model):
@@ -73,7 +73,7 @@ class HrHolidays(models.Model):
# 1 or 2 for normal holidays # 1 or 2 for normal holidays
@api.model @api.model
def _compute_number_of_days(self): def _usability_compute_number_of_days(self):
# depend on the holiday_status_id # depend on the holiday_status_id
hhpo = self.env['hr.holidays.public'] hhpo = self.env['hr.holidays.public']
days = 0.0 days = 0.0
@@ -218,6 +218,11 @@ class HrHolidays(models.Model):
string='Public Title', string='Public Title',
help="Warning: this title is shown publicly in the " help="Warning: this title is shown publicly in the "
"calendar. Don't write private/personnal information in this field.") "calendar. Don't write private/personnal information in this field.")
# by default, there is no company_id field on hr.holidays !
company_id = fields.Many2one(
related='employee_id.resource_id.company_id', store=True,
readonly=True)
state = fields.Selection(default='draft') # hr_holidays, default='confirm'
@api.constrains( @api.constrains(
'vacation_date_from', 'vacation_date_to', 'holiday_type', 'type') 'vacation_date_from', 'vacation_date_to', 'holiday_type', 'type')
@@ -307,16 +312,14 @@ class HrHolidays(models.Model):
'holiday_status_id') 'holiday_status_id')
def leave_number_of_days_change(self): def leave_number_of_days_change(self):
if self.type == 'remove': if self.type == 'remove':
days = self._compute_number_of_days() days = self._usability_compute_number_of_days()
self.number_of_days_temp = days self.number_of_days_temp = days
# Neutralize the native on_change on dates # Neutralize the native on_change on dates
def _onchange_date_from(self): def _onchange_date_from(self):
print "_onchange_date_from self=", self
return {} return {}
def _onchange_date_to(self): def _onchange_date_to(self):
print "xxxxxxxxxxxxxxx _onchange_date_to self=", self
return {} return {}
# I want to set number_of_days_temp as readonly in the view of leaves # I want to set number_of_days_temp as readonly in the view of leaves
@@ -326,7 +329,7 @@ class HrHolidays(models.Model):
def create(self, vals): def create(self, vals):
obj = super(HrHolidays, self).create(vals) obj = super(HrHolidays, self).create(vals)
if obj.type == 'remove': if obj.type == 'remove':
days = obj._compute_number_of_days() days = obj._usability_compute_number_of_days()
obj.number_of_days_temp = days obj.number_of_days_temp = days
return obj return obj
@@ -335,11 +338,22 @@ class HrHolidays(models.Model):
res = super(HrHolidays, self).write(vals) res = super(HrHolidays, self).write(vals)
for obj in self: for obj in self:
if obj.type == 'remove': if obj.type == 'remove':
days = obj._compute_number_of_days() days = obj._usability_compute_number_of_days()
if days != obj.number_of_days_temp: if days != obj.number_of_days_temp:
obj.number_of_days_temp = days obj.number_of_days_temp = days
return res return res
@api.multi
def action_confirm(self):
for holi in self:
if not self._context.get('no_email_notification'):
template = self.env.ref(
'hr_holidays_usability.email_template_hr_holidays')
template.with_context(
dbname=self._cr.dbname,
new_holiday_state='submitted').send_mail(holi.id)
return super(HrHolidays, self).action_confirm()
@api.multi @api.multi
def action_validate(self): def action_validate(self):
for holi in self: for holi in self:
@@ -364,6 +378,12 @@ class HrHolidays(models.Model):
"Allocation request '%s' has a leave type '%s' that " "Allocation request '%s' has a leave type '%s' that "
"can be approved only by an HR Manager.") "can be approved only by an HR Manager.")
% (holi.name, holi.holiday_status_id.name)) % (holi.name, holi.holiday_status_id.name))
if not self._context.get('no_email_notification'):
template = self.env.ref(
'hr_holidays_usability.email_template_hr_holidays')
template.with_context(
dbname=self._cr.dbname,
new_holiday_state='validated').send_mail(holi.id)
return super(HrHolidays, self).action_validate() return super(HrHolidays, self).action_validate()
@api.multi @api.multi
@@ -377,6 +397,12 @@ class HrHolidays(models.Model):
"You cannot refuse your own Leave or Allocation " "You cannot refuse your own Leave or Allocation "
"holiday request '%s'.") "holiday request '%s'.")
% holi.name) % holi.name)
if not self._context.get('no_email_notification'):
template = self.env.ref(
'hr_holidays_usability.email_template_hr_holidays')
template.with_context(
dbname=self._cr.dbname,
new_holiday_state='refused').send_mail(holi.id)
return super(HrHolidays, self).action_refuse() return super(HrHolidays, self).action_refuse()

View File

@@ -8,7 +8,7 @@
<field name="email_to">${object.employee_id.parent_id.user_id.email or ''}</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="email_cc">${object.employee_id.user_id.email or ''}</field>
<field name="reply_to">${user.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="subject">${ctx.get('dbname') and 'prod' not in ctx.get('dbname') and '[TEST]' or ''}[${object.type == 'remove' and 'Leave' or 'Allocation'} ${ctx.get('new_holiday_state')}] ${object.name or ''} - ${object.employee_id.name or ''}</field>
<field name="auto_delete" eval="False"/> <field name="auto_delete" eval="False"/>
<field name="lang">${user.lang}</field> <field name="lang">${user.lang}</field>
<field name="body_html"><![CDATA[ <field name="body_html"><![CDATA[
@@ -18,7 +18,7 @@
<p>WARNING : THIS IS A TEST E-MAIL sent from a test Odoo database (${ctx.get('dbname')}). Do not take into account !</p> <p>WARNING : THIS IS A TEST E-MAIL sent from a test Odoo database (${ctx.get('dbname')}). Do not take into account !</p>
% endif % 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 Odoo by ${user.name or ''} :</p> <p>The following ${object.type == 'remove' and 'leave request' or 'ALLOCATION request (i.e. credit of days, not debit !)'} has been ${ctx.get('new_holiday_state') or 'ERROR'} today in Odoo by ${user.name or ''} :</p>
<ul> <ul>
<li>Employee : ${object.employee_id.name or ''}</li> <li>Employee : ${object.employee_id.name or ''}</li>
@@ -35,11 +35,11 @@
<li>Notes for the manager : ${object.notes or ''}</li> <li>Notes for the manager : ${object.notes or ''}</li>
</ul> </ul>
% if ctx.get('wkf_tracker') == 'submitted': % if ctx.get('new_holiday_state') == 'submitted':
% if object.type == 'remove': % if object.type == 'remove':
<p>To validate or refuse it, go to the menu Human Resources > Leaves > Leave requests to approve.</p> <p>To validate or refuse it, go to the menu Leaves > Leaves to Approve > Leaves.</p>
% else: % else:
<p>To validate or refuse it, go to the menu Human Resources > Leaves > Allocation requests.</p> <p>To validate or refuse it, go to the menu Leaves > Leaves to Approve > Leaves Allocation.</p>
% endif % endif
% endif % endif

View File

@@ -35,7 +35,7 @@ hr_holidays.edit_holiday_new is used for both leaves and allocation -->
<field name="vacation_time_to" attrs="{'required': [('type', '=', 'remove')], 'invisible': [('type', '=', 'add')]}"/> <field name="vacation_time_to" attrs="{'required': [('type', '=', 'remove')], 'invisible': [('type', '=', 'add')]}"/>
</field> </field>
<field name="notes" position="replace"> <field name="notes" position="replace">
<group name="bottom"> <group name="bottom" colspan="2">
<group string="Message for the Manager" name="notes"> <group string="Message for the Manager" name="notes">
<field name="notes" nolabel="1" placeholder="Add a message for your manager..."/> <field name="notes" nolabel="1" placeholder="Add a message for your manager..."/>
</group> </group>
@@ -61,6 +61,7 @@ hr_holidays.edit_holiday_new is used for both leaves and allocation -->
</field> </field>
<field name="department_id" position="after"> <field name="department_id" position="after">
<field name="posted_date" groups="hr_holidays.group_hr_holidays_manager"/> <field name="posted_date" groups="hr_holidays.group_hr_holidays_manager"/>
<field name="company_id" groups="base.group_multi_company"/>
</field> </field>
</field> </field>
</record> </record>
@@ -86,6 +87,7 @@ hr_holidays.edit_holiday_new is used for both leaves and allocation -->
</field> </field>
<field name="holiday_status_id" position="after"> <field name="holiday_status_id" position="after">
<field name="posted_date" groups="hr_holidays.group_hr_holidays_manager"/> <field name="posted_date" groups="hr_holidays.group_hr_holidays_manager"/>
<field name="company_id" groups="base.group_multi_company"/>
</field> </field>
</field> </field>
</record> </record>

View File

@@ -3,7 +3,7 @@
# @author Alexis de Lattre <alexis.delattre@akretion.com> # @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models, tools from odoo import fields, models, api, tools
class HrHolidaysEmployeeCounter(models.Model): class HrHolidaysEmployeeCounter(models.Model):
@@ -22,9 +22,10 @@ class HrHolidaysEmployeeCounter(models.Model):
leaves_remaining_posted = fields.Float(string='Posted Remaining Leaves') leaves_remaining_posted = fields.Float(string='Posted Remaining Leaves')
allocated_leaves = fields.Float(string='Allocated Leaves') allocated_leaves = fields.Float(string='Allocated Leaves')
@api.model_cr
def init(self): def init(self):
tools.drop_view_if_exists(self._cr, 'hr_holidays_employee_counter') tools.drop_view_if_exists(self.env.cr, 'hr_holidays_employee_counter')
self._cr.execute(""" self.env.cr.execute("""
CREATE or REPLACE view hr_holidays_employee_counter AS ( CREATE or REPLACE view hr_holidays_employee_counter AS (
SELECT SELECT
min(hh.id) AS id, min(hh.id) AS id,

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="0"> <odoo noupdate="1">
<!-- <!--
Employee : only see his holidays Employee : only see his holidays
@@ -40,4 +40,10 @@ Manager = person that administrates the holidays process : can see everything, d
<field name="groups" eval="[(4, ref('hr_holidays.group_hr_holidays_manager'))]"/> <field name="groups" eval="[(4, ref('hr_holidays.group_hr_holidays_manager'))]"/>
</record> </record>
<record id="hr_holidays_multicompany_rule" model="ir.rule">
<field name="name">Holidays multi-company</field>
<field name="model_id" ref="hr_holidays.model_hr_holidays"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
</record>
</odoo> </odoo>

View File

@@ -3,7 +3,7 @@
# @author Alexis de Lattre <alexis.delattre@akretion.com> # @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields, api, workflow, _ from odoo import models, fields, api, _
from odoo.exceptions import UserError from odoo.exceptions import UserError
@@ -62,10 +62,10 @@ class HrHolidaysMassAllocation(models.TransientModel):
'type': 'add', 'type': 'add',
'holiday_type': 'employee', 'holiday_type': 'employee',
'holiday_status_id': self.holiday_status_id.id, 'holiday_status_id': self.holiday_status_id.id,
'state': 'confirm',
}) })
if auto_approve: if auto_approve:
# TODO: handle the no_email_notification hol.with_context(no_email_notification=True).action_validate()
hol.action_validate()
alloc_hol_ids.append(hol.id) alloc_hol_ids.append(hol.id)
action = self.env['ir.actions.act_window'].for_xml_id( action = self.env['ir.actions.act_window'].for_xml_id(
'hr_holidays', 'open_allocation_holidays') 'hr_holidays', 'open_allocation_holidays')

View File

@@ -15,7 +15,7 @@
<group name="main" string="Leave Requests to Post"> <group name="main" string="Leave Requests to Post">
<field name="state" invisible="1"/> <field name="state" invisible="1"/>
<field name="before_date" states="draft"/> <field name="before_date" states="draft"/>
<field name="holidays_to_post_ids" nolabel="1" <field name="holidays_to_post_ids" nolabel="1" colspan="2"
context="{'tree_view_ref': 'hr_holidays.view_holiday'}" context="{'tree_view_ref': 'hr_holidays.view_holiday'}"
states="done"/> states="done"/>
</group> </group>