From 0afbefca21eca195360f85198c5bfbf1e9c3503d Mon Sep 17 00:00:00 2001 From: william-andre Date: Tue, 22 Feb 2022 14:21:46 +0000 Subject: [PATCH] [FIX] account: formula/tag conflict on tax report lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) Co-authored-by: william-andre Co-authored-by: aj-fuentes --- addons/account/models/account_tax_report.py | 23 ++++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/addons/account/models/account_tax_report.py b/addons/account/models/account_tax_report.py index 72421118006..51a94471cf2 100644 --- a/addons/account/models/account_tax_report.py +++ b/addons/account/models/account_tax_report.py @@ -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