[FIX] web: use read to update record values after resequence

Commit:
https://github.com/odoo/odoo/commit/818c18e55d0718286ff5bf332186a10f4d7a58ef
Updated the resequence logic in a way that was almost falser than before.
The added test however did work by coincidence, as index values were equal to
the sequence field values.
To be sure that we synchronize with what happens on the server, we do a read
after the resequence.
Additionnally, we take into account the result of the server resequence return;
if it is false, it means no resequencing happened, so we should not do a read.

opw 1867049

closes odoo/odoo#27184
This commit is contained in:
len-odoo
2018-10-12 07:51:12 +00:00
parent 1ab53c27ff
commit 52d779007d
5 changed files with 69 additions and 41 deletions
@@ -893,27 +893,51 @@ var BasicModel = AbstractModel.extend({
route: '/web/dataset/resequence', route: '/web/dataset/resequence',
params: params, params: params,
}) })
.then(function () { .then(function (wasResequenced) {
var offset = options.offset ? options.offset : 0; if (!wasResequenced) {
var old_data = data.data.slice(); // the field on which the resequence was triggered does not
data.data = _.sortBy(data.data, function (d) { // exist, so no resequence happened server-side
if (_.contains(resIDs, self.localData[d].res_id)) { return $.when();
return _.indexOf(resIDs, self.localData[d].res_id) + offset; }
} else { var field = params.field ? params.field : 'sequence';
return _.indexOf(old_data, d);
return self._rpc({
model: modelName,
method: 'read',
args: [resIDs, [field]],
}).then(function (records) {
if (data.data.length) {
var dataType = self.localData[data.data[0]].type;
if (dataType === 'record') {
_.each(data.data, function (dataPoint) {
var recordData = self.localData[dataPoint].data;
var inRecords = _.findWhere(records, {id: recordData.id});
if (inRecords) {
recordData[field] = inRecords[field];
}
});
data.data = _.sortBy(data.data, function (d) {
return self.localData[d].data[field];
});
}
if (dataType === 'list') {
data.data = _.sortBy(data.data, function (d) {
return _.indexOf(resIDs, self.localData[d].res_id)
});
}
} }
}); data.res_ids = [];
data.res_ids = []; _.each(data.data, function (d) {
_.each(data.data, function (d) { var dataPoint = self.localData[d];
var dataPoint = self.localData[d]; if (dataPoint.type === 'record') {
if (dataPoint.type === 'record') { data.res_ids.push(dataPoint.res_id);
data.res_ids.push(dataPoint.res_id); } else {
} else { data.res_ids = data.res_ids.concat(dataPoint.res_ids);
data.res_ids = data.res_ids.concat(dataPoint.res_ids); }
} });
}); self._updateParentResIDs(data);
self._updateParentResIDs(data); return parentID;
return parentID; })
}); });
}, },
/** /**
@@ -775,10 +775,14 @@ var MockServer = Class.extend({
var offset = args.offset ? Number(args.offset) : 0; var offset = args.offset ? Number(args.offset) : 0;
var field = args.field ? args.field : 'sequence'; var field = args.field ? args.field : 'sequence';
var records = this.data[args.model].records; var records = this.data[args.model].records;
if (!(field in this.data[args.model].fields)) {
return false;
}
for (var i in args.ids) { for (var i in args.ids) {
var record = _.findWhere(records, {id: args.ids[i]}); var record = _.findWhere(records, {id: args.ids[i]});
record[field] = Number(i) + offset; record[field] = Number(i) + offset;
} }
return true;
}, },
/** /**
* Simulate a 'search_count' operation * Simulate a 'search_count' operation
@@ -192,6 +192,8 @@ QUnit.module('Views', {
var done = assert.async(); var done = assert.async();
assert.expect(8); assert.expect(8);
this.data.product.fields.sequence = {string: "Sequence", type: "integer"};
this.data.partner.fields.sequence = {string: "Sequence", type: "integer"};
this.data.partner.records.push({id: 3, foo: 'aaa', product_id: 37}); this.data.partner.records.push({id: 3, foo: 'aaa', product_id: 37});
var nbReseq = 0; var nbReseq = 0;
@@ -204,7 +206,7 @@ QUnit.module('Views', {
if (nbReseq === 1) { // resequencing columns if (nbReseq === 1) { // resequencing columns
assert.deepEqual(args.ids, [41, 37], assert.deepEqual(args.ids, [41, 37],
"ids should be correct"); "ids should be correct");
assert.strictEqual(args.model, 'product_id', assert.strictEqual(args.model, 'product',
"model should be correct"); "model should be correct");
} else if (nbReseq === 2) { // resequencing records } else if (nbReseq === 2) { // resequencing records
assert.deepEqual(args.ids, [3, 1], assert.deepEqual(args.ids, [3, 1],
@@ -212,7 +214,6 @@ QUnit.module('Views', {
assert.strictEqual(args.model, 'partner', assert.strictEqual(args.model, 'partner',
"model should be correct"); "model should be correct");
} }
return $.when();
} }
return this._super.apply(this, arguments); return this._super.apply(this, arguments);
}, },
@@ -229,7 +230,7 @@ QUnit.module('Views', {
"first group should be res_id 37"); "first group should be res_id 37");
// resequence columns // resequence columns
return model.resequence('product_id', [41, 37], stateID); return model.resequence('product', [41, 37], stateID);
}) })
.then(function (stateID) { .then(function (stateID) {
var state = model.get(stateID); var state = model.get(stateID);
@@ -1241,7 +1241,7 @@ QUnit.module('Views', {
}); });
QUnit.test('delete a column in grouped on m2o', function (assert) { QUnit.test('delete a column in grouped on m2o', function (assert) {
assert.expect(33); assert.expect(36);
testUtils.patch(KanbanRenderer, { testUtils.patch(KanbanRenderer, {
_renderGrouped: function () { _renderGrouped: function () {
@@ -1858,6 +1858,7 @@ QUnit.module('Views', {
QUnit.test('resequence columns in grouped by m2o', function (assert) { QUnit.test('resequence columns in grouped by m2o', function (assert) {
assert.expect(7); assert.expect(7);
this.data.product.fields.sequence = {string: "Sequence", type: "integer"};
var envIDs = [1, 3, 2, 4]; // the ids that should be in the environment during this test var envIDs = [1, 3, 2, 4]; // the ids that should be in the environment during this test
var kanban = createView({ var kanban = createView({
@@ -1871,12 +1872,6 @@ QUnit.module('Views', {
'</t></templates>' + '</t></templates>' +
'</kanban>', '</kanban>',
groupBy: ['product_id'], groupBy: ['product_id'],
mockRPC: function (route) {
if (route === '/web/dataset/resequence') {
return $.when();
}
return this._super.apply(this, arguments);
},
intercepts: { intercepts: {
env_updated: function (event) { env_updated: function (event) {
assert.deepEqual(event.data.ids, envIDs, assert.deepEqual(event.data.ids, envIDs,
@@ -1900,7 +1895,7 @@ QUnit.module('Views', {
kanban.update({}, {reload: false}); // re-render without reloading kanban.update({}, {reload: false}); // re-render without reloading
assert.strictEqual(kanban.$('.o_kanban_group:first').data('id'), 5, assert.strictEqual(kanban.$('.o_kanban_group:first').data('id'), 5,
"first column should be id 5 before resequencing"); "first column should be id 5 after resequencing");
kanban.destroy(); kanban.destroy();
}); });
+14 -10
View File
@@ -3025,10 +3025,10 @@ QUnit.module('Views', {
foo: { foo: {
fields: {int_field: {string: "int_field", type: "integer", sortable: true}}, fields: {int_field: {string: "int_field", type: "integer", sortable: true}},
records: [ records: [
{id: 1, int_field: 0}, {id: 1, int_field: 11},
{id: 2, int_field: 1}, {id: 2, int_field: 12},
{id: 3, int_field: 2}, {id: 3, int_field: 13},
{id: 4, int_field: 3}, {id: 4, int_field: 14},
] ]
} }
}; };
@@ -3047,14 +3047,15 @@ QUnit.module('Views', {
assert.deepEqual(args, { assert.deepEqual(args, {
model: "foo", model: "foo",
ids: [4, 3], ids: [4, 3],
offset: 2, offset: 13,
field: "int_field", field: "int_field",
}); });
} }
if (moves === 1) { if (moves === 1) {
assert.deepEqual(args, { assert.deepEqual(args, {
model: "foo", model: "foo",
ids: [1, 4, 2, 3], ids: [4, 2],
offset: 12,
field: "int_field", field: "int_field",
}); });
} }
@@ -3062,14 +3063,15 @@ QUnit.module('Views', {
assert.deepEqual(args, { assert.deepEqual(args, {
model: "foo", model: "foo",
ids: [2, 4], ids: [2, 4],
offset: 1, offset: 12,
field: "int_field", field: "int_field",
}); });
} }
if (moves === 3) { if (moves === 3) {
assert.deepEqual(args, { assert.deepEqual(args, {
model: "foo", model: "foo",
ids: [1, 4, 2, 3], ids: [4, 2],
offset: 12,
field: "int_field", field: "int_field",
}); });
} }
@@ -3136,7 +3138,6 @@ QUnit.module('Views', {
"should write the right field as sequence"); "should write the right field as sequence");
assert.deepEqual(args.ids, [4, 2, 3], assert.deepEqual(args.ids, [4, 2, 3],
"should write the sequence in correct order"); "should write the sequence in correct order");
return $.when();
} }
return this._super.apply(this, arguments); return this._super.apply(this, arguments);
}, },
@@ -3266,13 +3267,16 @@ QUnit.module('Views', {
'</tree>', '</tree>',
mockRPC: function (route, args) { mockRPC: function (route, args) {
if (route === '/web/dataset/resequence') { if (route === '/web/dataset/resequence') {
var _super = this._super.bind(this);
assert.strictEqual(args.offset, 1, assert.strictEqual(args.offset, 1,
"should write the sequence starting from the lowest current one"); "should write the sequence starting from the lowest current one");
assert.strictEqual(args.field, 'int_field', assert.strictEqual(args.field, 'int_field',
"should write the right field as sequence"); "should write the right field as sequence");
assert.deepEqual(args.ids, [4, 2, 3], assert.deepEqual(args.ids, [4, 2, 3],
"should write the sequence in correct order"); "should write the sequence in correct order");
return $.when(def); return $.when(def).then(function () {
return _super(route, args);
});
} }
return this._super.apply(this, arguments); return this._super.apply(this, arguments);
}, },