[FIX] hr_expense: correctly update tax_ids after splitting the expense
The - Split Expense - feature was introduced in odoo/odoo#90770 In this commit we fix the following bug, related to it: Steps to reproduce: - Create expense with tax_ids. - Click on - Split expense on the expense form. From the first hr.expense.split line remove the tax_ids. Rename it as '1', so that it is easier to find it back for checking later on. - Click on - Expense split on the wizard. Check the resulting expenses. Specifically, the one with the name '1'. Current behavior - The tax_ids field for the first expense (with the name '1') is still populated. Expected - The tax_ids field for the first expense should be empty. On top of that, we introduce the tests that check Split Expense flow. task - 2831024 closes odoo/odoo#108049 X-original-commit: 3aaf4f1ee2967793c9a4c29766cec63d2c6e3cf4 Related: odoo/enterprise#35005 Signed-off-by: Kevin Baptiste <kba@odoo.com>
This commit is contained in:
@@ -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!"))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
])
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user