[FIX] web: read records up to list limit
Fine-tuning of commit e7fab23420
In a one2many with more than one page with a limit of k records, add a line l.
It increments the list limit to k+1. Remove a line above (of index <= k).
It will try to load a line l' to replace it, that it will find on page 2.
However when deciding if it should read missing fields on that record, it will
scan at most u records, skipping virtual ids.
Here u is the min between the current number of lines and the list limit
without the temporary increase due to the added record.
Since there are at least two pages, u = k.
However since l is in the list at index k, then l' won't be read, and since it
was on page 2 its data hasn't been loaded.
Therefore the js would traceback when trying to evaluate it.
opw 1913361
closes odoo/odoo#29338
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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:'<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<group>' +
|
||||
'<field name="turtles">' +
|
||||
'<tree editable="bottom" limit="1" decoration-muted="turtle_bar == False">' +
|
||||
'<field name="turtle_foo"/>' +
|
||||
'<field name="turtle_bar"/>' +
|
||||
'</tree>' +
|
||||
'</field>' +
|
||||
'</group>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
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', {
|
||||
'</form>',
|
||||
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: {
|
||||
|
||||
Reference in New Issue
Block a user