diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index 53badbf1991..99c27d08c30 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -348,7 +348,7 @@ class HrExpense(models.Model): product = self.env['product.product'].search([('can_be_expensed', '=', True)]) if product: - product = product.filtered(lambda p: p.default_code == "EXP_GEN") or product[0] + product = product.filtered(lambda p: p.default_code == "EXP_GEN")[0] or product[0] else: raise UserError(_("You need to have at least one category that can be expensed in your database to proceed!")) diff --git a/addons/hr_expense/tests/common.py b/addons/hr_expense/tests/common.py index 3604ed2d72a..1a2e3903c98 100644 --- a/addons/hr_expense/tests/common.py +++ b/addons/hr_expense/tests/common.py @@ -39,6 +39,14 @@ class TestExpenseCommon(AccountTestInvoicingCommon): 'address_id': cls.expense_user_employee.partner_id.id, }) + cls.product_zero_cost = cls.env['product.product'].create({ + 'name': 'General', + 'default_code': 'EXP_GEN', + 'standard_price': 0.0, + 'can_be_expensed': True, + }) + + # Allow the current accounting user to access the expenses. cls.env.user.groups_id |= group_expense_manager diff --git a/addons/hr_expense/tests/test_expenses.py b/addons/hr_expense/tests/test_expenses.py index 4855a085961..25385602e05 100644 --- a/addons/hr_expense/tests/test_expenses.py +++ b/addons/hr_expense/tests/test_expenses.py @@ -628,3 +628,117 @@ class TestExpenses(TestExpenseCommon): 'amount_paid': formatLang(self.env, payment.amount_total, currency_obj=self.env.company.currency_id), 'currency': self.env.company.currency_id }) + + def test_hr_expense_split(self): + """ + Check Split Expense flow. + """ + expense = self.env['hr.expense'].create({ + 'name': 'Expense To Test Split - Diego, libre dans sa tĂȘte', + 'employee_id': self.expense_employee.id, + 'product_id': self.product_zero_cost.id, + 'total_amount': 100.00, + 'tax_ids': [(6, 0, [self.tax_purchase_a.id])], + 'analytic_distribution': {self.analytic_account_1.id: 100}, + }) + + split_wizard = expense.action_split_wizard() + wizard = self.env['hr.expense.split.wizard'].browse(split_wizard['res_id']) + + # Check default hr.expense.split values + self.assertRecordValues(wizard.expense_split_line_ids, [ + { + 'name': expense.name, + 'wizard_id': wizard.id, + 'expense_id': expense.id, + 'product_id': expense.product_id.id, + 'tax_ids': expense.tax_ids.ids, + 'total_amount': expense.total_amount / 2, + 'amount_tax': 6.52, + 'employee_id': expense.employee_id.id, + 'company_id': expense.company_id.id, + 'currency_id': expense.currency_id.id, + 'analytic_distribution': expense.analytic_distribution, + } for i in range(0, 2)]) + + self.assertEqual(wizard.split_possible, True) + self.assertEqual(wizard.total_amount, expense.total_amount) + + # Grant Analytic Accounting rights, to be able to modify analytic_distribution from the wizard + self.env.user.groups_id += self.env.ref('analytic.group_analytic_accounting') + + with Form(wizard) as form: + form.expense_split_line_ids.remove(index=0) + self.assertEqual(form.split_possible, False) + + # Check removing tax_ids and analytic_distribution + with form.expense_split_line_ids.edit(0) as line: + line.total_amount = 20 + line.tax_ids.clear() + line.analytic_distribution = {} + self.assertEqual(line.total_amount, 20) + self.assertEqual(line.amount_tax, 0) + + self.assertEqual(form.split_possible, False) + + # This line should have the same tax_ids and analytic_distribution as original expense + with form.expense_split_line_ids.new() as line: + line.total_amount = 30 + self.assertEqual(line.total_amount, 30) + self.assertEqual(line.amount_tax, 3.91) + self.assertEqual(form.split_possible, False) + self.assertEqual(form.total_amount, 50) + + # Check adding tax_ids and setting analytic_distribution + with form.expense_split_line_ids.new() as line: + line.total_amount = 50 + line.tax_ids.add(self.tax_purchase_b) + line.analytic_distribution = {self.analytic_account_2.id: 100} + self.assertEqual(line.total_amount, 50) + self.assertAlmostEqual(line.amount_tax, 11.54) + + # Check wizard values + self.assertEqual(form.total_amount, 100) + self.assertEqual(form.total_amount_original, 100) + self.assertAlmostEqual(form.total_amount_taxes, 15.45) + self.assertEqual(form.split_possible, True) + + wizard.action_split_expense() + # Check that split resulted into expenses with correct values + expenses_after_split = self.env['hr.expense'].search( + [ + ('name', '=', expense.name) + ] + ) + self.assertRecordValues(expenses_after_split.sorted('total_amount'), [ + { + 'name': expense.name, + 'employee_id': expense.employee_id.id, + 'product_id': expense.product_id.id, + 'total_amount': 20.0, + 'tax_ids': [], + 'amount_tax': 0, + 'untaxed_amount': 20, + 'analytic_distribution': False, + }, + { + 'name': expense.name, + 'employee_id': expense.employee_id.id, + 'product_id': expense.product_id.id, + 'total_amount': 30, + 'tax_ids': [self.tax_purchase_a.id], + 'amount_tax': 3.91, + 'untaxed_amount': 26.09, + 'analytic_distribution': {str(self.analytic_account_1.id): 100}, + }, + { + 'name': expense.name, + 'employee_id': expense.employee_id.id, + 'product_id': expense.product_id.id, + 'total_amount': 50, + 'tax_ids': [self.tax_purchase_a.id, self.tax_purchase_b.id], + 'amount_tax': 11.54, + 'untaxed_amount': 38.46, + 'analytic_distribution': {str(self.analytic_account_2.id): 100}, + } + ]) diff --git a/addons/hr_expense/wizard/hr_expense_split.py b/addons/hr_expense/wizard/hr_expense_split.py index 86d84308f40..c256f043982 100644 --- a/addons/hr_expense/wizard/hr_expense_split.py +++ b/addons/hr_expense/wizard/hr_expense_split.py @@ -70,7 +70,7 @@ class HrExpenseSplit(models.TransientModel): 'name': self.name, 'product_id': self.product_id.id, 'total_amount': self.total_amount, - 'tax_ids': self.tax_ids.ids, + 'tax_ids': [(6, 0, self.tax_ids.ids)], 'analytic_distribution': self.analytic_distribution, 'employee_id': self.employee_id.id, 'product_uom_id': self.product_id.uom_id.id,