From e062f89ed50c962197288a4e25f508fd5b3395bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 29 Nov 2018 15:07:47 +0000 Subject: [PATCH] [FIX] web: prevent crash in some cases (o2m) Recent works in the orm (see [1] for example) changed the behaviour of the server in the case of onchanges: it tries to optimize Odoo by sending a minimal diff to the web client in onchanges. Concretely, this means that the web client receives commands 4 (link to) instead of command 1 (update + record data). It also sends a minimal diff in that case. This is a big issue for the web client, because it relied on the knowledge of the data from the command 1 to be able to evaluate some modifiers. The good news is that we can mitigate the issue in one case: we do not actually need to evaluate the modifiers in the case of a command 4 (comming from the server), because we can assume that the record is valid. So, we simply bypass the check in that case. Note that this should fix most of the problem, but a deeper problem still remains: a crash can still happen when an onchange modifies a record in a one2many (but in a different page), and we also have a modifier which needs to be evaluated. opw: #1904514 [1] https://github.com/odoo/odoo/pull/29086 closes odoo/odoo#29172 closes odoo/odoo#29086 --- .../static/src/js/views/basic/basic_model.js | 1 + .../tests/fields/relational_fields_tests.js | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 04a10b46442..508ece9af0d 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3208,6 +3208,7 @@ var BasicModel = AbstractModel.extend({ _.each(element._changes, function (command) { if (command.operation === 'DELETE' || command.operation === 'FORGET' || + (command.operation === 'ADD' && !command.isNew)|| command.operation === 'REMOVE_ALL') { return; } diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index facc8132d7b..87b48526a2f 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -6207,6 +6207,51 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('one2many, onchange, edition and multipage...', function (assert) { + assert.expect(7); + + this.data.partner.onchanges = { + turtles: function (obj) { + obj.turtles = [[5]].concat(obj.turtles); + } + }; + + this.data.partner.records[0].turtles = [1,2,3]; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + mockRPC: function (route, args) { + assert.step(args.method + ' ' + args.model) + return this._super(route, args); + }, + viewOptions: { + mode: 'edit', + }, + }); + form.$('.o_field_x2many_list_row_add a').click(); + form.$('.o_field_x2many_list_row_add a').click(); + + assert.verifySteps([ + 'read partner', + 'read turtle', + 'default_get turtle', + 'onchange partner', + 'default_get turtle', + 'onchange partner', + ]); + form.destroy(); + }); + QUnit.test('one2many with CREATE onchanges correctly refreshed', function (assert) { assert.expect(5);