From fc52cae0349ae660cd5313710f918494efda0322 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 6 Sep 2019 09:15:45 +0000 Subject: [PATCH] [FIX] web: list: multi edition: force write same value Let's assume an editable list view with a many2one field and 2 records: the first one has value 1, the second value 2. The user selects all records and wants to set their many2one to value 1. It edits the first one, sets 1 and validates the confirm dialog. Before this rev., it didn't save anything because the 'reference' record (the one used to edit), didn't actually changed, as we reset the same value. This rev. forces the write the new value on all selected records in that case. Task 2068280 --- .../src/js/views/list/list_controller.js | 3 +- .../static/src/js/views/list/list_model.js | 10 ++++- addons/web/static/tests/views/list_tests.js | 38 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js index c7cef09b1df..a4d9de71907 100644 --- a/addons/web/static/src/js/views/list/list_controller.js +++ b/addons/web/static/src/js/views/list/list_controller.js @@ -367,6 +367,7 @@ var ListController = BasicController.extend({ */ _saveMultipleRecords: function (recordId, node, changes) { var self = this; + var fieldName = Object.keys(changes)[0]; var value = Object.values(changes)[0]; var recordIds = _.union([recordId], this.selectedRecords); var validRecordIds = recordIds.reduce(function (result, recordId) { @@ -397,7 +398,7 @@ var ListController = BasicController.extend({ } Dialog.confirm(self, message, { confirm_callback: function () { - self.model.saveRecords(recordId, validRecordIds) + self.model.saveRecords(recordId, validRecordIds, fieldName) .then(function () { self._updateButtons('readonly'); var state = self.model.get(self.handle); diff --git a/addons/web/static/src/js/views/list/list_model.js b/addons/web/static/src/js/views/list/list_model.js index 25fdf28954c..7a2e0c51ada 100644 --- a/addons/web/static/src/js/views/list/list_model.js +++ b/addons/web/static/src/js/views/list/list_model.js @@ -40,12 +40,18 @@ odoo.define('web.ListModel', function (require) { * @param {string} referenceRecordId the record datapoint used to * generate the changes to apply to recordIds * @param {string[]} recordIds a list of record datapoint ids + * @param {string} fieldName the field to write */ - saveRecords: function (referenceRecordId, recordIds) { + saveRecords: function (referenceRecordId, recordIds, fieldName) { var self = this; var referenceRecord = this.localData[referenceRecordId]; var list = this.localData[referenceRecord.parentID]; - var changes = this._generateChanges(referenceRecord, {}); + // generate all record values to ensure that we'll write something + // (e.g. 2 records selected, edit a many2one in the first one, but + // reset same value, we still want to save this value on the other + // record) + var allChanges = this._generateChanges(referenceRecord, {changesOnly: false}); + var changes = _.pick(allChanges, fieldName); var records = recordIds.map(function (recordId) { return self.localData[recordId]; }); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index bebf0bbe263..9b6808e001c 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -4552,6 +4552,44 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('editable list view: multi edition of many2one: set same value', async function (assert) { + assert.expect(4); + + var list = await createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '' + + '' + + '' + + '', + mockRPC: function (route, args) { + if (args.method === 'write') { + assert.deepEqual(args.args, [[1, 2, 3, 4], { m2o: 1 }], + "should force write value on all selected records"); + } + return this._super.apply(this, arguments); + }, + }); + + assert.strictEqual(list.$('.o_list_many2one').text(), "Value 1Value 2Value 1Value 1"); + + // select all records (the first one has value 1 for m2o) + await testUtils.dom.click(list.$('thead .o_list_record_selector input')); + + // set m2o to 1 in first record + await testUtils.dom.click(list.$('.o_data_row:eq(0) .o_data_cell:eq(1)')); + await testUtils.fields.many2one.searchAndClickItem('m2o', {search: 'Value 1'}); + + assert.containsOnce(document.body, '.modal'); + + await testUtils.dom.click($('.modal .modal-footer .btn-primary')); + + assert.strictEqual(list.$('.o_list_many2one').text(), "Value 1Value 1Value 1Value 1"); + + list.destroy(); + }); + QUnit.test('editable list view: multi edition with readonly modifiers', async function (assert) { assert.expect(5);