[FIX] web: incomplete record reload in x2many form view context

Steps to reproduce:

- Install eLearning
- Create or go to an existing course.
- Add Content
- Fill the name and use Save & Close
- Click again in the same content we have just created.
- Click on website preview.

Issue:

Saving a record from a form view that is part of an x2many field would
only reload the fields present in the list view. This led to incomplete
data being loaded into the model.

Solution:

- Pass the `viewType` option to `_fetchRecord` to ensure that the record
is reloaded in the context of the form view, thereby including all
fields.
- Add `viewType` to the `saveOptions` in the `basic_relational_model.js`
to ensure the correct view context is used during the save operation.

This ensures that all fields are reloaded into the model, providing a
complete view of the data.

opw-3330010

closes odoo/odoo#139968

X-original-commit: 3cec34e659222073b0fba36983eaec9f7bf5514f
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Maruan Aguerdouh (magm)
2023-11-20 06:45:47 +00:00
committed by Pierre Rousseau
parent c838944646
commit 4a7d93d089
2 changed files with 98 additions and 4 deletions
@@ -797,7 +797,7 @@ export class StaticList extends DataPoint {
}
_getCommands({ withReadonly } = {}) {
const { CREATE, UPDATE } = x2ManyCommands;
const { CREATE, UPDATE, LINK } = x2ManyCommands;
const commands = [];
for (const command of this._commands) {
if (command[0] === UPDATE && command[1] in this._unknownRecordCommands) {
@@ -814,9 +814,16 @@ export class StaticList extends DataPoint {
}
} else if (command[0] === CREATE || command[0] === UPDATE) {
const record = this._cache[command[1]];
const values = record._getChanges(record._changes, { withReadonly });
if (command[0] === CREATE || Object.keys(values).length) {
commands.push([command[0], command[1], values]);
if (command[0] === CREATE && record.resId) {
// we created a new record, but it has already been saved (e.g. because we clicked
// on a view button in the x2many dialog), so replace the CREATE command by a
// LINK
commands.push([LINK, record.resId]);
} else {
const values = record._getChanges(record._changes, { withReadonly });
if (command[0] === CREATE || Object.keys(values).length) {
commands.push([command[0], command[1], values]);
}
}
} else {
commands.push(command);
@@ -127,6 +127,7 @@ QUnit.module("Views", (hooks) => {
["partner", "Partner"],
],
},
user_id: { string: "User", type: "many2one", relation: "user" },
},
records: [
{
@@ -14299,4 +14300,90 @@ QUnit.module("Views", (hooks) => {
await editInput(target, "[name='int_field'] input", "42");
assert.verifySteps(["get_special_data 9", "get_special_data 42"]);
});
QUnit.test(
"x2many field in form dialog view is correctly saved when using a view button",
async function (assert) {
serverData.actions = {
1: {
id: 1,
name: "Partner",
res_model: "partner",
type: "ir.actions.act_window",
views: [[false, "form"]],
view_mode: "form",
res_id: 6,
},
};
serverData.views = {
"partner,false,form": `
<form>
<field name="display_name"/>
</form>`,
"partner,false,search": `<search/>`,
"user,false,form": `
<form>
<field name="partner_ids">
<tree>
<field name="display_name"/>
</tree>
<form>
<header>
<button type="action" name="1" string="test"/>
</header>
<field name="display_name"/>
</form>
</field>
</form>
`,
"user,false,search": `<search/>`,
};
const webClient = await createWebClient({
serverData,
mockRPC: (route, { method, args, model }) => {
if (method === "web_save") {
if (model === "partner") {
assert.step(`web_save_partner`);
assert.deepEqual(args[1], {
display_name: "new value",
});
} else if (model === "user") {
assert.step(`web_save_user`);
assert.deepEqual(
args[1],
{
partner_ids: [[4, 6]],
},
"Should be a LINK_TO command"
);
}
}
},
});
await doAction(webClient, {
res_id: 19,
type: "ir.actions.act_window",
res_model: "user",
view_mode: "form",
views: [[false, "form"]],
});
assert.containsNone(target, ".o_data_cell");
await click(target.querySelector(".o_field_x2many_list_row_add a"));
await editInput(target, ".o_field_widget[name=display_name] input", "new value");
await click(target, ".modal-dialog .o_form_button_save");
await click(target.querySelector(".o_data_cell"));
await click(target, "[name='1']");
assert.verifySteps(
["web_save_partner", "web_save_user"],
"Verify that the x2many record is saved (partner is saved, then user is saved with a link to"
);
assert.strictEqual(
target.querySelector(".o_field_widget[name=display_name] input").value,
"new value"
);
}
);
});