[FIX] web: make onchange2() apply x2many commands on existing record values

When doing an onchange on some existing record, the x2many commands must
be applied on the current x2many value of the record.  When doing an
onchange on a new record, the x2many commands must be applied on empty
x2many values.

Part-of: odoo/odoo#124612
This commit is contained in:
Raphael Collet
2023-06-13 12:49:20 +02:00
parent a980d58e48
commit 243a2e8d03
2 changed files with 33 additions and 6 deletions
+10 -6
View File
@@ -983,10 +983,8 @@ class Base(models.AbstractModel):
# values of the move, among which the one2many that contains the line
# itself, with old values!
#
changed_values = {fname: values[fname] for fname in field_names}
# set changed values to null in initial_values; not setting them
# triggers default_get() on the new record when creating snapshot0
initial_values = dict(values, **dict.fromkeys(field_names, False))
initial_values = dict(values)
changed_values = {fname: initial_values.pop(fname) for fname in field_names}
# do not force delegate fields to False
for parent_name in self._inherits.values():
@@ -999,7 +997,13 @@ class Base(models.AbstractModel):
# fill in the cache of record with the values of self
cache_values = {fname: self[fname] for fname in fields_spec}
record._update_cache(cache_values, validate=False)
record._update_cache(initial_values)
# apply initial values on top of the values of self
record._update_cache(initial_values)
else:
# set changed values to null in initial_values; not setting them
# triggers default_get() on the new record when creating snapshot0
initial_values.update(dict.fromkeys(field_names, False))
record._update_cache(initial_values, validate=False)
# make parent records match with the form values; this ensures that
# computed fields on parent records have all their dependencies at
@@ -1016,7 +1020,7 @@ class Base(models.AbstractModel):
# 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)
record._update_cache(changed_values, validate=False)
record._update_cache(changed_values)
# update snapshot0 with changed values
for field_name in field_names:
@@ -353,6 +353,29 @@ class TestOnchange2(SavepointCaseWithUserDemo):
result = multi.onchange2(values, ['partner'], fields_spec)
self.assertEqual(result['value'], expected_value)
def test_onchange_one2many_default(self):
""" test onchange on x2many field with default value in context """
default_messages = [Command.create({'body': 'A'})]
model = self.Discussion.with_context(default_messages=default_messages)
# the command CREATE below must be applied on the empty value, instead
# of the default value above
values = {
'name': 'Stuff',
'messages': [(Command.CREATE, 'virtual1', {'name': '[] ', 'body': 'B'})],
}
fields_spec = {
'name': {},
'messages': {'fields': {
'name': {},
'body': {},
}},
}
result = model.onchange2(values, ['name'], fields_spec)
self.assertEqual(result['value'], {
'messages': [Command.update('virtual1', {'name': '[Stuff] OdooBot'})],
})
def test_fields_specific(self):
""" test the effect of field-specific onchange method """
discussion = self.env.ref('test_new_api.discussion_0')