From 50abdbe9d9e2be1ed7b2c7d336c1aa0fa718081f Mon Sep 17 00:00:00 2001 From: std-odoo Date: Thu, 8 Sep 2022 14:21:56 +0000 Subject: [PATCH] [FIX] base: fix the property onchange Bug === - create a new helpdesk ticket without properties - create a new property - change the customer => The added property is removed The fix in the onchange of models.py needs to be more specific, and should be used only when the definition record is changed. Task-2965523 X-original-commit: 909ee004183068d9ffa94abe0d1472a8f0534f34 Part-of: odoo/odoo#101487 --- .../test_new_api/tests/test_properties.py | 22 +++++++++++++ odoo/models.py | 31 +++++++++++-------- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/odoo/addons/test_new_api/tests/test_properties.py b/odoo/addons/test_new_api/tests/test_properties.py index d6bd240abee..2574f82cba8 100644 --- a/odoo/addons/test_new_api/tests/test_properties.py +++ b/odoo/addons/test_new_api/tests/test_properties.py @@ -1186,6 +1186,28 @@ class PropertiesCase(TransactionCase): message.attributes, [{'name': 'new_property', 'type': 'char', 'value': 'test value'}]) + # re-write the same parent again and check that value are not reset + message.discussion = message.discussion + self.assertEqual( + message.attributes, + [{'name': 'new_property', 'type': 'char', 'value': 'test value'}]) + + # trigger a other onchange after setting the properties + # and check that it does not impact the properties + message.discussion.attributes_definition = [] + message_form = Form(message) + message.attributes = [{ + 'name': 'new_property', + 'type': 'char', + 'value': 'test value', + 'definition_changed': True, + }] + message_form.body = "a" * 42 + message = message_form.save() + self.assertEqual( + message.attributes, + [{'name': 'new_property', 'type': 'char', 'value': 'test value'}]) + @mute_logger('odoo.fields') def test_properties_field_definition_update(self): """Test the definition update from the child.""" diff --git a/odoo/models.py b/odoo/models.py index a7d8567ed18..3eda64a9170 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -6827,9 +6827,26 @@ class BaseModel(metaclass=MetaModel): for name, subnames in self[''].items(): if name == 'id': continue + field = record._fields[name] + if (field.type == 'properties' and field.definition_record in field_name + and other.get(name) == self[name] == []): + # TODO: The parent field on "record" can be False, if it was changed, + # (even if if was changed to a not Falsy value) because of + # >>> initial_values = dict(values, **dict.fromkeys(names, False)) + # If it's the case when we will read the properties field on this record, + # it will return False as well (no parent == no definition) + # So record at the following line, will always return a empty properties + # because the definition record is always False if it triggered the onchange + # >>> snapshot0 = Snapshot(record, nametree, fetch=(not first_call)) + # but we need "snapshot0" to have the old value to be able + # to compare it with the new one and trigger the onchange if necessary. + # In that particular case, "other.get(name)" must contains the + # non empty properties value. + result[name] = [] + continue + if not force and other.get(name) == self[name]: continue - field = record._fields[name] if field.type not in ('one2many', 'many2many'): result[name] = field.convert_to_onchange(self[name], record, {}) else: @@ -6957,18 +6974,6 @@ class BaseModel(metaclass=MetaModel): # make a snapshot based on the initial values of record snapshot0 = Snapshot(record, nametree, fetch=(not first_call)) - for name in initial_values: - # TODO: The parent field on "record" can be False, if it was changed, - # (even if if was changed to a not Falsy value) because of - # >>> initial_values = dict(values, **dict.fromkeys(names, False)) - # If it's the case when we will read the properties field on this record, - # it will return False as well (no parent == no definition) but we need - # "snapshot0" to have the old value to be able to compare it with the new one - # and trigger the onchange if necessary. - field = self._fields.get(name) - if field and field.type == 'properties': - snapshot0[name] = initial_values[name] - # store changed values in cache; also trigger recomputations based on # subfields (e.g., line.a has been modified, line.b is computed stored # and depends on line.a, but line.b is not in the form view)