summaryrefslogtreecommitdiff
path: root/odoo/addons/test_new_api/tests/test_onchange.py
diff options
context:
space:
mode:
authorLaurent Smet <las@odoo.com>2020-11-20 08:00:31 +0000
committerRaphael Collet <rco@odoo.com>2020-12-02 11:45:17 +0000
commit5279a08a005bacee4ecd76cc189d8ce65c8e600c (patch)
treeb635beef0fd3e992f1fe407ec247775ec0bc6146 /odoo/addons/test_new_api/tests/test_onchange.py
parentbaf32bbc177fe653ffc4ee4cd9c014c85910c8d2 (diff)
[FIX] core: invalidation of computed editable field in one2many
This fixes the issue introduced by revision fd50ba9fb838067fab0b920470cf79b9c94d785c The way computed fields are invalidated depends on the order of the dict passed as a parameter to method onchange(). This causes some unexpected behavior when dealing with computed editable fields: the user loses the value in that field because of the onchange. Explanation: during the onchange, the modified field is cached by record._update_cache(changed_values, validate=True) If the field is a one2many, 'value' contains an update command for each modified line. Because of 'validate=True', the assignment triggers field computations on the lines, which are already handled by another call to onchange(). In case anything on the parent model modifies some line, the whole one2many values are returned to the user, and accidentally recomputed fields show up in the interface. closes odoo/odoo#62060 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Diffstat (limited to 'odoo/addons/test_new_api/tests/test_onchange.py')
-rw-r--r--odoo/addons/test_new_api/tests/test_onchange.py38
1 files changed, 37 insertions, 1 deletions
diff --git a/odoo/addons/test_new_api/tests/test_onchange.py b/odoo/addons/test_new_api/tests/test_onchange.py
index 38c7b8be531..1b424777bc0 100644
--- a/odoo/addons/test_new_api/tests/test_onchange.py
+++ b/odoo/addons/test_new_api/tests/test_onchange.py
@@ -4,7 +4,7 @@
from unittest.mock import patch
from odoo.addons.base.tests.common import SavepointCaseWithUserDemo
-from odoo.tests import common
+from odoo.tests import common, Form
def strip_prefix(prefix, names):
size = len(prefix)
@@ -751,3 +751,39 @@ class TestComputeOnchange(common.TransactionCase):
with form.child_ids.edit(2) as line:
line.cost = 30
self.assertEqual(form.cost, 61)
+
+ def test_onchange_editable_compute_one2many(self):
+ # create a record with a computed editable field ('edit') on lines
+ record = self.env['test_new_api.compute_editable'].create({'line_ids': [(0, 0, {'value': 7})]})
+ record.flush()
+ line = record.line_ids
+ self.assertRecordValues(line, [{'value': 7, 'edit': 7, 'count': 0}])
+
+ # retrieve the onchange spec for calling 'onchange'
+ spec = Form(record)._view['onchange']
+
+ # The onchange on 'line_ids' should increment 'count' and keep the value
+ # of 'edit' (this field should not be recomputed), whatever the order of
+ # the fields in the dictionary. This ensures that the value set by the
+ # user on a computed editable field on a line is not lost.
+ line_ids = [
+ (1, line.id, {'value': 8, 'edit': 9, 'count': 0}),
+ (0, 0, {'value': 8, 'edit': 9, 'count': 0}),
+ ]
+ result = record.onchange({'line_ids': line_ids}, 'line_ids', spec)
+ expected = {'value': {
+ 'line_ids': [
+ (5,),
+ (1, line.id, {'value': 8, 'edit': 9, 'count': 8}),
+ (0, 0, {'value': 8, 'edit': 9, 'count': 8}),
+ ],
+ }}
+ self.assertEqual(result, expected)
+
+ # change dict order in lines, and try again
+ line_ids = [
+ (op, id_, dict(reversed(list(vals.items()))))
+ for op, id_, vals in line_ids
+ ]
+ result = record.onchange({'line_ids': line_ids}, 'line_ids', spec)
+ self.assertEqual(result, expected)