[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) <pro@odoo.com>
This commit is contained in:
Lucas Lefèvre (lul)
2024-02-12 20:24:01 +00:00
parent fc032efc2d
commit 49af4d6d9a
5 changed files with 67 additions and 3 deletions
@@ -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,
});
}
@@ -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):
@@ -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
);
@@ -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[$θ]");
});
@@ -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()
)