From 8306e82a005dc8b69eaea9c2c935ecfbaaf1dd14 Mon Sep 17 00:00:00 2001 From: Lucas Perais Date: Thu, 12 Jan 2023 10:37:18 +0000 Subject: [PATCH] [FIX] web: one2many: field in list and not in form Have a one2many that defines a list arch. The list should not be editable, precisely, when adding a record, it should go through a form view. Define a standard form view in DB, not in the main arch, that doesn't have at least one of the field that the list arch has. Create a record in the one2many list, change a field in order to trigger an onchange. Before this commit, there was a crash, because the onchange asked for the field present in the list and the ones present in the form, but there was a description (the result of fields_get) only for the fields present in the form. After this commit, this is solved. closes odoo/odoo#109749 closes odoo/odoo#110410 X-original-commit: c6897e1e1e5bcf3378bddeb58393baa7426b64c7 Signed-off-by: Lucas Perais (lpe) Signed-off-by: Aaron Bohy (aab) --- .../src/views/fields/relational_utils.js | 5 +- .../views/fields/one2many_field_tests.js | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/views/fields/relational_utils.js b/addons/web/static/src/views/fields/relational_utils.js index 585cc222ac9..68d0038adc8 100644 --- a/addons/web/static/src/views/fields/relational_utils.js +++ b/addons/web/static/src/views/fields/relational_utils.js @@ -558,7 +558,10 @@ async function getFormViewInfo({ list, activeField, viewService, userService, en views: [[false, "form"]], }); const archInfo = new FormArchParser().parse(views.form.arch, relatedModels, comodel); - formViewInfo = { ...archInfo, fields }; // should be good to memorize this on activeField + // Fields that need to be defined are the ones in the form view, this is natural, + // plus the ones that the list record has, that is, present in either the list arch or the kanban arch + // of the one2many field + formViewInfo = { ...archInfo, fields: { ...list.fields, ...fields } }; // should be good to memorize this on activeField } await loadSubViews( 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 9f4f2bf043a..ebabc21cea9 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -12500,4 +12500,57 @@ QUnit.module("Fields", (hooks) => { assert.hasAttrValue(target.querySelector(".o_dialog .o_form_button_save_new"), "disabled", undefined); assert.hasAttrValue(target.querySelector(".o_dialog .o_form_button_cancel"), "disabled", undefined); }); + + QUnit.test("field in list but not in fetched form", async function (assert) { + serverData.models.partner.fields.o2m = { + type: "one2many", + relation: "partner_type", + relation_field: "p_id", + }; + serverData.models.partner_type.onchanges = { + display_name: (rec) => { + if (rec.display_name === "changed") { + rec.color = 5; + } + }, + }; + + serverData.models.partner_type.fields.p_id = { type: "many2one", relation: "partner" }; + serverData.views = { + "partner_type,false,form": `
`, + }; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + + + +
`, + mockRPC(route, args) { + assert.step(`${args.method}: ${args.model}`); + }, + }); + + assert.verifySteps(["get_views: partner", "onchange: partner"]); + await click(target, ".o_field_x2many_list_row_add a"); + assert.verifySteps(["get_views: partner_type", "onchange: partner_type"]); + await editInput( + target.querySelector(".modal"), + ".o_field_widget[name='display_name'] input", + "changed" + ); + assert.verifySteps(["onchange: partner_type"]); + await click(target.querySelector(".modal .o_form_button_save")); + assert.strictEqual(target.querySelector(".o_data_row").textContent, "changed5"); + await click(target, ".o_form_button_save"); + assert.verifySteps(["create: partner", "read: partner", "read: partner_type"]); + assert.strictEqual(target.querySelector(".o_data_row").textContent, "changed5"); + }); });