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) {