[FIX] web: onchange on not loaded inline list view

Let's assume a one2many A inside a form view, such that the one2many
views (list, not editable, and form) are defined inline, and there is an
onchange on A. There is another inline one2many B editable list
displayed in the inner form view (and B isn't in the list). There are
two records on the one2many A, both of them having one record in their
one2many B. Edit the first record of A, and edit it's subrecord in B.
Click on save. This triggers an onchange on A and the onchange returns a
command 5 (DELETE_ALL), and two commands 1 (UPDATE). Now edit the second
record of A, and simply close the dialog (e.g. 'Discard'). Save the main
record: the record in one2many B of the second record of A has been duplicated.

This occured because the code in BasicModel messed up information coming
from the onchange (UPDATE command) and from the read (performed when
opening the second record), thus producing a CREATE command instead of
an UPDATE one.

This rev. ensures to properly mix the read data with the onchange
result, by transfering the changes over the list datapoint created after
the read.

opw-1836785
closes #25330
This commit is contained in:
Nicolas Lempereur
2018-06-22 10:19:51 +02:00
parent adeb570b5a
commit 06d89a8440
2 changed files with 95 additions and 0 deletions
@@ -2578,6 +2578,11 @@ var BasicModel = AbstractModel.extend({
relationField: field.relation_field,
viewType: view ? view.type : fieldInfo.viewType,
});
// set existing changes to the list
if (record._changes && record._changes[fieldName]) {
list._changes = self.localData[record._changes[fieldName]]._changes;
record._changes[fieldName] = list.id;
}
record.data[fieldName] = list.id;
if (!fieldInfo.__no_fetch) {
var def = self._readUngroupedList(list).then(function () {
@@ -143,10 +143,12 @@ QUnit.module('relational_fields', {
user: {
fields: {
name: {string: "Name", type: "char"},
partner_ids: {string: "one2many partners field", type: "one2many", relation: 'partner', relation_field: 'user_id'},
},
records: [{
id: 17,
name: "Aline",
partner_ids: [1, 2],
}, {
id: 19,
name: "Christine",
@@ -9383,6 +9385,94 @@ QUnit.module('relational_fields', {
form.destroy();
});
QUnit.test('onchange affecting inline unopened list view', function (assert) {
// when we got onchange result for fields of record that were not
// already available because they were in a inline view not already
// opened, in a given configuration the change were applied ignoring
// existing data, thus a line of a one2many field inside a one2many
// field could be duplicated unexplectedly
assert.expect(5);
var numUserOnchange = 0;
this.data.user.onchanges = {
partner_ids: function (obj) {
if (numUserOnchange === 0) {
// simulate proper server onchange after save of modal with new record
obj.partner_ids = [
[5],
[1, 1, {
display_name: 'first record',
turtles: [
[5],
[1, 2, {'display_name': 'donatello'}],
],
}],
[1, 2, {
display_name: 'second record',
turtles: [
[5],
obj.partner_ids[1][2].turtles[0],
],
}],
];
}
numUserOnchange++;
},
};
var form = createView({
View: FormView,
model: 'user',
data: this.data,
arch: '<form><sheet><group>' +
'<field name="partner_ids">' +
'<form>'+
'<field name="turtles">' +
'<tree editable="bottom">' +
'<field name="display_name"/>' +
'</tree>' +
'</field>' +
'</form>' +
'<tree>' +
'<field name="display_name"/>' +
'</tree>' +
'</field>' +
'</group></sheet></form>',
res_id: 17,
});
// add a turtle on second partner
form.$buttons.find('.o_form_button_edit').click();
form.$('.o_data_row:eq(1)').click();
$('.modal .o_field_x2many_list_row_add a').click();
$('.modal input[name="display_name"]').val('michelangelo').change();
$('.modal .btn-primary').click();
// open first partner so changes from previous action are applied
form.$('.o_data_row:eq(0)').click();
$('.modal .btn-primary').click();
form.$buttons.find('.o_form_button_save').click();
assert.strictEqual(numUserOnchange, 2,
'there should 2 and only 2 onchange from closing the partner modal');
form.$('.o_data_row:eq(0)').click();
assert.strictEqual($('.modal .o_data_row').length, 1,
'only 1 turtle for first partner');
assert.strictEqual($('.modal .o_data_row').text(), 'donatello',
'first partner turtle is donatello');
$('.modal .o_form_button_cancel').click();
form.$('.o_data_row:eq(1)').click();
assert.strictEqual($('.modal .o_data_row').length, 1,
'only 1 turtle for second partner');
assert.strictEqual($('.modal .o_data_row').text(), 'michelangelo',
'second partner turtle is michelangelo');
$('.modal .o_form_button_cancel').click();
form.destroy();
});
QUnit.module('FieldMany2Many');
QUnit.test('many2many kanban: edition', function (assert) {