Skip to content

Commit 433e5b4

Browse files
committed
[FIX] account: properly unlink tags when unlinking a tax report line, or impacting the tags trough tag_name or tax report modifications
closes odoo#71628 X-original-commit: 697952e Signed-off-by: Laurent Smet <[email protected]> Signed-off-by: oco-odoo <[email protected]>
1 parent 5733173 commit 433e5b4

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

addons/account/models/account_tax_report.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ def write(self, vals):
3131
new_tags = tags_cache[cache_key]
3232

3333
if new_tags:
34-
tags_to_unlink = line.tag_ids.filtered(lambda x: record == x.mapped('tax_report_line_ids.report_id'))
35-
# == 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
34+
line._remove_tags_used_only_by_self()
3635
line.write({'tag_ids': [(6, 0, new_tags.ids)]})
37-
self.env['account.tax.report.line']._delete_tags_from_taxes(tags_to_unlink.ids)
3836

3937
elif line.mapped('tag_ids.tax_report_line_ids.report_id').filtered(lambda x: x not in self):
38+
line._remove_tags_used_only_by_self()
4039
line.write({'tag_ids': [(5, 0, 0)] + line._get_tags_create_vals(line.tag_name, vals['country_id'])})
4140
tags_cache[cache_key] = line.tag_ids
4241

@@ -203,7 +202,7 @@ def write(self, vals):
203202
# All the lines sharing their tags must always be synchronized,
204203
tags_to_remove += records_to_link.mapped('tag_ids')
205204
records_to_link = tags_to_remove.mapped('tax_report_line_ids')
206-
self._delete_tags_from_taxes(tags_to_remove.ids)
205+
tags_to_remove.mapped('tax_report_line_ids')._remove_tags_used_only_by_self()
207206
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)]})
208207

209208
else:
@@ -220,17 +219,27 @@ def write(self, vals):
220219
return rslt
221220

222221
def unlink(self):
223-
self._delete_tags_from_taxes(self.mapped('tag_ids.id'))
222+
self._remove_tags_used_only_by_self()
224223
children = self.mapped('children_line_ids')
225224
if children:
226225
children.unlink()
227226
return super(AccountTaxReportLine, self).unlink()
228227

228+
def _remove_tags_used_only_by_self(self):
229+
""" Deletes and removes from taxes and move lines all the
230+
tags from the provided tax report lines that are not linked
231+
to any other tax report lines.
232+
"""
233+
all_tags = self.mapped('tag_ids')
234+
tags_to_unlink = all_tags.filtered(lambda x: not (x.tax_report_line_ids - self))
235+
self.write({'tag_ids': [(2, tag.id, 0) for tag in tags_to_unlink]})
236+
self._delete_tags_from_taxes(tags_to_unlink.ids)
237+
229238
@api.model
230239
def _delete_tags_from_taxes(self, tag_ids_to_delete):
231240
""" Based on a list of tag ids, removes them first from the
232241
repartition lines they are linked to, then deletes them
233-
from the account move lines.
242+
from the account move lines, and finally unlink them.
234243
"""
235244
if not tag_ids_to_delete:
236245
# Nothing to do, then!
@@ -247,6 +256,8 @@ def _delete_tags_from_taxes(self, tag_ids_to_delete):
247256
self.env['account.move.line'].invalidate_cache(fnames=['tax_tag_ids'])
248257
self.env['account.tax.repartition.line'].invalidate_cache(fnames=['tag_ids'])
249258

259+
self.env['account.account.tag'].browse(tag_ids_to_delete).unlink()
260+
250261
@api.constrains('formula', 'tag_name')
251262
def _validate_formula(self):
252263
for record in self:

addons/account/tests/test_tax_report.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ def setUpClass(cls, chart_template_ref=None):
6868
'sequence': 7,
6969
})
7070

71+
cls.tax_report_line_1_6 = cls.env['account.tax.report.line'].create({
72+
'name': "[100] Line 100",
73+
'tag_name': '100',
74+
'report_id': cls.tax_report_1.id,
75+
'sequence': 8,
76+
})
77+
7178
cls.tax_report_2 = cls.env['account.tax.report'].create({
7279
'name': "Tax report 2",
7380
'country_id': cls.test_country_1.id,
@@ -93,6 +100,13 @@ def setUpClass(cls, chart_template_ref=None):
93100
'sequence': 3,
94101
})
95102

103+
cls.tax_report_line_2_6 = cls.env['account.tax.report.line'].create({
104+
'name': "[100] Line 100",
105+
'tag_name': '100',
106+
'report_id': cls.tax_report_2.id,
107+
'sequence': 4,
108+
})
109+
96110
def _get_tax_tags(self, tag_name=None):
97111
domain = [('country_id', '=', self.test_country_1.id), ('applicability', '=', 'taxes')]
98112
if tag_name:
@@ -255,3 +269,17 @@ def test_tax_report_change_country(self):
255269
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")
256270
elif line.tag_ids or original_report_2_tags[line.id]:
257271
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")
272+
273+
def test_unlink_report_line_tags(self):
274+
""" Under certain circumstances, unlinking a tax report line should also unlink
275+
the tags that are linked to it. We test those cases here.
276+
"""
277+
def check_tags_unlink(tag_name, report_lines, unlinked, error_message):
278+
report_lines.unlink()
279+
surviving_tags = self._get_tax_tags(tag_name)
280+
required_len = 0 if unlinked else 2 # 2 for + and - tag
281+
self.assertEqual(len(surviving_tags), required_len, error_message)
282+
283+
check_tags_unlink('42', self.tax_report_line_2_42, True, "Unlinking one line not sharing its tags should also unlink them")
284+
check_tags_unlink('01', self.tax_report_line_1_1, False, "Unlinking one line sharing its tags with others should keep the tags")
285+
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")

0 commit comments

Comments
 (0)