[FIX] web: x2m causes an onchange on the parent which fails

When the onchange triggered by an x2m fails on the parent record,
we want to reuse a valid value (the one before the onchange).

How to reproduce:
- Go to a form view with an x2m (onchange=true) that contains at least one record
- Edit the record in the x2m
- onchange on parent record fails

Before this commit:
    The value is unchanged.

After this commit:
    The value of the edited field is replaced by its old value.

closes odoo/odoo#136450

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
FrancoisGe
2023-09-25 15:20:22 +00:00
parent 7daff81041
commit ef77dbee98
2 changed files with 43 additions and 1 deletions
@@ -1044,7 +1044,7 @@ export class Record extends DataPoint {
}
}
if (Object.keys(changes).length > 0) {
const initialChanges = pick(this._changes, ...Object.keys(changes));
const initialChanges = pick(this.data, ...Object.keys(changes));
this._applyChanges(changes);
try {
await this._onUpdate({ withoutParentUpdate });
@@ -14177,4 +14177,46 @@ QUnit.module("Fields", (hooks) => {
]);
assert.verifySteps(["get_views", "web_read", "web_save"]);
});
QUnit.test("one2many causes an onchange on the parent which fails", async function (assert) {
serverData.models.partner.onchanges = {
turtles: function () {},
};
serviceRegistry.add("error", errorService);
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<field name="turtles">
<tree editable="top">
<field name="turtle_foo"/>
</tree>
</field>
</form>`,
mockRPC(route, args) {
if (args.method === "onchange" && args.model === "partner") {
throw makeServerError();
}
},
resId: 1,
});
await click(target.querySelector(".o_data_cell"));
assert.strictEqual(
target.querySelector(".o_field_widget[name='turtle_foo'] input").value,
"blip"
);
// onchange on parent record fails
await editInput(target, ".o_field_widget[name='turtle_foo'] input", "new value");
await nextTick();
assert.strictEqual(
target.querySelector(".o_field_widget[name='turtle_foo'] input").value,
"blip"
);
assert.containsOnce(target, ".o_error_dialog");
});
});