From 49af4d6d9ad5dfe7c93c6975513b4db3bcb00dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Lef=C3=A8vre=20=28lul=29?= Date: Tue, 30 Jan 2024 11:40:46 +0100 Subject: [PATCH] [PERF] spreadsheet_dashboard: avoid currency RPC Most (if not all) dashboards have monetary amounts. They are formatted with the main company currency format. Before this commit, a RPC was made to fetch the company currency. With this commit, the dashboard is loaded with the currency. It saves one network request and a full spreadsheet evaluation (which would have occured after the request is done) closes odoo/odoo#151725 Task: 3709466 Related: odoo/enterprise#55415 Signed-off-by: Pierre Rousseau (pro) --- .../static/src/currency/helpers.js | 17 ++++++++++ .../models/spreadsheet_dashboard.py | 2 ++ .../dashboard_action/dashboard_loader.js | 12 +++++-- .../tests/dashboard/dashboard_loader_test.js | 31 +++++++++++++++++++ .../tests/test_spreadsheet_dashboard.py | 8 +++++ 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 addons/spreadsheet/static/src/currency/helpers.js diff --git a/addons/spreadsheet/static/src/currency/helpers.js b/addons/spreadsheet/static/src/currency/helpers.js new file mode 100644 index 00000000000..82f5d7ea65e --- /dev/null +++ b/addons/spreadsheet/static/src/currency/helpers.js @@ -0,0 +1,17 @@ +/** @odoo-module **/ + +import { helpers } from "@odoo/o-spreadsheet"; + +const { createCurrencyFormat } = helpers; + +/** + * @param {object} currency + * @returns {string} + */ +export function createDefaultCurrencyFormat(currency) { + return createCurrencyFormat({ + symbol: currency.symbol, + position: currency.position, + decimalPlaces: currency.decimalPlaces, + }); +} diff --git a/addons/spreadsheet_dashboard/models/spreadsheet_dashboard.py b/addons/spreadsheet_dashboard/models/spreadsheet_dashboard.py index 4a8c30e9fe6..7d75ec4cdb0 100644 --- a/addons/spreadsheet_dashboard/models/spreadsheet_dashboard.py +++ b/addons/spreadsheet_dashboard/models/spreadsheet_dashboard.py @@ -20,9 +20,11 @@ class SpreadsheetDashboard(models.Model): snapshot = json.loads(self.spreadsheet_data) user_locale = self.env['res.lang']._get_user_spreadsheet_locale() snapshot.setdefault('settings', {})['locale'] = user_locale + default_currency = self.env['res.currency'].get_company_currency_for_spreadsheet() return { 'snapshot': snapshot, 'revisions': [], + 'default_currency': default_currency, } def copy(self, default=None): diff --git a/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js b/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js index 82eea59558d..329335973b1 100644 --- a/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js +++ b/addons/spreadsheet_dashboard/static/src/bundle/dashboard_action/dashboard_loader.js @@ -3,6 +3,7 @@ import { DataSources } from "@spreadsheet/data_sources/data_sources"; import { migrate } from "@spreadsheet/o_spreadsheet/migration"; import { Model } from "@odoo/o-spreadsheet"; +import { createDefaultCurrencyFormat } from "@spreadsheet/currency/helpers"; /** * @type {{ @@ -161,12 +162,12 @@ export class DashboardLoader { const dashboard = this._getDashboard(dashboardId); dashboard.status = Status.Loading; try { - const { snapshot, revisions } = await this.orm.call( + const { snapshot, revisions, default_currency } = await this.orm.call( "spreadsheet.dashboard", "get_readonly_dashboard", [dashboardId] ); - dashboard.model = this._createSpreadsheetModel(snapshot, revisions); + dashboard.model = this._createSpreadsheetModel(snapshot, revisions, default_currency); dashboard.status = Status.Loaded; } catch (error) { dashboard.error = error; @@ -195,15 +196,20 @@ export class DashboardLoader { * @private * @param {object} snapshot * @param {object[]} revisions + * @param {object} [defaultCurrency] * @returns {Model} */ - _createSpreadsheetModel(snapshot, revisions = []) { + _createSpreadsheetModel(snapshot, revisions = [], defaultCurrency) { const dataSources = new DataSources(this.env); + const defaultCurrencyFormat = defaultCurrency + ? createDefaultCurrencyFormat(defaultCurrency) + : undefined; const model = new Model( migrate(snapshot), { custom: { env: this.env, orm: this.orm, dataSources }, mode: "dashboard", + defaultCurrencyFormat, }, revisions ); diff --git a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js index dbb1294680e..9b91456dd2e 100644 --- a/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js +++ b/addons/spreadsheet_dashboard/static/tests/dashboard/dashboard_loader_test.js @@ -276,3 +276,34 @@ QUnit.test("Model is in dashboard mode", async (assert) => { await nextTick(); assert.verifySteps(["activate sheet"]); }); + +QUnit.test("default currency format", async (assert) => { + const loader = await createDashboardLoader({ + mockRPC: function (route, args) { + if ( + args.model === "spreadsheet.dashboard" && + args.method === "get_readonly_dashboard" + ) { + return { + data: {}, + revisions: [], + default_currency: { + code: "Odoo", + symbol: "θ", + position: "after", + decimalPlaces: 2, + }, + }; + } + if (args.method === "get_company_currency_for_spreadsheet") { + throw new Error("Should not make any RPC"); + } + }, + }); + await loader.load(); + const result = loader.getDashboard(3); + assert.strictEqual(result.status, Status.Loading); + await nextTick(); + const { model } = loader.getDashboard(3); + assert.strictEqual(model.getters.getCompanyCurrencyFormat(), "#,##0.00[$θ]"); +}); diff --git a/addons/spreadsheet_dashboard/tests/test_spreadsheet_dashboard.py b/addons/spreadsheet_dashboard/tests/test_spreadsheet_dashboard.py index d44be21a031..c54f3431178 100644 --- a/addons/spreadsheet_dashboard/tests/test_spreadsheet_dashboard.py +++ b/addons/spreadsheet_dashboard/tests/test_spreadsheet_dashboard.py @@ -65,3 +65,11 @@ class TestSpreadsheetDashboard(DashboardTestCommon): locale = data["snapshot"]["settings"]["locale"] self.assertEqual(locale["code"], "fr_FR") self.assertEqual(len(data["revisions"]), 0) + + def test_load_with_company_currency(self): + dashboard = self.create_dashboard().with_user(self.user) + data = dashboard.get_readonly_dashboard() + self.assertEqual( + data["default_currency"], + self.env["res.currency"].get_company_currency_for_spreadsheet() + )