[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
This commit is contained in:
Aaron Bohy
2019-09-18 11:28:03 +00:00
parent 63289fa06a
commit 2cdd46b566
3 changed files with 48 additions and 3 deletions
@@ -457,6 +457,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, nextRecordId) {
@@ -487,7 +488,7 @@ var ListController = BasicController.extend({
}
Dialog.confirm(this, message, {
confirm_callback: () => {
this.model.saveRecords(recordId, validRecordIds)
this.model.saveRecords(recordId, validRecordIds, fieldName)
.then(() => {
this._updateButtons('readonly');
const state = this.model.get(this.handle);
@@ -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];
});
@@ -5411,6 +5411,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: '<tree editable="bottom">' +
'<field name="foo"/>' +
'<field name="m2o"/>' +
'</tree>',
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);