diff --git a/addons/hr/data/hr_data.xml b/addons/hr/data/hr_data.xml
index bb2cf4b5a08..2b031146e01 100644
--- a/addons/hr/data/hr_data.xml
+++ b/addons/hr/data/hr_data.xml
@@ -29,5 +29,16 @@ Leave Management (keep track of employee leaves), Expense Management (manage emp
+
+ HR: unknown employee bounce
+ Your document has not been created
+ ${user.email}
+ ${ctx['email_to']|safe}
+ ${user.lang}
+
+
+
+
+
diff --git a/addons/hr/models/__init__.py b/addons/hr/models/__init__.py
index c870236ee6c..ef90454a6d7 100644
--- a/addons/hr/models/__init__.py
+++ b/addons/hr/models/__init__.py
@@ -2,5 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import hr
+import mail_alias
+import mail_thread
import res_partner
import res_users
diff --git a/addons/hr/models/mail_alias.py b/addons/hr/models/mail_alias.py
new file mode 100644
index 00000000000..710b7efaff7
--- /dev/null
+++ b/addons/hr/models/mail_alias.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class Alias(models.Model):
+ _inherit = 'mail.alias'
+
+ alias_contact = fields.Selection(selection_add=[('employees', 'Authenticated Employees')])
diff --git a/addons/hr/models/mail_thread.py b/addons/hr/models/mail_thread.py
new file mode 100644
index 00000000000..d27cbbd2afc
--- /dev/null
+++ b/addons/hr/models/mail_thread.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import logging
+
+from odoo import api, models
+from odoo.addons.mail.models.mail_thread import decode_header
+from odoo.tools import email_split
+
+_logger = logging.getLogger(__name__)
+
+class MailThread(models.AbstractModel):
+ _inherit = "mail.thread"
+
+ @api.model
+ def message_route_verify(self, message, message_dict, route, update_author=True, assert_model=True, create_fallback=True, allow_private=False):
+ res = super(MailThread, self).message_route_verify(message, message_dict, route, update_author, assert_model, create_fallback, allow_private)
+
+ if res:
+ alias = route[4]
+ email_from = decode_header(message, 'From')
+ message_id = message.get('Message-Id')
+
+ # Identically equal to the definition in mail module because sub methods are local
+ # variables and cannot be called with super
+ def _create_bounce_email(body_html):
+ bounce_to = decode_header(message, 'Return-Path') or email_from
+ bounce_mail_values = {
+ 'body_html': body_html,
+ 'subject': 'Re: %s' % message.get('subject'),
+ 'email_to': bounce_to,
+ 'auto_delete': True,
+ }
+ bounce_from = self.env['ir.mail_server']._get_default_bounce_address()
+ if bounce_from:
+ bounce_mail_values['email_from'] = 'MAILER-DAEMON <%s>' % bounce_from
+ self.env['mail.mail'].create(bounce_mail_values).send()
+
+ def _warn(message):
+ _logger.info('Routing mail with Message-Id %s: route %s: %s',
+ message_id, route, message)
+
+ # Alias: check alias_contact settings for employees
+
+ if alias and alias.alias_contact == 'employees':
+ email_address = email_split(email_from)[0]
+ employee = self.env['hr.employee'].search([('work_email', 'ilike', email_address)], limit=1)
+ if not employee:
+ employee = self.env['hr.employee'].search([('user_id.email', 'ilike', email_address)], limit=1)
+ if not employee:
+ mail_template = self.env.ref('hr.mail_template_data_unknown_employee_email_address')
+ _warn('alias %s does not accept unknown employees, skipping' % alias.alias_name)
+ _create_bounce_email(mail_template.body_html)
+ return False
+ return res
diff --git a/addons/hr_expense/data/hr_expense_data.xml b/addons/hr_expense/data/hr_expense_data.xml
index 3ca4fed609c..425fb3a6e79 100644
--- a/addons/hr_expense/data/hr_expense_data.xml
+++ b/addons/hr_expense/data/hr_expense_data.xml
@@ -17,6 +17,7 @@
expense
+ employees
@@ -65,15 +66,5 @@
-
- HrExpense: unknown employee bounce
- Your expense has not been created
- help@odoo.com
- ${ctx['email_to']|safe}
- ${user.lang}
-
-
-
-
diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py
index 5ce0b3edfe9..e38a2537873 100644
--- a/addons/hr_expense/models/hr_expense.py
+++ b/addons/hr_expense/models/hr_expense.py
@@ -289,21 +289,14 @@ class HrExpense(models.Model):
def message_new(self, msg_dict, custom_values=None):
if custom_values is None:
custom_values = {}
- # Retrieve the email address from the email field. The string is constructed like
- # 'foo '. We will extract 'bar' from this
+
email_address = email_split(msg_dict.get('email_from', False))[0]
- # Look after an employee who has this email address or an employee for whom the related
- # user has this email address. In the case not employee is found, we send back an email
- # to explain that the expense will not be created.
- employee = self.env['hr.employee'].search([('work_email', 'ilike', email_address)], limit=1)
- if not employee:
- employee = self.env['hr.employee'].search([('user_id.email', 'ilike', email_address)], limit=1)
- if not employee:
- # Send back an email to explain why the expense has not been created
- mail_template = self.env.ref('hr_expense.mail_template_data_expense_unknown_email_address')
- mail_template.with_context(email_to=email_address).send_mail(self.env.ref('base.module_hr_expense').id)
- return False
+ employee = self.env['hr.employee'].search([
+ '|',
+ ('work_email', 'ilike', email_address),
+ ('user_id.email', 'ilike', email_address)
+ ], limit=1)
expense_description = msg_dict.get('subject', '')