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 cf63583bb49..ff6b8e61f4d 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 @@ -3096,9 +3096,18 @@ var BasicModel = AbstractModel.extend({ var view = fieldInfo.views && fieldInfo.views[fieldInfo.mode]; var fieldsInfo = view ? view.fieldsInfo : (fieldInfo.fieldsInfo || {}); var ids = record.data[fieldName] || []; + + // remove default_* & *_view_ref keys from record context + const recordContext = { ...record.context }; + for (const key in recordContext) { + if (key.startsWith("default_") || key.endsWith("_view_ref")) { + delete recordContext[key]; + } + } + var list = self._makeDataPoint({ count: ids.length, - context: _.extend({}, record.context, field.context), + context: Object.assign({}, recordContext, field.context), fieldsInfo: fieldsInfo, fields: view ? view.fields : fieldInfo.relatedFields, limit: fieldInfo.limit, @@ -4599,12 +4608,16 @@ var BasicModel = AbstractModel.extend({ var fields = view ? view.fields : fieldInfo.relatedFields; var viewType = view ? view.type : fieldInfo.viewType; - // remove default_* keys from parent context to avoid issue of same field name in x2m - var parentContext = _.omit(record.context, function (val, key) { - return _.str.startsWith(key, 'default_'); - }); + // remove default_* & *_view_ref keys from record context + const recordContext = { ...record.context }; + for (const key in recordContext) { + if (key.startsWith("default_") || key.endsWith("_view_ref")) { + delete recordContext[key]; + } + } + var x2manyList = self._makeDataPoint({ - context: parentContext, + context: recordContext, fieldsInfo: fieldsInfo, fields: fields, limit: fieldInfo.limit, diff --git a/addons/web/static/tests/views/form/form_view_tests.js b/addons/web/static/tests/views/form/form_view_tests.js index 64933234af1..fb6927b5ef4 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -942,6 +942,89 @@ QUnit.module("Views", (hooks) => { await click(target.querySelector('.o_field_widget[name="product_id"] .o_external_button')); }); + QUnit.test("Form and subsubview with default_ or _view_ref contexts", async function (assert) { + serverData.models.partner_type.fields.company_ids = { + string: "one2many field", + type: "one2many", + relation: "res.company", + }; + serverData.views = { + "res.company,false,search": "", + "res.company,false,list": ``, + "res.company,bar_rescompany_form_view,form": `
`, + "partner_type,false,search": "", + "partner_type,false,list": ``, + "partner_type,foo_partner_type_form_view,form": ` +
+ + + `, + }; + + const userContext = { + lang: "en", + tz: "taht", + uid: 7, + }; + const expectedContexts = new Map(); + + // Make main form view + expectedContexts.set("partner", { ...userContext }); + expectedContexts.set("partner_type", { + ...userContext, + base_model_name: "partner", + form_view_ref: "foo_partner_type_form_view", + }); + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + `, + resId: 2, + mockRPC: (route, { method, model, kwargs }) => { + if (["get_views", "onchange"].includes(method)) { + const { context } = kwargs; + assert.step(`${method} (${model})`); + assert.deepEqual(context, expectedContexts.get(model)); + } + }, + }); + assert.verifySteps(["get_views (partner)", "get_views (partner_type)"]); + + // Add a line in the x2many timmy field + expectedContexts.clear(); + expectedContexts.set("partner_type", { + ...userContext, + default_partner_id: 2, + form_view_ref: "foo_partner_type_form_view", + }); + await click(target, "[name=timmy] .o_field_x2many_list_row_add a"); + assert.verifySteps(["get_views (partner_type)"]); + + // Create a new timmy + await click(target, ".modal .o_create_button"); + assert.verifySteps(["get_views (partner_type)", "onchange (partner_type)"]); + + // Create a new company + expectedContexts.clear(); + expectedContexts.set("res.company", { + ...userContext, + default_color: 2, + form_view_ref: "bar_rescompany_form_view", + }); + await click(target, ".modal [name=company_ids] .o_field_x2many_list_row_add a"); + assert.verifySteps(["get_views (res.company)", "onchange (res.company)"]); + }); + QUnit.test("invisible fields are properly hidden", async function (assert) { await makeView({ type: "form",