From 509b30853e65d3b171589afd538edcd7b4b68671 Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Mon, 23 Jan 2023 13:09:54 +0000 Subject: [PATCH] [FIX] web: field wrongly considered as always invisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a field is present twice in a view, the field information stored in the relational model `activeFields` holds and consider only the latest xml node found. Therefore, a field is sometimes considered alwaysInvisible when it is visible and editable. This means that you might click on the 'Save' button and get a server error because a required field is not set when you should the required field should have been highlighted and requested before making a `create` rpc request. This commit makes sure that for the alwaysInvisible logic, both nodes are considered. closes odoo/odoo#110959 X-original-commit: 3d490a264b2fe837f9dc5138f8605f5466b7c312 Signed-off-by: Georis François (fge) Signed-off-by: Aaron Bohy (aab) --- .../static/src/views/form/form_arch_parser.js | 13 ++++++++++- .../tests/views/form/form_view_tests.js | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/views/form/form_arch_parser.js b/addons/web/static/src/views/form/form_arch_parser.js index 3dc52ceec9c..002d439d3bc 100644 --- a/addons/web/static/src/views/form/form_arch_parser.js +++ b/addons/web/static/src/views/form/form_arch_parser.js @@ -49,7 +49,18 @@ export class FormArchParser extends XMLParser { }); // TODO: generate activeFields for the model based on fieldNodes (merge duplicated fields) for (const fieldNode of Object.values(fieldNodes)) { - activeFields[fieldNode.name] = fieldNode; + const fieldName = fieldNode.name; + if (activeFields[fieldName]) { + const { alwaysInvisible } = fieldNode; + activeFields[fieldName] = { + ...fieldNode, + // a field can only be considered to be always invisible + // if all its nodes are always invisible + alwaysInvisible: activeFields[fieldName].alwaysInvisible && alwaysInvisible, + }; + } else { + activeFields[fieldName] = fieldNode; + } // const { onChange, modifiers } = fieldNode; // let readonly = modifiers.readonly || []; // let required = modifiers.required || []; 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 17cced3422b..3b1029be563 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -12699,6 +12699,28 @@ QUnit.module("Views", (hooks) => { assert.verifySteps(["get_views", "onchange", "create", "read"]); }); + QUnit.test("save a form view with a duplicated invisible required field", async function (assert) { + serverData.models.partner.fields.text = { string: "Text", type: "char", required: 1 }; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + +
`, + }); + + await clickSave(target); + + assert.containsOnce(target, ".o_form_label.o_field_invalid"); + assert.containsOnce(target, ".o_field_char.o_field_invalid"); + }); + QUnit.test( "save a form view with an invisible required field in a x2many", async function (assert) {