diff --git a/src/base/tests/test_util.py b/src/base/tests/test_util.py index 7cf6ace30..58ecb3bca 100644 --- a/src/base/tests/test_util.py +++ b/src/base/tests/test_util.py @@ -1131,6 +1131,31 @@ def test_invert_boolean_field(self): initial_repartition[False] += initial_repartition.pop(None, 0) self.assertEqual(back_repartition, initial_repartition) + def test_change_field_selection_with_default(self): + cr = self.env.cr + lang = self.env["res.lang"].create({"name": "Elvish", "code": "el_VISH", "active": True}) + if util.table_exists(cr, "ir_default"): + self.env["ir.default"].set("res.partner", "lang", "el_VISH") + else: + self.env["ir.values"].set_default("res.partner", "lang", "el_VISH") + util.flush(lang) + partner = self.env["res.partner"].create({"name": "Gandalf"}) + self.assertEqual(partner.lang, "el_VISH") + + util.invalidate(partner) + util.change_field_selection_values(cr, "res.partner", "lang", {"el_VISH": "en_US"}) + + self.assertEqual(partner.lang, "en_US") + + if util.table_exists(cr, "ir_default"): + new_default = (getattr(self.env["ir.default"], "get", None) or self.env["ir.default"]._get)( + "res.partner", "lang" + ) + else: + new_default = self.env["ir.values"].get_default("res.partner", "lang") + + self.assertEqual(new_default, "en_US") + class TestHelpers(UnitTestCase): def test_model_table_conversion(self): diff --git a/src/util/fields.py b/src/util/fields.py index dcd03dbca..9c6defc47 100644 --- a/src/util/fields.py +++ b/src/util/fields.py @@ -38,6 +38,12 @@ def make_index_name(table_name, column_name): return "%s_%s_index" % (table_name, column_name) +try: + from odoo.tools import pickle +except ImportError: + import pickle + + from . import json from .const import ENVIRON from .domains import _adapt_one_domain, _replace_path, _valid_path_to, adapt_domains @@ -1187,6 +1193,35 @@ def change_field_selection_values(cr, model, field, mapping, skip_inherit=()): [model, field, [k for k in mapping if k not in mapping.values()]], ) + if table_exists(cr, "ir_values"): + query = """ + UPDATE ir_values + SET value = %(json)s::jsonb->>value + WHERE model = %(model)s + AND name = %(name)s + AND key = 'default' + AND value IN %(keys)s + """ + dumped_map = {pickle.dumps(k): pickle.dumps(v) for k, v in mapping.items()} + else: + query = """ + UPDATE ir_default d + SET json_value = (%(json)s::jsonb->>d.json_value) + FROM ir_model_fields f + WHERE d.field_id = f.id + AND f.model = %(model)s + AND f.name = %(name)s + AND d.json_value IN %(keys)s + """ + dumped_map = {json.dumps(k): json.dumps(v) for k, v in mapping.items()} + data = { + "keys": tuple(dumped_map), + "json": json.dumps(dumped_map), + "model": model, + "name": field, + } + cr.execute(query, data) + def adapter(leaf, _or, _neg): left, op, right = leaf if isinstance(right, (tuple, list)): # noqa: SIM108