From 94a7bef5db7e0f131d2cd5208d0ac1f78edce117 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Tue, 29 May 2018 10:03:42 +0200 Subject: [PATCH] [FIX] web: domain evaluation in parented m2o in o2m list Model A has a o2m to model B Model B has a m2o parent_id on B In A's form, add a B item, then in the m2o, create record Save and New Click on the m2o Before this commit, the python crashed on name_search. This was because we sent the virtual ids to it After this commit, there is no crash OPW 1850212 closes #24948 --- .../static/src/js/views/basic/basic_model.js | 9 +++ .../tests/fields/relational_fields_tests.js | 59 +++++++++++++++++++ 2 files changed, 68 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 d276e66d33f..042f7bafa97 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3129,6 +3129,15 @@ var BasicModel = AbstractModel.extend({ // when sent to the server, the x2manys values must be a list // of commands in a context, but the list of ids in a domain ids.toJSON = _generateX2ManyCommands.bind(null, fieldName); + } else if (field.type === 'one2many') { // Ids are evaluated as a list of ids + /* Filtering out virtual ids from the ids list + * The server will crash if there are virtual ids in there + * The webClient doesn't do literal id list comparison like ids == list + * Only relevant in o2m: m2m does create actual records in db + */ + ids = _.filter(ids, function (id) { + return typeof id !== 'string'; + }); } context[fieldName] = ids; } diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index a1fe054a0e7..022fa802274 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -2602,6 +2602,65 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('O2M with parented m2o and domain on parent.m2o', function (assert) { + assert.expect(3); + + /* records in an o2m can have a m2o pointing to themselves + * in that case, a domain evaluation on that field followed by name_search + * shouldn't send virtual_ids to the server + */ + + this.data.turtle.fields.parent_id = {string: "Parent", type: "many2one", relation: 'turtle'}; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '' + + '
', + archs: { + 'turtle,false,form': '
', + }, + + mockRPC: function(route, args) { + if (route === '/web/dataset/call_kw/turtle/name_search') { + // We are going to pass twice here + // First time, we really have nothing + // Second time, a virtual_id has been created + assert.deepEqual(args.kwargs.args, [['id', 'in', []]]); + } + return this._super(route, args); + } + }); + + form.$('.o_field_x2many_list[name=turtles] .o_field_x2many_list_row_add a').click(); + var $modal = $('.modal-content'); + + var $turtleParent = $modal.find('.o_field_many2one input'); + var $dropdown = $turtleParent.autocomplete('widget'); + + $turtleParent.click(); + + $dropdown.find('li.o_m2o_dropdown_option:contains(Create)').first().mouseenter().click(); + + $modal = $('.modal-content'); + + $modal.eq(1).find('.modal-footer .btn-primary').eq(0).click(); // Confirm new Record + $modal.eq(0).find('.modal-footer .btn-primary').eq(1).click(); // Save & New + + assert.equal(form.$('.o_data_row').length, 1, + 'The main record should have the new record in its o2m'); + + $modal = $('.modal-content'); + $modal.find('.o_field_many2one input').click(); + + form.destroy(); + }); + QUnit.test('one2many list editable with cell readonly modifier', function (assert) { assert.expect(4);