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 1e930ccf783e43f6eac8de36c03ac19b2c5b89df..f87106ec0c289984fc0274306ab9b6aa1439aac3 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3587,27 +3587,21 @@ var BasicModel = AbstractModel.extend({ _makeDefaultRecord: function (modelName, params) { var self = this; - var determineExtraFields = function () { - // Fields that are present in the originating view, that need to be initialized - // Hence preventing their value to crash when getting back to the originating view - var parentRecord = self.localData[params.parentID]; - - var originView = parentRecord && parentRecord.fieldsInfo; - if (!originView || !originView[parentRecord.viewType]) - return []; - - var fieldsFromOrigin = _.filter(Object.keys(originView[parentRecord.viewType]), - function (fieldname) { - return params.fields[fieldname] !== undefined; - }); - - return fieldsFromOrigin; - }; - - var fieldNames = Object.keys(params.fieldsInfo[params.viewType]); + var targetView = params.viewType; + var fields = params.fields; + var fieldsInfo = params.fieldsInfo; + var fieldNames = Object.keys(fieldsInfo[targetView]); var fields_key = _.without(fieldNames, '__last_update'); - var extraFields = determineExtraFields(); + // Fields that are present in the originating view, that need to be initialized + // Hence preventing their value to crash when getting back to the originating view + var parentRecord = self.localData[params.parentID]; + if (parentRecord) { + var originView = parentRecord.viewType; + fieldNames = _.union(fieldNames, Object.keys(parentRecord.fieldsInfo[originView])); + fieldsInfo[targetView] = _.defaults({}, fieldsInfo[targetView], parentRecord.fieldsInfo[originView]); + fields = _.defaults({}, fields, parentRecord.fields); + } return this._rpc({ model: modelName, @@ -3616,15 +3610,14 @@ var BasicModel = AbstractModel.extend({ context: params.context, }) .then(function (result) { - var record = self._makeDataPoint({ modelName: modelName, - fields: params.fields, - fieldsInfo: params.fieldsInfo, + fields: fields, + fieldsInfo: fieldsInfo, context: params.context, parentID: params.parentID, res_ids: params.res_ids, - viewType: params.viewType, + viewType: targetView, }); // We want to overwrite the default value of the handle field (if any), @@ -3641,7 +3634,7 @@ var BasicModel = AbstractModel.extend({ result[overrideDefaultFields.field] = overrideDefaultFields.value; } - return self.applyDefaultValues(record.id, result, {fieldNames: _.union(fieldNames, extraFields)}) + return self.applyDefaultValues(record.id, result, {fieldNames: fieldNames}) .then(function () { var def = $.Deferred(); self._performOnChange(record, fields_key).always(function () { diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index f64e4e32e919e21652f811615572f8ea448ddcb4..9c7c6363a407dc9fdf144aa420292d1346810da9 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -13544,6 +13544,90 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('one2many with extra field from server not in (inline) form', function (assert) { + assert.expect(1); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<field name="p" >' + + '<tree>' + + '<field name="datetime"/>' + + '<field name="display_name"/>' + + '</tree>' + + '<form>' + + '<field name="display_name"/>' + + '</form>' + + '</field>' + + '</form>', + res_id: 1, + viewOptions: { + mode: 'edit', + }, + }); + + var x2mList = form.$('.o_field_x2many_list[name=p]'); + + // Add a record in the list + x2mList.find('.o_field_x2many_list_row_add a').click(); + + var modal = $('.modal-lg'); + + var nameInput = modal.find('input.o_input[name=display_name]'); + nameInput.val('michelangelo').trigger('input'); + + // Save the record in the modal (though it is still virtual) + modal.find('.btn-primary').first().click(); + + assert.equal(x2mList.find('.o_data_row').length, 1, + 'There should be 1 records in the x2m list'); + + form.destroy(); + }); + + QUnit.test('one2many with extra X2many field from server not in inline form', function (assert) { + assert.expect(1); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form string="Partners">' + + '<field name="p" >' + + '<tree>' + + '<field name="turtles"/>' + + '<field name="display_name"/>' + + '</tree>' + + '<form>' + + '<field name="display_name"/>' + + '</form>' + + '</field>' + + '</form>', + res_id: 1, + viewOptions: { + mode: 'edit', + }, + }); + + var x2mList = form.$('.o_field_x2many_list[name=p]'); + + // Add a first record in the list + x2mList.find('.o_field_x2many_list_row_add a').click(); + + // Save & New + $('.modal-lg').find('.btn-primary').eq(1).click(); + + // Save & Close + $('.modal-lg').find('.btn-primary').eq(0).click(); + + assert.equal(x2mList.find('.o_data_row').length, 2, + 'There should be 2 records in the x2m list'); + + form.destroy(); + }); + QUnit.test('one2many invisible depends on parent field', function (assert) { assert.expect(4);