From 3f96cff0aa5097a386c289cf9fd2aeb3048376ab Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Tue, 12 Jan 2021 18:40:46 +0000 Subject: [FIX] base, website: replicate inherit_id update on cow view Before this commit, only whitelisted fields would be updated on cow views during a module update. A field would be whitelisted if he had the same value than the original view, see it as a heuristic to not write on modified fields. But `inherit_id` is not that simple, even if the cow view has a different value than its original view, it doesn't mean it was modified by the user, it is just because of the cow mechanism that assigned a copied view as inherit_id, which is just a copy ofthe original one. We can thus consider `inherit_id` as unchanged and whitelist it if the `key` is the same. In practice, it means that cow'd views did not receive the `inherit_id` updates as in commit https://github.com/odoo/odoo/commit/c8577568a1e39f6692889b3e21652fa3b8df06b2#diff-823e5db841dca1798ff1300e243059a4e1c93343598d2be5a1d1dcd1d2d0c273R537 where `portal.my_account_link` had its `inherit_id` changed from `portal.frontend_layout` to `portal.user_dropdow`, see https://github.com/odoo/upgrade/pull/2059: Considering a module update changing `inherit_id` of D from A to B, the following use cases are expected. Without this fix, D' never move: CASE 1 A A' B A A' B | | => / \ D D' D D' CASE 2 A A' B B' A A' B B' | | => | | D D' D D' CASE 3 A B A B / \ => / \ D D' D D' CASE 4 A B B' A B B' / \ => | | D D' D D' Opw: 2422773 Opw: 2422727 Opw: 2422770 Opw: 2423406 Opw: 2423859 X-original-commit: 2951ed681aa5e31563e501de691716806ddb46bd --- odoo/addons/base/models/ir_ui_view.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'odoo') diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py index c77316d4557..a042859dc82 100644 --- a/odoo/addons/base/models/ir_ui_view.py +++ b/odoo/addons/base/models/ir_ui_view.py @@ -1826,15 +1826,32 @@ actual arch. noupdate behavior on views having an ir.model.data. """ if self.type == 'qweb': - # Update also specific views for cow_view in self._get_specific_views(): authorized_vals = {} for key in values: - if cow_view[key] == self[key]: + if key != 'inherit_id' and cow_view[key] == self[key]: authorized_vals[key] = values[key] - cow_view.write(authorized_vals) + # if inherit_id update, replicate change on cow view but + # only if that cow view inherit_id wasn't manually changed + inherit_id = values.get('inherit_id') + if inherit_id and self.inherit_id.id != inherit_id and \ + cow_view.inherit_id.key == self.inherit_id.key: + self._load_records_write_on_cow(cow_view, inherit_id, authorized_vals) + else: + cow_view.with_context(no_cow=True).write(authorized_vals) super(View, self)._load_records_write(values) + def _load_records_write_on_cow(self, cow_view, inherit_id, values): + # for modules updated before `website`, we need to + # store the change to replay later on cow views + if not hasattr(self.pool, 'website_views_to_adapt'): + self.pool.website_views_to_adapt = [] + self.pool.website_views_to_adapt.append(( + cow_view.id, + inherit_id, + values, + )) + class ResetViewArchWizard(models.TransientModel): """ A wizard to compare and reset views architecture. """ -- cgit v1.2.3