[FIX] account: formula/tag conflict on tax report lines

When removing a tag_name but adding a forumula instead[1], postponing the
constraint made the constraint `_validate_formula` fail because we were
writing on `formula` before writing on `tag_name`, and both were non
null in that transient state.

[1] https://github.com/odoo/odoo/commit/1c184391d545298b9b38d4935a6e457ba7674f43#diff-f24beb4fa8533b0bb6f95ecb84b749c2f20991803142ed11282dcce944799098R187-R190

closes odoo/odoo#85174

X-original-commit: ecf4e6f8a6cf1eb99b689f9fe9088d5cad4dfa34
Signed-off-by: William André (wan) <wan@odoo.com>
Co-authored-by: william-andre <wan@odoo.com>
Co-authored-by: aj-fuentes <afu@odoo.com>
This commit is contained in:
william-andre
2022-02-22 21:05:44 +00:00
co-authored by aj-fuentes
parent 8a5c8a3cb9
commit 0afbefca21
+13 -10
View File
@@ -249,20 +249,23 @@ class AccountTaxReportLine(models.Model):
return [(0, 0, minus_tag_vals), (0, 0, plus_tag_vals)]
def write(self, vals):
tag_name_postponed = None
# If tag_name was set, but not tag_ids, we postpone the write of
# tag_name, and perform it only after having generated/retrieved the tags.
# Otherwise, tag_name and tags' name would not match, breaking
# _validate_tags constaint.
postpone_tag_name = 'tag_name' in vals and not 'tag_ids' in vals
postponed_vals = {}
if postpone_tag_name:
tag_name_postponed = vals.pop('tag_name')
if 'tag_name' in vals and 'tag_ids' not in vals:
postponed_vals = {'tag_name': vals.pop('tag_name')}
tag_name_postponed = postponed_vals['tag_name']
# if tag_name is posponed then we also postpone formula to avoid
# breaking _validate_formula constraint
if 'formula' in vals:
postponed_vals['formula'] = vals.pop('formula')
rslt = super(AccountTaxReportLine, self).write(vals)
if postpone_tag_name:
if postponed_vals:
# If tag_name modification has been postponed,
# we need to search for existing tags corresponding to the new tag name
# (or create them if they don't exist yet) and assign them to the records
@@ -283,7 +286,7 @@ class AccountTaxReportLine(models.Model):
minus_child_tags.write({'name': '-' + tag_name_postponed})
plus_child_tags = tags_to_update.filtered(lambda x: not x.tax_negate)
plus_child_tags.write({'name': '+' + tag_name_postponed})
super(AccountTaxReportLine, to_update).write({'tag_name': tag_name_postponed})
super(AccountTaxReportLine, to_update).write(postponed_vals)
else:
existing_tags = self.env['account.account.tag']._get_tax_tags(tag_name_postponed, country_id)
@@ -295,7 +298,7 @@ class AccountTaxReportLine(models.Model):
# linking it to the first report line of the record set
first_record = records_to_link[0]
tags_to_remove += first_record.tag_ids
first_record.write({'tag_name': tag_name_postponed, 'tag_ids': [(5, 0, 0)] + self._get_tags_create_vals(tag_name_postponed, country_id)})
first_record.write({**postponed_vals, 'tag_ids': [(5, 0, 0)] + self._get_tags_create_vals(tag_name_postponed, country_id)})
existing_tags = first_record.tag_ids
records_to_link -= first_record
@@ -303,7 +306,7 @@ class AccountTaxReportLine(models.Model):
tags_to_remove += records_to_link.mapped('tag_ids')
records_to_link = tags_to_remove.mapped('tax_report_line_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)]})
records_to_link.write({**postponed_vals, 'tag_ids': [(2, tag.id) for tag in tags_to_remove] + [(6, 0, existing_tags.ids)]})
else:
# tag_name was set empty, so we remove the tags on current lines
@@ -314,7 +317,7 @@ class AccountTaxReportLine(models.Model):
if not other_lines_same_tag:
self._delete_tags_from_taxes(line_tags.ids)
orm_cmd_code = other_lines_same_tag and 3 or 2
records.write({'tag_name': None, 'tag_ids': [(orm_cmd_code, tag.id) for tag in line_tags]})
records.write({**postponed_vals, 'tag_ids': [(orm_cmd_code, tag.id) for tag in line_tags]})
return rslt