[FIX] account: tax computation: when forcing the tags on caba taxes, also force the account
Cash basis taxes use a distinct transition account on their tax lines; the tax account set on the repartition lines is only used when the payment is received, on the cash basis move. In enterprise, the bank reconciliation widget allows setting a tax on the manual write-off done for a statement line. When doing so, we expect the tax to behave just like on an invoice. For cash basis taxes, this means the "final" tax account has to be used instead of the transition one ; it wasn't the case. OPW 3255511 X-original-commit: 991fa46081296c3560bd7ca195996693a81a46b8 Part-of: odoo/odoo#120924
This commit is contained in:
@@ -741,7 +741,7 @@ class AccountTax(models.Model):
|
||||
'amount': sign * line_amount,
|
||||
'base': float_round(sign * tax_base_amount, precision_rounding=prec),
|
||||
'sequence': tax.sequence,
|
||||
'account_id': repartition_line._get_aml_target_tax_account().id,
|
||||
'account_id': repartition_line._get_aml_target_tax_account(force_caba_exigibility=include_caba_tags).id,
|
||||
'analytic': tax.analytic,
|
||||
'use_in_tax_closing': repartition_line.use_in_tax_closing,
|
||||
'price_include': price_include,
|
||||
@@ -825,7 +825,7 @@ class AccountTax(models.Model):
|
||||
}
|
||||
|
||||
@api.model
|
||||
def _get_generation_dict_from_base_line(self, line_vals, tax_vals):
|
||||
def _get_generation_dict_from_base_line(self, line_vals, tax_vals, force_caba_exigibility=False):
|
||||
""" Take a tax results returned by the taxes computation method and return a dictionary representing the way
|
||||
the tax amounts will be grouped together. To do so, the dictionary will be converted into a string key.
|
||||
Then, the existing tax lines sharing the same key will be updated and the missing ones will be created.
|
||||
@@ -835,7 +835,7 @@ class AccountTax(models.Model):
|
||||
:return: A python dict.
|
||||
"""
|
||||
tax_repartition_line = tax_vals['tax_repartition_line']
|
||||
tax_account = tax_repartition_line._get_aml_target_tax_account() or line_vals['account']
|
||||
tax_account = tax_repartition_line._get_aml_target_tax_account(force_caba_exigibility=force_caba_exigibility) or line_vals['account']
|
||||
return {
|
||||
'account_id': tax_account.id,
|
||||
'currency_id': line_vals['currency'].id,
|
||||
@@ -1129,7 +1129,7 @@ class AccountTax(models.Model):
|
||||
existing_tax_line_map[grouping_key] = line_vals
|
||||
|
||||
def grouping_key_generator(base_line, tax_values):
|
||||
return self._get_generation_dict_from_base_line(base_line, tax_values)
|
||||
return self._get_generation_dict_from_base_line(base_line, tax_values, force_caba_exigibility=include_caba_tags)
|
||||
|
||||
# Update/create the tax lines.
|
||||
global_tax_details = self._aggregate_taxes(to_process, grouping_key_generator=grouping_key_generator)
|
||||
@@ -1387,13 +1387,13 @@ class AccountTaxRepartitionLine(models.Model):
|
||||
if self.repartition_type == 'base':
|
||||
self.account_id = None
|
||||
|
||||
def _get_aml_target_tax_account(self):
|
||||
def _get_aml_target_tax_account(self, force_caba_exigibility=False):
|
||||
""" Get the default tax account to set on a business line.
|
||||
|
||||
:return: An account.account record or an empty recordset.
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.tax_id.tax_exigibility == 'on_payment' and not self._context.get('caba_no_transition_account'):
|
||||
if not force_caba_exigibility and self.tax_id.tax_exigibility == 'on_payment' and not self._context.get('caba_no_transition_account'):
|
||||
return self.tax_id.cash_basis_transition_account_id
|
||||
else:
|
||||
return self.account_id
|
||||
|
||||
@@ -906,3 +906,62 @@ class TestAccountMove(AccountTestInvoicingCommon):
|
||||
self.assertTrue(exchange_diff)
|
||||
with self.assertRaises(UserError), self.cr.savepoint():
|
||||
exchange_diff.button_draft()
|
||||
|
||||
def test_always_exigible_caba_account(self):
|
||||
""" Always exigible misc operations (so, the ones without payable/receivable line) with cash basis
|
||||
taxes should see their tax lines use the final tax account, not the transition account.
|
||||
"""
|
||||
tax_account = self.company_data['default_account_tax_sale']
|
||||
|
||||
caba_tax = self.env['account.tax'].create({
|
||||
'name': "CABA",
|
||||
'amount_type': 'percent',
|
||||
'amount': 20.0,
|
||||
'tax_exigibility': 'on_payment',
|
||||
'cash_basis_transition_account_id': self.safe_copy(tax_account).id,
|
||||
'invoice_repartition_line_ids': [
|
||||
(0, 0, {
|
||||
'repartition_type': 'base',
|
||||
}),
|
||||
(0, 0, {
|
||||
'repartition_type': 'tax',
|
||||
'account_id': tax_account.id,
|
||||
}),
|
||||
],
|
||||
'refund_repartition_line_ids': [
|
||||
(0, 0, {
|
||||
'repartition_type': 'base',
|
||||
}),
|
||||
(0, 0, {
|
||||
'repartition_type': 'tax',
|
||||
'account_id': tax_account.id,
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
move_form = Form(self.env['account.move'].with_context(default_move_type='entry'))
|
||||
|
||||
# Create a new account.move.line with debit amount.
|
||||
income_account = self.company_data['default_account_revenue']
|
||||
with move_form.line_ids.new() as debit_line:
|
||||
debit_line.name = 'debit'
|
||||
debit_line.account_id = income_account
|
||||
debit_line.debit = 120
|
||||
|
||||
with move_form.line_ids.new() as credit_line:
|
||||
credit_line.name = 'credit'
|
||||
credit_line.account_id = income_account
|
||||
credit_line.credit = 100
|
||||
credit_line.tax_ids.clear()
|
||||
credit_line.tax_ids.add(caba_tax)
|
||||
|
||||
move = move_form.save()
|
||||
|
||||
self.assertTrue(move.always_tax_exigible)
|
||||
|
||||
self.assertRecordValues(move.line_ids.sorted(lambda x: -x.balance), [
|
||||
# pylint: disable=C0326
|
||||
{'name': 'debit', 'debit': 120.0, 'credit': 0.0, 'account_id': income_account.id, 'tax_ids': [], 'tax_line_id': False},
|
||||
{'name': 'CABA', 'debit': 0.0, 'credit': 20.0, 'account_id': tax_account.id, 'tax_ids': [], 'tax_line_id': caba_tax.id},
|
||||
{'name': 'credit', 'debit': 0.0, 'credit': 100.0, 'account_id': income_account.id, 'tax_ids': caba_tax.ids, 'tax_line_id': False},
|
||||
])
|
||||
|
||||
@@ -29,10 +29,10 @@ class AccountTax(models.Model):
|
||||
l10n_in_reverse_charge = fields.Boolean("Reverse charge", help="Tick this if this tax is reverse charge. Only for Indian accounting")
|
||||
|
||||
@api.model
|
||||
def _get_generation_dict_from_base_line(self, line_vals, tax_vals):
|
||||
def _get_generation_dict_from_base_line(self, line_vals, tax_vals, force_caba_exigibility=False):
|
||||
# EXTENDS account
|
||||
# Group taxes also by product.
|
||||
res = super()._get_generation_dict_from_base_line(line_vals, tax_vals)
|
||||
res = super()._get_generation_dict_from_base_line(line_vals, tax_vals, force_caba_exigibility=force_caba_exigibility)
|
||||
record = line_vals['record']
|
||||
if isinstance(record, models.Model)\
|
||||
and record._name == 'account.move.line'\
|
||||
|
||||
Reference in New Issue
Block a user