diff --git a/addons/web/static/src/legacy/js/views/basic/basic_model.js b/addons/web/static/src/legacy/js/views/basic/basic_model.js index e7ebc36e1dd..2f7f4143ad9 100644 --- a/addons/web/static/src/legacy/js/views/basic/basic_model.js +++ b/addons/web/static/src/legacy/js/views/basic/basic_model.js @@ -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)); } diff --git a/addons/web/static/tests/legacy/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/legacy/fields/relational_fields/field_one2many_tests.js index d1d7f9a2519..78484cd2cd6 100644 --- a/addons/web/static/tests/legacy/fields/relational_fields/field_one2many_tests.js +++ b/addons/web/static/tests/legacy/fields/relational_fields/field_one2many_tests.js @@ -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: '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '', + 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(); + }); }); }); }); diff --git a/addons/web/static/tests/views/fields/one2many_field_tests.js b/addons/web/static/tests/views/fields/one2many_field_tests.js index 04d360d27e4..735ed69fde1 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -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: ` +
+ + + + + + + + + + + + + `, + 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); + }); });