diff options
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_model.js | 8 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/relational_fields/field_one2many_tests.js | 75 |
2 files changed, 78 insertions, 5 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 649dd3bb1c6..4a3a1930cb1 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -231,7 +231,7 @@ var BasicModel = AbstractModel.extend({ * @returns {Promise} resolved when the fieldInfo have been set on the given * datapoint and all its children, and all rawChanges have been applied */ - addFieldsInfo: function (dataPointID, viewInfo) { + addFieldsInfo: async function (dataPointID, viewInfo) { var dataPoint = this.localData[dataPointID]; dataPoint.fields = _.extend({}, dataPoint.fields, viewInfo.fields); // complete the given fieldInfo with the fields of the main view, so @@ -245,7 +245,9 @@ var BasicModel = AbstractModel.extend({ // so we might have stored changes for them (e.g. coming from onchange // RPCs), that we haven't been able to process earlier (because those // fields were unknown at that time). So we now try to process them. - return this.applyRawChanges(dataPointID, viewInfo.viewType).then(() => { + if (dataPoint.type === 'record') { + await this.applyRawChanges(dataPointID, viewInfo.viewType); + } const proms = []; const fieldInfo = dataPoint.fieldsInfo[viewInfo.viewType]; // recursively apply the new field info on sub datapoints @@ -278,8 +280,6 @@ var BasicModel = AbstractModel.extend({ }); } return Promise.all(proms); - }); - }, /** * Onchange RPCs may return values for fields that are not in the current diff --git a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js index 75346009aaf..f8ff8cba1eb 100644 --- a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js +++ b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js @@ -6511,7 +6511,7 @@ QUnit.module('fields', {}, function () { form.destroy(); }); - QUnit.test('one2many: onchange that returns unknow field in list, but not in form', async function (assert) { + QUnit.test('one2many: onchange that returns unknown field in list, but not in form', async function (assert) { assert.expect(5); this.data.partner.onchanges = { @@ -6563,6 +6563,79 @@ QUnit.module('fields', {}, function () { form.destroy(); }); + QUnit.test('multi level of nested x2manys, onchange and rawChanges', async function (assert) { + assert.expect(8); + + this.data.partner.records[0].p = [1]; + this.data.partner.onchanges = { + name: function () { }, + }; + + var form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ` + <form> + <field name="name"/> + <field name="p"> + <tree><field name="display_name"/></tree> + <form> + <field name="display_name"/> + <field name="p"> + <tree><field name="display_name"/></tree> + <form><field name="display_name"/></form> + </field> + </form> + </field> + </form>`, + mockRPC(route, args) { + if (args.method === 'write') { + assert.deepEqual(args.args[1].p[0][2], { + p: [[1, 1, { display_name: 'new name' }]], + }); + } + return this._super(...arguments); + }, + res_id: 1, + }); + + assert.containsOnce(form, '.o_data_row', "the one2many should contain one row"); + + // open the o2m record in readonly first + await testUtils.dom.click(form.$('.o_data_row td:first')); + assert.containsOnce(document.body, ".modal .o_form_readonly"); + await testUtils.dom.click($('.modal .modal-footer .o_form_button_cancel')); + + // switch to edit mode and open it again + await testUtils.form.clickEdit(form); + await testUtils.dom.click(form.$('.o_data_row td:first')); + + assert.containsOnce(document.body, ".modal .o_form_editable"); + assert.containsOnce(document.body, '.modal .o_data_row', "the one2many should contain one row"); + + // open the o2m again, in the dialog + await testUtils.dom.click($('.modal .o_data_row td:first')); + + assert.containsN(document.body, ".modal .o_form_editable", 2); + + // edit the name and click save modal that is on top + await testUtils.fields.editInput($('.modal:nth(1) .o_field_widget[name=display_name]'), 'new name'); + await testUtils.dom.click($('.modal:nth(1) .modal-footer .btn-primary')); + + assert.containsOnce(document.body, ".modal .o_form_editable"); + + // click save on the other modal + await testUtils.dom.click($('.modal .modal-footer .btn-primary')); + + assert.containsNone(document.body, ".modal"); + + // save the main record + await testUtils.form.clickSave(form); + + form.destroy(); + }); + QUnit.test('onchange and required fields with override in arch', async function (assert) { assert.expect(4); |
