Skip to content

Commit bfe8509

Browse files
committed
[FIX] core: first onchange when adding a line in a one2many field
Consider a form view with a one2many field, which has no form subview. Also the form view of the comodel (the one2many field's lines) contains the inverse many2one field of the one2many field. When adding a new line on some existing record, the form view shows the many2one field as empty, instead of being the main record. Explanation: the form view of the line invokes onchange() with the main record's values (dict) as the value of the many2one field. Inside onchange(), the field is actually set to a new record corresponding to the main record. Alas, when that value is sent back to the form, the new record is serialized as False. Solution: let onchange() serialize the new record as its origin record instead. closes odoo#114641 X-original-commit: d137ea4 Signed-off-by: Raphael Collet <rco@odoo.com>
1 parent dbaf8da commit bfe8509

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

odoo/addons/test_new_api/tests/test_onchange.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,20 @@ def mock_read(self, fields=None, load='_classic_read'):
535535

536536
self.assertFalse(called[0], "discussion.messages has been read")
537537

538+
def test_onchange_one2many_many2one_in_form(self):
539+
order = self.env['test_new_api.monetary_order'].create({
540+
'currency_id': self.env.ref('base.USD').id,
541+
})
542+
543+
# this call to onchange() is made when creating a new line in field
544+
# order.line_ids; check what happens when the line's form view contains
545+
# the inverse many2one field
546+
values = {'order_id': {'id': order.id, 'currency_id': order.currency_id.id}}
547+
field_onchange = dict.fromkeys(['order_id', 'subtotal'], '')
548+
result = self.env['test_new_api.monetary_order_line'].onchange(values, [], field_onchange)
549+
550+
self.assertEqual(result['value']['order_id'], (order.id, order.display_name))
551+
538552
def test_onchange_inherited(self):
539553
""" Setting an inherited field should assign the field on the parent record. """
540554
foo, bar = self.env['test_new_api.multi.tag'].create([{'name': 'Foo'}, {'name': 'Bar'}])

odoo/fields.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,9 +3021,8 @@ def convert_to_display_name(self, value, record):
30213021
return value.display_name
30223022

30233023
def convert_to_onchange(self, value, record, names):
3024-
if not value.id:
3025-
return False
3026-
return super(Many2one, self).convert_to_onchange(value, record, names)
3024+
# if value is a new record, serialize its origin instead
3025+
return super().convert_to_onchange(value._origin, record, names)
30273026

30283027
def write(self, records, value):
30293028
# discard recomputation of self on records

0 commit comments

Comments
 (0)