[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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user