[FIX] account: properly unlink tags when unlinking a tax report line, or impacting the tags trough tag_name or tax report modifications

closes odoo/odoo#71635

X-original-commit: 697952ef2d806134f53d2eb464a5173ddb3a05d8
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-06-02 17:10:19 +00:00
parent af546b7b35
commit 8d385119ed
2 changed files with 45 additions and 6 deletions
+17 -6
View File
@@ -31,12 +31,11 @@ class AccountTaxReport(models.Model):
new_tags = tags_cache[cache_key]
if new_tags:
tags_to_unlink = line.tag_ids.filtered(lambda x: record == x.mapped('tax_report_line_ids.report_id'))
# == instead of in, as we only want tags_to_unlink to contain the tags that are not linked to any other report than the one we're considering
line._remove_tags_used_only_by_self()
line.write({'tag_ids': [(6, 0, new_tags.ids)]})
self.env['account.tax.report.line']._delete_tags_from_taxes(tags_to_unlink.ids)
elif line.mapped('tag_ids.tax_report_line_ids.report_id').filtered(lambda x: x not in self):
line._remove_tags_used_only_by_self()
line.write({'tag_ids': [(5, 0, 0)] + line._get_tags_create_vals(line.tag_name, vals['country_id'])})
tags_cache[cache_key] = line.tag_ids
@@ -225,7 +224,7 @@ class AccountTaxReportLine(models.Model):
# All the lines sharing their tags must always be synchronized,
tags_to_remove += records_to_link.mapped('tag_ids')
records_to_link = tags_to_remove.mapped('tax_report_line_ids')
self._delete_tags_from_taxes(tags_to_remove.ids)
tags_to_remove.mapped('tax_report_line_ids')._remove_tags_used_only_by_self()
records_to_link.write({'tag_name': tag_name_postponed, 'tag_ids': [(2, tag.id) for tag in tags_to_remove] + [(6, 0, existing_tags.ids)]})
else:
@@ -242,17 +241,27 @@ class AccountTaxReportLine(models.Model):
return rslt
def unlink(self):
self._delete_tags_from_taxes(self.mapped('tag_ids.id'))
self._remove_tags_used_only_by_self()
children = self.mapped('children_line_ids')
if children:
children.unlink()
return super(AccountTaxReportLine, self).unlink()
def _remove_tags_used_only_by_self(self):
""" Deletes and removes from taxes and move lines all the
tags from the provided tax report lines that are not linked
to any other tax report lines.
"""
all_tags = self.mapped('tag_ids')
tags_to_unlink = all_tags.filtered(lambda x: not (x.tax_report_line_ids - self))
self.write({'tag_ids': [(2, tag.id, 0) for tag in tags_to_unlink]})
self._delete_tags_from_taxes(tags_to_unlink.ids)
@api.model
def _delete_tags_from_taxes(self, tag_ids_to_delete):
""" Based on a list of tag ids, removes them first from the
repartition lines they are linked to, then deletes them
from the account move lines.
from the account move lines, and finally unlink them.
"""
if not tag_ids_to_delete:
# Nothing to do, then!
@@ -269,6 +278,8 @@ class AccountTaxReportLine(models.Model):
self.env['account.move.line'].invalidate_cache(fnames=['tax_tag_ids'])
self.env['account.tax.repartition.line'].invalidate_cache(fnames=['tag_ids'])
self.env['account.account.tag'].browse(tag_ids_to_delete).unlink()
@api.constrains('formula', 'tag_name')
def _validate_formula(self):
for record in self:
+28
View File
@@ -64,6 +64,13 @@ class TaxReportTest(AccountTestInvoicingCommon):
'sequence': 7,
})
cls.tax_report_line_1_6 = cls.env['account.tax.report.line'].create({
'name': "[100] Line 100",
'tag_name': '100',
'report_id': cls.tax_report_1.id,
'sequence': 8,
})
cls.tax_report_2 = cls.env['account.tax.report'].create({
'name': "Tax report 2",
'country_id': cls.test_country_1.id,
@@ -89,6 +96,13 @@ class TaxReportTest(AccountTestInvoicingCommon):
'sequence': 3,
})
cls.tax_report_line_2_6 = cls.env['account.tax.report.line'].create({
'name': "[100] Line 100",
'tag_name': '100',
'report_id': cls.tax_report_2.id,
'sequence': 4,
})
def _get_tax_tags(self, tag_name=None):
domain = [('country_id', '=', self.test_country_1.id), ('applicability', '=', 'taxes')]
if tag_name:
@@ -255,3 +269,17 @@ class TaxReportTest(AccountTestInvoicingCommon):
self.assertEqual(line.tag_ids.ids, original_report_2_tags[line.id], "The tax report lines not sharing their tags with any other report should keep the same tags when the country of their report is changed")
elif line.tag_ids or original_report_2_tags[line.id]:
self.assertNotEqual(line.tag_ids.ids, original_report_2_tags[line.id], "The tax report lines sharing their tags with other report should receive new tags when the country of their report is changed")
def test_unlink_report_line_tags(self):
""" Under certain circumstances, unlinking a tax report line should also unlink
the tags that are linked to it. We test those cases here.
"""
def check_tags_unlink(tag_name, report_lines, unlinked, error_message):
report_lines.unlink()
surviving_tags = self._get_tax_tags(tag_name)
required_len = 0 if unlinked else 2 # 2 for + and - tag
self.assertEqual(len(surviving_tags), required_len, error_message)
check_tags_unlink('42', self.tax_report_line_2_42, True, "Unlinking one line not sharing its tags should also unlink them")
check_tags_unlink('01', self.tax_report_line_1_1, False, "Unlinking one line sharing its tags with others should keep the tags")
check_tags_unlink('100', self.tax_report_line_1_6 + self.tax_report_line_2_6, True, "Unlinkink all the lines sharing the same tags should also unlink them")