[FIX] web: generalize whitespace separator when parsing

**Issue:**

When the thousands separator is "nbsp" and the user inputs a value
that is "1 234", the parser will crash because the thousands separator
is different from what is manually inputted by the user.

This is problematic because when typing, it's very difficult for
users to enter "nbsp" character in their input.

**Solution:**

This change proposes that if the thousands separator is a whitespace,
we consider all whitespace characters from user input as thousands
separator. As a result, even if the thousands separator is "nbsp",
the system will successfully parse "1 234" as 1234.

X-original-commit: bffddcf015da9cf514fc25cc7f839e923e470d94
Part-of: odoo/odoo#107862
This commit is contained in:
Joseph Caburnay
2022-12-13 17:03:25 +01:00
parent 89c6124599
commit 4e5eebf966
2 changed files with 14 additions and 1 deletions
@@ -44,8 +44,15 @@ function parseNumber(value, options = {}) {
value = Math.trunc(value);
}
} else {
// A whitespace thousands separator is equivalent to any whitespace character.
// E.g. "1 000 000" should be parsed as 1000000 even if the
// thousands separator is nbsp.
const thousandsSepRegex = options.thousandsSep.match(/\s+/)
? /\s+/g
: new RegExp(escapeRegExp(options.thousandsSep), "g") || ",";
// a number can have the thousand separator multiple times. ex: 1,000,000.00
value = value.replaceAll(new RegExp(escapeRegExp(options.thousandsSep), "g") || ",", "");
value = value.replaceAll(thousandsSepRegex, "");
// a number only have one decimal separator
value = value.replace(new RegExp(escapeRegExp(options.decimalPoint), "g") || ".", ".");
}
@@ -11,6 +11,7 @@ import {
import { session } from "@web/session";
import { defaultLocalization } from "@web/../tests/helpers/mock_services";
import { patchWithCleanup } from "@web/../tests/helpers/utils";
import { nbsp } from "@web/core/utils/strings";
function expectInvalidNumberError(assert, func, value, options) {
let message = `${func.name} fails on value: "${value}"`;
@@ -48,6 +49,11 @@ QUnit.module("Fields", (hooks) => {
patchWithCleanup(localization, { decimalPoint: ",", thousandsSep: false });
assert.strictEqual(parseFloat("1234,567"), 1234.567);
patchWithCleanup(localization, { decimalPoint: ",", thousandsSep: nbsp });
assert.strictEqual(parseFloat("9 876,543"), 9876.543);
assert.strictEqual(parseFloat("1 234 567,89"), 1234567.89);
assert.strictEqual(parseFloat(`98${nbsp}765 432,1`), 98765432.1);
});
QUnit.test("parseFloatTime", function (assert) {