[IMP] account: make use of fiscal positions in write-offs created by reconciliation models

Before, the taxes assigned by the reconciliation models in their write-offs weren't mapped by fiscal positions. This could cause confusion, and essentially required the user to always fix by hand the cases that weren't matched.

Task 2645280

closes odoo/odoo#77204

X-original-commit: e75184459a7d47df86aa72efa36c06462d7ee9ea
Related: odoo/enterprise#21187
Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
This commit is contained in:
oco-odoo
2021-09-27 16:56:42 +00:00
parent 45c4a29e82
commit 8873e2015f
2 changed files with 63 additions and 6 deletions
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo import api, fields, models, Command, _
from odoo.tools import float_compare, float_is_zero
from odoo.osv.expression import get_unaccent_wrapper
from odoo.exceptions import UserError, ValidationError
@@ -356,7 +356,7 @@ class AccountReconcileModel(models.Model):
base_line_dict['tax_tag_ids'] = [(6, 0, res['base_tags'])]
return new_aml_dicts
def _get_write_off_move_lines_dict(self, st_line, residual_balance):
def _get_write_off_move_lines_dict(self, st_line, residual_balance, partner_id):
''' Get move.lines dict (to be passed to the create()) corresponding to the reconciliation model's write-off lines.
:param st_line: An account.bank.statement.line record.(possibly empty, if performing manual reconciliation)
:param residual_balance: The residual balance of the statement line.
@@ -420,13 +420,16 @@ class AccountReconcileModel(models.Model):
residual_balance -= balance
if line.tax_ids:
writeoff_line['tax_ids'] = [(6, None, line.tax_ids.ids)]
tax = line.tax_ids
taxes = line.tax_ids
detected_fiscal_position = self.env['account.fiscal.position'].get_fiscal_position(partner_id)
if detected_fiscal_position:
taxes = detected_fiscal_position.map_tax(taxes)
writeoff_line['tax_ids'] = [Command.set(taxes.ids)]
# Multiple taxes with force_tax_included results in wrong computation, so we
# only allow to set the force_tax_included field if we have one tax selected
if line.force_tax_included:
tax = tax[0].with_context(force_price_include=True)
tax_vals_list = self._get_taxes_move_lines_dict(tax, writeoff_line)
taxes = taxes[0].with_context(force_price_include=True)
tax_vals_list = self._get_taxes_move_lines_dict(taxes, writeoff_line)
lines_vals_list += tax_vals_list
if not line.force_tax_included:
for tax_line in tax_vals_list:
@@ -828,6 +831,7 @@ class AccountReconcileModel(models.Model):
writeoff_vals_list = self._get_write_off_move_lines_dict(
st_line,
matched_candidates_values['balance_sign'] * residual_balance_after_rec,
partner.id,
)
if writeoff_vals_list:
rslt['status'] = 'write_off'
@@ -1043,6 +1047,7 @@ class AccountReconcileModel(models.Model):
writeoff_vals_list = self._get_write_off_move_lines_dict(
st_line,
matched_candidates_values['balance_sign'] * residual_balance_after_rec,
partner.id,
)
rslt = {
@@ -807,6 +807,58 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
{'partner_id': self.partner_1.id, 'debit': 7.26, 'credit': 0.0, 'tax_ids': [], 'tax_line_id': self.tax12.id},
])
def test_auto_reconcile_with_tax_fpos(self):
""" Test the fiscal positions are applied by reconcile models when using taxes.
"""
self.rule_1.write({
'auto_reconcile': True,
'rule_type': 'writeoff_suggestion',
'line_ids': [(1, self.rule_1.line_ids.id, {
'amount': 100,
'force_tax_included': True,
'tax_ids': [(6, 0, self.tax21.ids)],
})]
})
self.partner_1.country_id = self.env.ref('base.lu')
belgium = self.env.ref('base.be')
self.partner_2.country_id = belgium
self.bank_line_2.partner_id = self.partner_2
self.bank_line_1.amount = -121
self.bank_line_2.amount = -112
self.env['account.fiscal.position'].create({
'name': "Test",
'country_id': belgium.id,
'auto_apply': True,
'tax_ids': [
Command.create({
'tax_src_id': self.tax21.id,
'tax_dest_id': self.tax12.id,
}),
]
})
self._check_statement_matching(self.rule_1, {
self.bank_line_1.id: {'aml_ids': [], 'model': self.rule_1, 'status': 'reconciled', 'partner': self.bank_line_1.partner_id},
self.bank_line_2.id: {'aml_ids': [], 'model': self.rule_1, 'status': 'reconciled', 'partner': self.bank_line_2.partner_id},
}, statements=self.bank_st)
self.assertRecordValues(self.bank_line_1.line_ids, [
{'partner_id': self.partner_1.id, 'debit': 0.0, 'credit': 121.0, 'tax_ids': [], 'tax_line_id': False},
{'partner_id': self.partner_1.id, 'debit': 100.0, 'credit': 0.0, 'tax_ids': [self.tax21.id], 'tax_line_id': False},
{'partner_id': self.partner_1.id, 'debit': 21.0, 'credit': 0.0, 'tax_ids': [], 'tax_line_id': self.tax21.id},
])
self.assertRecordValues(self.bank_line_2.line_ids, [
{'partner_id': self.partner_2.id, 'debit': 0.0, 'credit': 112.0, 'tax_ids': [], 'tax_line_id': False},
{'partner_id': self.partner_2.id, 'debit': 100.0, 'credit': 0.0, 'tax_ids': [self.tax12.id], 'tax_line_id': False},
{'partner_id': self.partner_2.id, 'debit': 12.0, 'credit': 0.0, 'tax_ids': [], 'tax_line_id': self.tax12.id},
])
def test_reverted_move_matching(self):
partner = self.partner_1
AccountMove = self.env['account.move']