From 00b40aafeed475c93e08e5a34592c1e80c325198 Mon Sep 17 00:00:00 2001 From: Luis Fernando Limon Tenorio Date: Mon, 26 Oct 2026 01:45:12 -0600 Subject: [PATCH] [FIX] openupgrade_framework: adapt patches to v20 - keep the attachments of removed models: v20 added IrModel._unlink_related_attachments, which deletes them (incl. binary field data) when obsolete models are unlinked in _process_end - validate views one by one: the warning handler read xml_id/model on a multi-record recordset, raising 'Expected singleton' - also catch the errors raised after a swallowed _raise_view_error - use the cursor's savepoint helper in unlink (uuid4 was never called and savepoints were never released) - respect country_ids when auto installing modules in update_list --- .../odoo/addons/base/models/ir_model.py | 19 ++++++++++- .../odoo/addons/base/models/ir_module.py | 4 +++ .../odoo/addons/base/models/ir_ui_view.py | 32 ++++++++++++------- .../odoo_patch/odoo/orm/models.py | 11 ++----- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_model.py b/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_model.py index 11c1864b2540..89ecb71f38e3 100644 --- a/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_model.py +++ b/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_model.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openupgradelib import openupgrade -from odoo import models +from odoo import api, models from odoo.addons.base.models.ir_model import ( IrModel, @@ -28,6 +28,23 @@ def _drop_table(self): IrModel._drop_table = _drop_table +@api.ondelete(at_uninstall=False) +def _unlink_related_attachments(self): + """Never delete attachments (incl. binary field data) of removed models""" + for model in self: + openupgrade.message( + self.env.cr, + "Unknown", + False, + False, + "Not deleting the attachments of model %s", + model.model, + ) + + +IrModel._unlink_related_attachments = _unlink_related_attachments + + def _drop_column(self): """Never drop columns""" for field in self: diff --git a/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_module.py b/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_module.py index b71e0f78534f..740c35fbdc68 100644 --- a/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_module.py +++ b/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_module.py @@ -15,6 +15,7 @@ def update_list(self): """ result = IrModuleModule.update_list._original_method(self) new_auto_install_modules = self.browse([]) + company_countries = self.env["res.company"].sudo().search([]).country_id for module in self.env["ir.module.module"].search( [ ("auto_install", "=", True), @@ -22,6 +23,9 @@ def update_list(self): ("name", "not like", ("l10n_%")), ] ): + # same rule as button_install + if module.country_ids and not module.country_ids & company_countries: + continue if all( state in ("to upgrade", "to install", "installed") for state in module.dependencies_id.mapped("state") diff --git a/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_ui_view.py b/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_ui_view.py index 8b82f5f3a84a..8051e712cbb5 100644 --- a/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_ui_view.py +++ b/openupgrade_framework/odoo_patch/odoo/addons/base/models/ir_ui_view.py @@ -16,18 +16,26 @@ def _check_xml(self): """Don't raise or log exceptions in view validation unless explicitly requested. Mute warnings about views which are common during migration.""" with mute_logger("odoo.addons.base.models.ir_ui_view"): - try: - return IrUiView._check_xml._original_method(self) - except ValidationError as e: - _logger.warning( - "Can't render custom view %s for model %s. " - "Assuming you are migrating between major versions of Odoo. " - "Please review the view contents manually after the migration.\n" - "Error: %s", - self.xml_id, - self.model, - e, - ) + for view in self: + try: + IrUiView._check_xml._original_method(view) + # with _raise_view_error not raising, validation can fail later on + except ( + ValidationError, + ValueError, + AttributeError, + KeyError, + NameError, + ) as e: + _logger.warning( + "Can't render custom view %s for model %s. " + "Assuming you are migrating between major versions of Odoo. " + "Please review the view contents manually after the migration.\n" + "Error: %s", + view.xml_id, + view.model, + e, + ) def _raise_view_error( diff --git a/openupgrade_framework/odoo_patch/odoo/orm/models.py b/openupgrade_framework/odoo_patch/odoo/orm/models.py index 314147eae39f..57a9cece3d60 100644 --- a/openupgrade_framework/odoo_patch/odoo/orm/models.py +++ b/openupgrade_framework/odoo_patch/odoo/orm/models.py @@ -1,7 +1,6 @@ # Copyright Odoo Community Association (OCA) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging -from uuid import uuid4 from odoo.models import BaseModel @@ -19,16 +18,10 @@ def unlink(self): """ if not self.env.context.get(MODULE_UNINSTALL_FLAG): return BaseModel.unlink._original_method(self) - savepoint = str(uuid4) try: - self.env.cr.execute( # pylint: disable=sql-injection - f'SAVEPOINT "{savepoint}"' - ) - return BaseModel.unlink._original_method(self) + with self.env.cr.savepoint(): + return BaseModel.unlink._original_method(self) except Exception as e: - self.env.cr.execute( # pylint: disable=sql-injection - f'ROLLBACK TO SAVEPOINT "{savepoint}"' - ) _logger.warning( "Could not delete obsolete record with ids %s of model %s", self.ids,