[IMP] hr_expense: improve activity management on expense sheet model

This commit improves expense flow management through a better integration
of activities and addition of automated activities. Several things are done
in this commit :

 * expense sheet (report) model do not inherit from mail.activity.mixin.
   This commit adds the inherit so that expense users and managers can now
   schedule and manage activities on expense reports. This will help them
   in their daily job;
 * automatic activities generation is added for expense reports. Activities
   are generated for approval. They are also automatically set as done when
   validating or unlinked when refusing or resetting to avoid bloating users
   with unnecessary activities;
 * a menu to configure activity types is added. Indeed HR managers should be
   able to see and configure activity types related to their job;
 * filters are added to be able to use the systray and to filter the kanban
   view based on activities

Having automated activities allow to replace some messages and tracking
that were implemented to warn people of expense reports to approve.
This commit therefore

 * simplifies the tracking as tracking to confirm reports is not necessary
   anymore;
 * removes to approve subtype on report model as well as its parent subtype
   on the department. This allows to simplify chatter in hr_expense app;
This commit is contained in:
Thibault Delavallée
2018-03-27 15:19:34 +02:00
parent 238c20ffff
commit 133fd0a21e
6 changed files with 69 additions and 21 deletions
+1
View File
@@ -36,6 +36,7 @@ This module also uses analytic accounting and is compatible with the invoice on
'wizard/hr_expense_refuse_reason_views.xml',
'wizard/hr_expense_sheet_register_payment.xml',
'views/hr_expense_views.xml',
'views/mail_activity_views.xml',
'security/ir_rule.xml',
'report/hr_expense_report.xml',
'views/hr_department_views.xml',
+7 -16
View File
@@ -2,7 +2,13 @@
<odoo>
<data noupdate="1">
<!--default alias for leads-->
<record id="mail_act_expense_approval" model="mail.activity.type">
<field name="name">Expense Approval</field>
<field name="icon">fa-dollar</field>
<field name="res_model_id" ref="hr_expense.model_hr_expense_sheet"/>
</record>
<!-- default alias for expenses -->
<record id="mail_alias_expense" model="mail.alias">
<field name="alias_name">expense</field>
<field name="alias_model_id" ref="model_hr_expense"/>
@@ -23,27 +29,12 @@
<field name="default" eval="True"/>
<field name="description">Expense report refused</field>
</record>
<record id="mt_expense_confirmed" model="mail.message.subtype">
<field name="name">Submitted</field>
<field name="res_model">hr.expense.sheet</field>
<field name="description">Expense report submitted, waiting approval</field>
<field name="default" eval="True"/>
</record>
<record id="mt_expense_paid" model="mail.message.subtype">
<field name="name">Paid</field>
<field name="res_model">hr.expense.sheet</field>
<field name="description">Expense report paid</field>
<field name="default" eval="False"/>
</record>
<!-- Department (Parent) related subtypes for messaging / Chatter -->
<record id="mt_department_expense_confirmed" model="mail.message.subtype">
<field name="name">Expenses To Approve</field>
<field name="res_model">hr.department</field>
<field name="default" eval="False"/>
<field name="parent_id" eval="ref('mt_expense_confirmed')"/>
<field name="relation_field">department_id</field>
<field name="sequence" eval="10"/>
</record>
<!-- Email Templates -->
<template id="hr_expense_template_refuse_reason">
+25 -4
View File
@@ -450,7 +450,7 @@ class HrExpense(models.Model):
class HrExpenseSheet(models.Model):
_name = "hr.expense.sheet"
_inherit = ['mail.thread']
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "Expense Report"
_order = "accounting_date desc, id desc"
@@ -529,6 +529,7 @@ class HrExpenseSheet(models.Model):
def create(self, vals):
self._create_set_followers(vals)
sheet = super(HrExpenseSheet, self).create(vals)
sheet.activity_update()
return sheet
@api.multi
@@ -554,8 +555,6 @@ class HrExpenseSheet(models.Model):
self.ensure_one()
if 'state' in init_values and self.state == 'approve':
return 'hr_expense.mt_expense_approved'
elif 'state' in init_values and self.state == 'submit':
return 'hr_expense.mt_expense_confirmed'
elif 'state' in init_values and self.state == 'cancel':
return 'hr_expense.mt_expense_refused'
elif 'state' in init_values and self.state == 'done':
@@ -621,6 +620,7 @@ class HrExpenseSheet(models.Model):
self.write({'state': 'post'})
else:
self.write({'state': 'done'})
self.activity_update()
return res
@api.multi
@@ -649,6 +649,7 @@ class HrExpenseSheet(models.Model):
raise UserError(_("Only HR Officers can approve expenses"))
responsible_id = self.user_id.id or self.env.user.id
self.write({'state': 'approve', 'user_id': responsible_id})
self.activity_update()
@api.multi
def paid_expense_sheets(self):
@@ -661,8 +662,28 @@ class HrExpenseSheet(models.Model):
self.write({'state': 'cancel'})
for sheet in self:
sheet.message_post_with_view('hr_expense.hr_expense_template_refuse_reason', values={'reason': reason, 'is_sheet': True, 'name': self.name})
self.activity_update()
@api.multi
def reset_expense_sheets(self):
self.mapped('expense_line_ids').write({'is_refused': False})
return self.write({'state': 'submit'})
self.write({'state': 'submit'})
self.activity_update()
return True
def _get_responsible_for_approval(self):
if self.user_id:
return self.user_id
elif self.employee_id.parent_id.user_id:
return self.employee_id.parent_id.user_id
elif self.employee_id.department_id.manager_id.user_id:
return self.employee_id.department_id.manager_id.user_id
return self.env.user
def activity_update(self):
for expense_report in self.filtered(lambda hol: hol.state == 'submit'):
self.activity_schedule(
'hr_expense.mail_act_expense_approval', fields.Date.today(),
user_id=expense_report._get_responsible_for_approval().id)
self.filtered(lambda hol: hol.state == 'approve').activity_feedback(['hr_expense.mail_act_expense_approval'])
self.filtered(lambda hol: hol.state == 'cancel').activity_unlink(['hr_expense.mail_act_expense_approval'])
@@ -1,5 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_expense_user,hr.expense.user,model_hr_expense,hr_expense.group_hr_expense_user,1,1,1,1
access_hr_expense_employee,hr.expense.employee,model_hr_expense,base.group_user,1,1,1,1
access_hr_expense_sheet_user,hr.expense.sheet.user,model_hr_expense_sheet,hr_expense.group_hr_expense_user,1,1,1,1
@@ -15,3 +14,4 @@ access_account_invoice_tax_user,account.invoice.tax.user,account.model_account_i
access_account_move_user,account.move.user,account.model_account_move,hr_expense.group_hr_expense_user,1,0,0,0
access_account_move_line_user,account.move.line.user,account.model_account_move_line,hr_expense.group_hr_expense_user,1,0,0,0
access_account_analytic_line_user,account.analytic.line.user,account.model_account_analytic_line,hr_expense.group_hr_expense_user,1,1,1,1
access_mail_activity_type_expense_user,mail.activity.type.expense.user,mail.model_mail_activity_type,hr_expense.group_hr_expense_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
access_hr_expense_user hr.expense.user model_hr_expense hr_expense.group_hr_expense_user 1 1 1 1
2 access_hr_expense_employee access_hr_expense_user hr.expense.employee hr.expense.user model_hr_expense base.group_user hr_expense.group_hr_expense_user 1 1 1 1
3 access_hr_expense_sheet_user access_hr_expense_employee hr.expense.sheet.user hr.expense.employee model_hr_expense_sheet model_hr_expense hr_expense.group_hr_expense_user base.group_user 1 1 1 1
4 access_hr_expense_sheet_employee access_hr_expense_sheet_user hr.expense.sheet.employee hr.expense.sheet.user model_hr_expense_sheet base.group_user hr_expense.group_hr_expense_user 1 1 1 1
14 access_account_move_line_user access_account_move_user account.move.line.user account.move.user account.model_account_move_line account.model_account_move hr_expense.group_hr_expense_user 1 0 0 0
15 access_account_analytic_line_user access_account_move_line_user account.analytic.line.user account.move.line.user account.model_account_analytic_line account.model_account_move_line hr_expense.group_hr_expense_user 1 1 0 1 0 1 0
16 access_account_analytic_line_user account.analytic.line.user account.model_account_analytic_line hr_expense.group_hr_expense_user 1 1 1 1
17 access_mail_activity_type_expense_user mail.activity.type.expense.user mail.model_mail_activity_type hr_expense.group_hr_expense_user 1 1 1 1
@@ -203,6 +203,15 @@
<filter string="My Expenses" name="my_expenses" domain="[('employee_id.user_id', '=', uid)]"/>
<separator />
<filter string="New Mail" name="message_unread" domain="[('message_unread', '=', True)]"/>
<separator/>
<filter string="Late Activities" name="activities_overdue"
domain="[('activity_ids.date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]"
help="Show all records which has next action date is before today"/>
<filter string="Today Activities" name="activities_today"
domain="[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
<filter string="Future Activities" name="activities_upcoming_all"
domain="[('activity_ids.date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))
]"/>
<group expand="0" string="Group By">
<filter string="Report" name="report" domain="[]" context="{'group_by': 'sheet_id'}"/>
<filter string="Employee" name="employee" domain="[]" context="{'group_by': 'employee_id'}"/>
@@ -487,6 +496,7 @@
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
@@ -576,6 +586,15 @@
<filter string="My Reports" name="my_reports" domain="[('employee_id.user_id', '=', uid)]"/>
<separator />
<filter string="New Mail" name="message_unread" domain="[('message_unread', '=', True)]"/>
<separator/>
<filter string="Late Activities" name="activities_overdue"
domain="[('activity_ids.date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]"
help="Show all records which has next action date is before today"/>
<filter string="Today Activities" name="activities_today"
domain="[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
<filter string="Future Activities" name="activities_upcoming_all"
domain="[('activity_ids.date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))
]"/>
<group expand="0" string="Group By">
<filter string="Employee" name="employee" domain="[]" context="{'group_by': 'employee_id'}"/>
<filter string="Department" name="department" domain="[]" context="{'group_by': 'department_id'}"/>
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<odoo>
<!-- Activity types config -->
<record id="mail_activity_type_action_config_hr_expense" model="ir.actions.act_window">
<field name="name">Activity Types</field>
<field name="res_model">mail.activity.type</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">['|', ('res_model_id', '=', False), ('res_model_id.model', '=', 'hr.expense.sheet')]</field>
<field name="context">{'default_res_model': 'hr.expense.sheet'}</field>
</record>
<menuitem id="hr_expense_menu_config_activity_type"
action="mail_activity_type_action_config_hr_expense"
parent="menu_hr_expense_configuration"
groups="base.group_no_one"/>
</odoo>