From f609a616d19e44397ef207323c7f9ed3e2203484 Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Mon, 4 Sep 2023 08:51:02 +0200 Subject: [PATCH] [IMP] web: allow to save and read next record in one rpc call In [1], a new python function was introduced that allows to save and read in one rpc. This commit, adds the possiblitity to read another record in the same rpc call. This is particularly useful when you want to save and read the next record (for instance on a pager). 1: ebd538a1942c532bcf1c9deeab3c25efe23b6893 Task-id : 3453184 closes odoo/odoo#134125 Signed-off-by: Aaron Bohy (aab) --- addons/web/models/models.py | 4 +++- addons/web/static/src/model/relational_model/record.js | 10 +++++++--- addons/web/static/src/views/form/form_controller.js | 8 +++----- addons/web/static/tests/helpers/mock_server.js | 3 +++ addons/web/static/tests/views/form/form_view_tests.js | 4 +++- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/addons/web/models/models.py b/addons/web/models/models.py index 5d19f8a8595..993da2a539d 100644 --- a/addons/web/models/models.py +++ b/addons/web/models/models.py @@ -66,11 +66,13 @@ class Base(models.AbstractModel): 'records': records, } - def web_save(self, vals, specification: Dict[str, Dict]) -> List[Dict]: + def web_save(self, vals, specification: Dict[str, Dict], next_id=None) -> List[Dict]: if self: self.write(vals) else: self = self.create(vals) + if next_id: + self = self.browse(next_id) return self.with_context(bin_size=True).web_read(specification) def web_read(self, specification: Dict[str, Dict]) -> List[Dict]: diff --git a/addons/web/static/src/model/relational_model/record.js b/addons/web/static/src/model/relational_model/record.js index 90bc9ab68ca..845632cc08b 100644 --- a/addons/web/static/src/model/relational_model/record.js +++ b/addons/web/static/src/model/relational_model/record.js @@ -826,7 +826,10 @@ export class Record extends DataPoint { this._activeFieldsToRestore = undefined; } - async _save({ noReload, onError } = {}) { + async _save({ noReload, onError, nextId } = {}) { + if (nextId) { + noReload = false; + } // before saving, abandon new invalid, untouched records in x2manys for (const fieldName in this.activeFields) { const field = this.fields[fieldName]; @@ -858,6 +861,7 @@ export class Record extends DataPoint { const kwargs = { context: this.context, specification: fieldSpec, + next_id: nextId, }; let records = []; try { @@ -876,9 +880,9 @@ export class Record extends DataPoint { } throw e; } - if (creation && records.length) { + if ((creation || nextId) && records.length) { const resId = records[0].id; - const resIds = this.resIds.concat([resId]); + const resIds = resId in this.resIds ? this.resIds : this.resIds.concat([resId]); this.model._updateConfig(this.config, { resId, resIds }, { noReload: true }); } if (!noReload) { diff --git a/addons/web/static/src/views/form/form_controller.js b/addons/web/static/src/views/form/form_controller.js index 67d2583c6f6..b190790cbd0 100644 --- a/addons/web/static/src/views/form/form_controller.js +++ b/addons/web/static/src/views/form/form_controller.js @@ -318,14 +318,12 @@ export class FormController extends Component { async onPagerUpdate({ offset, resIds }) { const dirty = await this.model.root.isDirty(); - let canProceed = true; if (dirty) { - canProceed = await this.model.root.save({ - noReload: true, + return this.model.root.save({ onError: this.onSaveError.bind(this), + nextId: resIds[offset], }); - } - if (canProceed) { + } else { return this.model.load({ resId: resIds[offset] }); } } diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index 35af3221c95..b71fa346bba 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -1914,6 +1914,9 @@ export class MockServer { } else { this.mockWrite(modelName, args); } + if (kwargs.next_id) { + args[0] = kwargs.next_id; + } return this.mockWebRead(modelName, args, kwargs); } 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 b2ce0387135..4f5e09f28eb 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -5477,6 +5477,7 @@ QUnit.module("Views", (hooks) => { assert.strictEqual(target.querySelector(".o_pager_value").textContent, "1"); assert.strictEqual(target.querySelector(".o_pager_limit").textContent, "2"); + assert.strictEqual(target.querySelector(".o_input").value, "yop"); // edit the foo field await editInput(target, ".o_field_widget[name=foo] input", "new value"); @@ -5484,7 +5485,8 @@ QUnit.module("Views", (hooks) => { await click(target.querySelector(".o_pager_next")); assert.strictEqual(target.querySelector(".o_pager_value").textContent, "2"); - assert.verifySteps(["get_views", "web_read", "web_save", "web_read"]); + assert.strictEqual(target.querySelector(".o_input").value, "blip"); + assert.verifySteps(["get_views", "web_read", "web_save"]); }); QUnit.test("switching to another record from an invalid one", async function (assert) {