diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index 38e1cb5247b..d7e956a2b48 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -920,14 +920,9 @@ class HrExpense(models.Model): @api.model def message_new(self, msg_dict, custom_values=None): email_address = email_split(msg_dict.get('email_from', False))[0] + employee = self._get_employee_from_email(email_address) - employee = self.env['hr.employee'].search([ - '|', - ('work_email', 'ilike', email_address), - ('user_id.email', 'ilike', email_address) - ]).filtered(lambda e: e.company_id == e.user_id.company_id) - - if len(employee) != 1: + if not employee: return super().message_new(msg_dict, custom_values=custom_values) expense_description = msg_dict.get('subject', '') @@ -967,6 +962,29 @@ class HrExpense(models.Model): self._send_expense_success_mail(msg_dict, expense) return expense + @api.model + def _get_employee_from_email(self, email_address): + employee = self.env['hr.employee'].search([ + ('user_id', '!=', False), + '|', + ('work_email', 'ilike', email_address), + ('user_id.email', 'ilike', email_address), + ]) + + if len(employee) > 1: + # Several employees can be linked to the same user. + # In that case, we only keep the employee that matched the user's company. + return employee.filtered(lambda e: e.company_id == e.user_id.company_id) + + if not employee: + # An employee does not always have a user. + return self.env['hr.employee'].search([ + ('user_id', '=', False), + ('work_email', 'ilike', email_address), + ], limit=1) + + return employee + @api.model def _parse_product(self, expense_description): """ diff --git a/addons/hr_expense/tests/test_expenses_mail_import.py b/addons/hr_expense/tests/test_expenses_mail_import.py index 70d8b0d9ec7..f2c81522a09 100644 --- a/addons/hr_expense/tests/test_expenses_mail_import.py +++ b/addons/hr_expense/tests/test_expenses_mail_import.py @@ -67,6 +67,43 @@ class TestExpensesMailImport(TestExpenseCommon): 'employee_id': company_2_employee.id, }]) + def test_import_expense_from_email_employee_without_user(self): + """When an employee is not linked to a user, he has to be able to create expenses from email""" + employee = self.expense_employee + employee.user_id = False + + message_parsed = { + 'message_id': "the-world-is-a-ghetto", + 'subject': 'New expense', + 'email_from': employee.work_email, + 'to': 'catchall@yourcompany.com', + 'body': "Don't you know, that for me, and for you", + 'attachments': [], + } + + expense = self.env['hr.expense'].message_new(message_parsed) + self.assertRecordValues(expense, [{ + 'employee_id': employee.id, + }]) + + def test_import_expense_from_email_no_product(self): + message_parsed = { + 'message_id': "the-world-is-a-ghetto", + 'subject': 'no product code 800', + 'email_from': self.expense_user_employee.email, + 'to': 'catchall@yourcompany.com', + 'body': "Don't you know, that for me, and for you", + 'attachments': [], + } + + expense = self.env['hr.expense'].message_new(message_parsed) + + self.assertRecordValues(expense, [{ + 'product_id': False, + 'total_amount': 800.0, + 'employee_id': self.expense_employee.id, + }]) + def test_import_expense_from_mail_parsing_subjects(self): def assertParsedValues(subject, currencies, exp_description, exp_amount, exp_product, exp_currency): product, amount, currency_id, description = self.env['hr.expense'] \