From 587751aa0dbd095db99e93398cf98d705c35679c Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Fri, 4 Aug 2017 15:36:31 +0200 Subject: [PATCH] [FIX] web: prevent virtual datapoint creation when no default value Previously, it used to create a virtual datapoint even though there was no change on this field. If the field was a many2one, this datapoint triggered a name_get call afterwards, but giving the virtual id of the datapoint since there is no real record. The solution is to avoid creating a virtual datapoint when it is not needed at all, thus fixing the wrong name_get call. Steps to reproduce the bug: - Enable lots in Iventory - Choose a product which is a component of another (through mrp bom) - Set this product as tracked by lot - Set this product inventory quantity to 0 - Create a new manufacturing order for the product for which it is a component - Click on "Check Availability" - Click on Produce - You'll get an error as the web client tries to fetch the name_get of this datapoint even though the record does not exist. --- .../static/src/js/views/basic/basic_model.js | 3 ++ .../tests/fields/relational_fields_tests.js | 36 +++++++++++++++++++ 2 files changed, 39 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 966a6ef3a78..fc3b68eeab7 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -2877,6 +2877,9 @@ var BasicModel = AbstractModel.extend({ r._changes = _.defaults(value[2], r.data); for (var name in r._changes) { + if (r._changes[name] === null) { + continue; + } var isFieldInView = name in r.fields; if (isFieldInView && r.fields[name].type === 'many2one') { var rec = self._makeDataPoint({ diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index d5f2315e89c..9944c2704ca 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -922,6 +922,42 @@ QUnit.module('relational_fields', { }); }); + QUnit.test('list in form: create with one2many with many2one', function (assert) { + assert.expect(1); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
', + mockRPC: function (route, args) { + if (args.method === 'default_get') { + return $.when({p: [[0, 0, {display_name: 'new record'}]]}); + } else if (args.method === 'name_get') { + // This should not be called at all and thus is not accounted for + // in the assert.expect. If this is called, you broke this test. + assert.notOk(_.str.startsWith(args.args[0][0], 'virtual_'), + "should not call name_get for the m2o inside o2m which has no value"); + } + return this._super.apply(this, arguments); + }, + }); + + assert.strictEqual($('td.o_data_cell:first').text(), 'new record', + "should have created the new record in the o2m with the correct name"); + + form.destroy(); + }); + QUnit.test('autocompletion in a many2one, in form view with a domain', function (assert) { assert.expect(1);