[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) <lpe@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Lucas Perais
2023-01-19 17:49:14 +01:00
parent 6278eaeb32
commit 8306e82a00
2 changed files with 57 additions and 1 deletions
@@ -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(
@@ -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": `<form><field name="display_name" /></form>`,
};
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<field name="o2m">
<tree>
<field name="display_name"/>
<field name="color" />
</tree>
</field>
</form>`,
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");
});
});