[FIX] web: basic_model: save a paged nested o2m

In a form view, have a o2m field (A), with a nested o2m field (B).
The A field should have multiple pages, with each record having at least one record
in their B field.

Have a (C) field that will modify a record in the nested o2m when changed.

Change the C field, and save.

Before this commit, the record's nested o2m from the other page had a wrong value
(a mere 4 command).

After this commit, their value is a command 4 and a command 1, with the right values.

closes odoo/odoo#99986

X-original-commit: e45e3b83f0f3116cc983c6bd8a9212e815b4d4f5
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Florian Damhaut
2022-09-12 13:49:31 +02:00
committed by Aaron Bohy
parent e9aac69e6b
commit b3489af4c1
3 changed files with 102 additions and 1 deletions
@@ -3311,6 +3311,7 @@ var BasicModel = AbstractModel.extend({
_generateX2ManyCommands: function (record, options) {
var self = this;
options = options || {};
const changesOnly = options.changesOnly;
var fields = record.fields;
if (options.fieldNames) {
fields = _.pick(fields, options.fieldNames);
@@ -3403,7 +3404,7 @@ var BasicModel = AbstractModel.extend({
if (!this.isNew(relRecord.id)) {
// the subrecord already exists in db
commands[fieldName].push(x2ManyCommands.link_to(relRecord.res_id));
if (this.isDirty(relRecord.id)) {
if (changesOnly ? Object.keys(changes).length : this.isDirty(relRecord.id)) {
delete changes.id;
commands[fieldName].push(x2ManyCommands.update(relRecord.res_id, changes));
}
@@ -10135,6 +10135,59 @@ QUnit.module('Legacy fields', {}, function () {
form.destroy();
});
QUnit.test('nested one2manys, multi page, onchange', async function (assert) {
assert.expect(5);
this.data.partner.records[2].int_field = 5;
this.data.partner.records[0].p = [2, 4]; // limit 1 -> record 4 will be on second page
this.data.partner.records[1].turtles = [1];
this.data.partner.records[2].turtles = [2];
this.data.turtle.records[0].turtle_int = 1;
this.data.turtle.records[1].turtle_int = 2;
this.data.partner.onchanges.int_field = function (obj) {
assert.step('onchange')
obj.p = [[5]]
obj.p.push([1, 2, { turtles: [[5], [1, 1, { turtle_int: obj.int_field }]] }]);
obj.p.push([1, 4, { turtles: [[5], [1, 2, { turtle_int: obj.int_field }]] }]);
};
var form = await createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partner">' +
'<field name="int_field"/>' +
'<field name="p">' +
'<tree editable="bottom" limit="1" default_order="display_name">' +
'<field name="display_name" />' +
'<field name="int_field" />' +
'<field name="turtles">' +
'<tree editable="bottom">' +
'<field name="turtle_int"/>' +
'</tree>' +
'</field>' +
'</tree>' +
'</field>' +
'</form>',
res_id: 1,
viewOptions: {
mode: 'edit',
},
});
await testUtils.fields.editInput(form.$('.o_field_widget[name="int_field"]'), '5');
assert.verifySteps(['onchange'])
await testUtils.form.clickSave(form);
assert.strictEqual(this.data.partner.records[0].int_field, 5, 'Value should have been updated')
assert.strictEqual(this.data.turtle.records[1].turtle_int, 5, 'Shown data should have been updated');
assert.strictEqual(this.data.turtle.records[0].turtle_int, 5, 'Hidden data should have been updated');
form.destroy();
});
});
});
});
@@ -12596,4 +12596,51 @@ QUnit.module("Fields", (hooks) => {
);
}
);
QUnit.test('nested one2manys, multi page, onchange', async function (assert) {
serverData.models.partner.records[2].int_field = 5;
serverData.models.partner.records[0].p = [2, 4]; // limit 1 -> record 4 will be on second page
serverData.models.partner.records[1].turtles = [1];
serverData.models.partner.records[2].turtles = [2];
serverData.models.turtle.records[0].turtle_int = 1;
serverData.models.turtle.records[1].turtle_int = 2;
serverData.models.partner.onchanges.int_field = function (obj) {
assert.step('onchange')
obj.p = [[5]]
obj.p.push([1, 2, { turtles: [[5], [1, 1, { turtle_int: obj.int_field }]] }]);
obj.p.push([1, 4, { turtles: [[5], [1, 2, { turtle_int: obj.int_field }]] }]);
};
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<field name="int_field"/>
<field name="p">
<tree editable="bottom" limit="1" default_order="display_name">
<field name="display_name" />
<field name="int_field" />
<field name="turtles">
<tree editable="bottom">
<field name="turtle_int"/>
</tree>
</field>
</tree>
</field>
</form>`,
resId: 1,
mode: 'edit',
});
await editInput(target, ".o_field_widget[name=int_field] input", "5");
assert.verifySteps(['onchange'])
await clickSave(target);
assert.strictEqual(serverData.models.partner.records[0].int_field, 5)
assert.strictEqual(serverData.models.turtle.records[1].turtle_int, 5);
assert.strictEqual(serverData.models.turtle.records[0].turtle_int, 5);
});
});