From ea0f441d4d211c851a241945709a26d7040b24bc Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Thu, 10 Aug 2023 09:39:38 +0000 Subject: [PATCH] [FIX] web: menu action not executed if save fails Before this commit, in the form view, clicking on an action in the menu action executed the action even though the record save had failed. Expected behaviour: When you click on an action, you want to save the record and execute the action if the record was saved without error. How to reproduce: - Go to a form view - Create a new record - Edit a field to ensure that the save returns an error - Click on an action in the action menu (for example duplicate) - The "Oh Snap" dialog opens - Click on "Discard Before this commit: The button action code executes and displays a crash After this commit: The button action code does not execute closes odoo/odoo#131660 Signed-off-by: Jorge Pinna Puissant (jpp) --- .../static/src/views/form/form_controller.js | 9 +++++-- .../tests/views/form/form_view_tests.js | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/views/form/form_controller.js b/addons/web/static/src/views/form/form_controller.js index ce8a35d8744..a193b04238f 100644 --- a/addons/web/static/src/views/form/form_controller.js +++ b/addons/web/static/src/views/form/form_controller.js @@ -426,10 +426,15 @@ export class FormController extends Component { async shouldExecuteAction(item) { const dirty = await this.model.root.isDirty(); if ((dirty || this.model.root.isNew) && !item.skipSave) { - return this.model.root.save({ + let hasError = false; + const isSaved = await this.model.root.save({ stayInEdition: true, - onError: this.onSaveError.bind(this), + onError: (...args) => { + hasError = true; + return this.onSaveError(...args); + }, }); + return isSaved && !hasError; } return true; } 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 a0de703b600..5b7932a6a61 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -4557,6 +4557,33 @@ QUnit.module("Views", (hooks) => { ); }); + QUnit.test("don't duplicate if save fail", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: '
', + actionMenus: {}, + async mockRPC(route, args) { + if (args.method === "create") { + assert.step("create"); + throw makeServerError(); + } + if (args.method === "copy") { + assert.step("copy"); + } + }, + }); + await editInput(target, "[name=foo] input", "new value"); + await toggleActionMenu(target); + await toggleMenuItem(target, "Duplicate"); + assert.containsOnce(target, ".modal .o_error_dialog"); + // Discard changes don't trigger Duplicate action + await click(target, ".modal .btn-secondary"); + + assert.verifySteps(["create"]); + }); + QUnit.test("clicking on stat buttons in edit mode", async function (assert) { let count = 0; const fakeActionService = {