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', '')