[REF] web: move parseMonetary to currency

closes odoo-dev/odoo#926

Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
Jorge Pinna Puissant
2021-06-18 21:31:30 +02:00
committed by Aaron Bohy
parent 41e5435d97
commit 22bb866588
4 changed files with 82 additions and 81 deletions
+35 -1
View File
@@ -1,6 +1,6 @@
/** @odoo-module **/
import { formatFloat, humanNumber } from "./numbers";
import { formatFloat, humanNumber, parseFloat, InvalidNumberError } from "./numbers";
/**
* Formats a value as a currency.
@@ -36,3 +36,37 @@ export function formatCurrency(value, cid, options = {}) {
return `${currency.symbol} ${formatted}`;
}
}
/**
* Try to extract a monetary value from a string. The localization is considered in the process.
* The monetary value can have the formats sym$&nbsp;float, float$&nbsp;sym or float
* where $&nbsp; is a non breaking space and sym is a currency symbol.
* If a symbol is found it must correspond to the default currency symbol or to the
* symbol of the currency whose id is passed in options.
*
* @param {string} value
* @param {Object} [options={}]
* @param {number} [options.currencyId]
* @returns {number} float
*/
export function parseCurrency(value, options = {}) {
let values = value.split("&nbsp;");
if (values.length === 1) {
return parseFloat(value);
}
let currency;
if (options.currencyId) {
currency = odoo.session_info.currencies[options.currencyId];
} else {
currency = Object.values(odoo.session_info.currencies)[0];
}
const symbolIndex = values.findIndex((v) => v === currency.symbol);
if (symbolIndex === -1) {
throw new InvalidNumberError(`"${value}" is not a correct number`);
}
values.splice(symbolIndex, 1);
if (values.length !== 1) {
throw new InvalidNumberError(`"${value}" is not a correct number`);
}
return parseFloat(values[0]);
}
+1 -35
View File
@@ -4,7 +4,7 @@ import { escapeRegExp, intersperse } from "../utils/strings";
import { localization } from "./localization";
import { _lt } from "./translation";
class InvalidNumberError extends Error {}
export class InvalidNumberError extends Error {}
// -----------------------------------------------------------------------------
// Helpers
@@ -136,40 +136,6 @@ export function parseInteger(value) {
return parsed;
}
/**
* Try to extract a monetary value from a string. The localization is considered in the process.
* The monetary value can have the formats sym$&nbsp;float, float$&nbsp;sym or float
* where $&nbsp; is a non breaking space and sym is a currency symbol.
* If a symbol is found it must correspond to the default currency symbol or to the
* symbol of the currency whose id is passed in options.
*
* @param {string} value
* @param {Object} [options={}]
* @param {number} [options.currencyId]
* @returns {number} float
*/
export function parseMonetary(value, options = {}) {
let values = value.split("&nbsp;");
if (values.length === 1) {
return parseFloat(value);
}
let currency;
if (options.currencyId) {
currency = odoo.session_info.currencies[options.currencyId];
} else {
currency = Object.values(odoo.session_info.currencies)[0];
}
const symbolIndex = values.findIndex((v) => v === currency.symbol);
if (symbolIndex === -1) {
throw new InvalidNumberError(`"${value}" is not a correct number`);
}
values.splice(symbolIndex, 1);
if (values.length !== 1) {
throw new InvalidNumberError(`"${value}" is not a correct number`);
}
return parseFloat(values[0]);
}
/**
* Try to extract a float from a string and unconvert it with a conversion factor of 100.
* The localization is considered in the process.
@@ -1,15 +1,18 @@
/** @odoo-module **/
import { formatCurrency } from "@web/core/l10n/currency";
import { formatCurrency, parseCurrency } from "@web/core/l10n/currency";
import { localization } from "@web/core/l10n/localization";
import { patch, unpatch } from "@web/core/utils/patch";
import { defaultLocalization } from "../../helpers/mock_services";
import { patchWithCleanup } from "@web/../tests/helpers/utils";
QUnit.module("utils", () => {
QUnit.module("utils", (hooks) => {
hooks.beforeEach(() => {
patchWithCleanup(localization, defaultLocalization);
});
QUnit.module("Currency");
QUnit.test("format", async (assert) => {
patch(localization, "locpatch", defaultLocalization);
assert.deepEqual(formatCurrency(1234567.654, 1), "$ 1,234,567.65");
assert.deepEqual(formatCurrency(1234567.654, 2), "1,234,567.65 €");
assert.deepEqual(
@@ -26,7 +29,46 @@ QUnit.module("utils", () => {
"currency digits should take over options digits when both are defined"
);
assert.strictEqual(formatCurrency(false, 2), "");
unpatch(localization, "locpatch");
});
QUnit.test("parseCurrency", function (assert) {
assert.expect(17);
patchWithCleanup(odoo.session_info, {
currencies: {
1: {
digits: [69, 2],
position: "after",
symbol: "€",
},
3: {
digits: [69, 2],
position: "before",
symbol: "$",
},
},
});
assert.strictEqual(parseCurrency(""), 0);
assert.strictEqual(parseCurrency("0"), 0);
assert.strictEqual(parseCurrency("100.00&nbsp;€"), 100);
assert.strictEqual(parseCurrency("-100.00"), -100);
assert.strictEqual(parseCurrency("1,000.00"), 1000);
assert.strictEqual(parseCurrency("1,000,000.00"), 1000000);
assert.strictEqual(parseCurrency("$&nbsp;125.00", { currencyId: 3 }), 125);
assert.strictEqual(parseCurrency("1,000.00&nbsp;€", { currencyId: 1 }), 1000);
assert.throws(() => parseCurrency("&nbsp;", { currencyId: 3 }));
assert.throws(() => parseCurrency("1&nbsp;", { currencyId: 3 }));
assert.throws(() => parseCurrency("&nbsp;1", { currencyId: 3 }));
assert.throws(() => parseCurrency("12.00 €"));
assert.throws(() => parseCurrency("$ 12.00", { currencyId: 3 }));
assert.throws(() => parseCurrency("1&nbsp;$", { currencyId: 1 }));
assert.throws(() => parseCurrency("$&nbsp;1")); // "€" is the default currency here
assert.throws(() => parseCurrency("1$&nbsp;1", { currencyId: 1 }));
assert.throws(() => parseCurrency("$&nbsp;12.00&nbsp;34", { currencyId: 3 }));
});
// BOI: we do not have a parse method, but here are some tests if we want to add this at some point.
@@ -7,7 +7,6 @@ import {
parseFloat,
parseFloatTime,
parseInteger,
parseMonetary,
parsePercentage,
} from "@web/core/l10n/numbers";
import { localization } from "@web/core/l10n/localization";
@@ -129,46 +128,6 @@ QUnit.module("utils", (hooks) => {
expectInvalidNumberError(assert, parseInteger, "1.234,567");
});
QUnit.test("parseMonetary", function (assert) {
assert.expect(17);
patchWithCleanup(odoo.session_info, {
currencies: {
1: {
digits: [69, 2],
position: "after",
symbol: "€",
},
3: {
digits: [69, 2],
position: "before",
symbol: "$",
},
},
});
assert.strictEqual(parseMonetary(""), 0);
assert.strictEqual(parseMonetary("0"), 0);
assert.strictEqual(parseMonetary("100.00&nbsp;€"), 100);
assert.strictEqual(parseMonetary("-100.00"), -100);
assert.strictEqual(parseMonetary("1,000.00"), 1000);
assert.strictEqual(parseMonetary("1,000,000.00"), 1000000);
assert.strictEqual(parseMonetary("$&nbsp;125.00", { currencyId: 3 }), 125);
assert.strictEqual(parseMonetary("1,000.00&nbsp;€", { currencyId: 1 }), 1000);
expectInvalidNumberError(assert, parseMonetary, "&nbsp;", { currencyId: 3 });
expectInvalidNumberError(assert, parseMonetary, "1&nbsp;", { currencyId: 3 });
expectInvalidNumberError(assert, parseMonetary, "&nbsp;1", { currencyId: 3 });
expectInvalidNumberError(assert, parseMonetary, "12.00 €");
expectInvalidNumberError(assert, parseMonetary, "$ 12.00", { currencyId: 3 });
expectInvalidNumberError(assert, parseMonetary, "1&nbsp;$", { currencyId: 1 });
expectInvalidNumberError(assert, parseMonetary, "$&nbsp;1"); // "€" is the default currency here
expectInvalidNumberError(assert, parseMonetary, "1$&nbsp;1", { currencyId: 1 });
expectInvalidNumberError(assert, parseMonetary, "$&nbsp;12.00&nbsp;34", { currencyId: 3 });
});
QUnit.test("parsePercentage", function (assert) {
assert.expect(9);