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 508ece9af0d..418542e062a 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3958,11 +3958,24 @@ var BasicModel = AbstractModel.extend({ } return def.then(function () { var resIDs = []; - // generate the current count and res_ids list by applying the changes - var currentCount = list.count; var currentResIDs = list.res_ids; - var effectiveLimit = (list.limit || 0) - (list.tempLimitIncrement || 0); - var upperBound = effectiveLimit ? Math.min(list.offset + effectiveLimit, currentCount) : currentCount; + // if new records have been added to the list, their virtual ids have + // been pushed at the end of res_ids (or at the beginning, depending + // on the editable property), ignoring completely the current page + // where the records have actually been created ; for that reason, + // we use orderedResIDs which is a freezed order with the virtual ids + // at the correct position where they were actually inserted ; however, + // when we use orderedResIDs, we must filter out ids that are not in + // res_ids, which correspond to records that have been removed from + // the relation (this information being taken into account in res_ids + // but not in orderedResIDs) + if (list.orderedResIDs) { + currentResIDs = list.orderedResIDs.filter(function (resID) { + return list.res_ids.indexOf(resID) >= 0; + }); + } + var currentCount = currentResIDs.length; + var upperBound = list.limit ? Math.min(list.offset + list.limit, currentCount) : currentCount; var fieldNames = list.getFieldNames(); for (var i = list.offset; i < upperBound; i++) { var resId = currentResIDs[i]; diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 93bebf0a4bc..0a5825850d6 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -3999,6 +3999,50 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('delete a record while adding another one in a multipage', function (assert) { + // in a many2one with at least 2 pages, add a new line. Delete the line above it. + // (the onchange makes it so that the virtualID is inserted in the middle of the currentResIDs.) + // it should load the next line to display it on the page. + assert.expect(2); + + this.data.partner.records[0].turtles = [2, 3]; + this.data.partner.onchanges.turtles = function (obj) { + obj.turtles = [[5]].concat(obj.turtles); + }; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
', + res_id: 1, + }); + + form.$buttons.find('.o_form_button_edit').click(); + // add a line (virtual record) + form.$('.o_field_x2many_list_row_add a').click(); + form.$('.o_input').val('pi').trigger('input'); + // delete the line above it + form.$('.o_list_record_delete').first().click(); + // the next line should be displayed below the newly added one + assert.strictEqual(form.$('.o_data_row').length, 2, "should have 2 records"); + assert.strictEqual(form.$('.o_data_row').text(), 'pikawa', + "should display the correct records on page 1"); + + form.destroy(); + }); + QUnit.test('onchange returning a command 6 for an x2many', function (assert) { assert.expect(2); @@ -6231,7 +6275,7 @@ QUnit.module('relational_fields', { '', res_id: 1, mockRPC: function (route, args) { - assert.step(args.method + ' ' + args.model) + assert.step(args.method + ' ' + args.model); return this._super(route, args); }, viewOptions: {