Skip to content

Commit 5db14d0

Browse files
Support comma as decimal separator in odometer input
normalizeOdometerText now converts commas to periods so both "." and "," work as decimal input in any locale. When this produces multiple decimal points (from group separators that became dots), only the last dot is kept as the decimal separator. This preserves correct handling of German "1.234,5" → "1234.5" and English "1,234.5" → "1234.5" while also allowing English "123,4" → "123.4". Co-authored-by: Chavda Sachin <ChavdaSachin@users.noreply.github.com>
1 parent 879234a commit 5db14d0

2 files changed

Lines changed: 37 additions & 6 deletions

File tree

src/libs/DistanceRequestUtils.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,15 +474,24 @@ function isDistanceAmountWithinLimit(distance: number, rate: number): boolean {
474474
* Normalize odometer text by standardizing locale digits and stripping all
475475
* non-numeric characters except the decimal point. fromLocaleDigit converts
476476
* each locale character to its standard equivalent (e.g. German ',' → '.'
477-
* for decimal, German '.' → ',' for group separator), then we keep only
478-
* digits and the standard decimal point.
477+
* for decimal, German '.' → ',' for group separator). Commas are then
478+
* treated as decimal separators so both "." and "," work as decimal input
479+
* in any locale. If this produces multiple decimal points (from group
480+
* separators that became dots), only the last dot is kept as the decimal.
481+
* Finally we keep only digits and the standard decimal point.
479482
*/
480483
function normalizeOdometerText(text: string, fromLocaleDigit: (char: string) => string): string {
481484
const standardized = replaceAllDigits(text, fromLocaleDigit);
482-
const stripped = standardized.replaceAll(/[^0-9.]/g, '');
485+
// Treat commas as decimal separators so both "." and "," work as decimal input
486+
const withCommasAsDecimals = standardized.replaceAll(',', '.');
487+
const stripped = withCommasAsDecimals.replaceAll(/[^0-9.]/g, '');
488+
// If multiple decimal points exist (e.g. from group separators that became
489+
// dots), keep only the last one as the actual decimal separator.
490+
const dotParts = stripped.split('.');
491+
const consolidated = dotParts.length > 2 ? dotParts.slice(0, -1).join('') + '.' + (dotParts.at(-1) ?? '') : stripped;
483492
// Remove redundant leading zeroes (e.g. "007" → "7", "000" → "0") but
484493
// keep a single zero before a decimal point (e.g. "0.5" stays "0.5").
485-
return stripped.replace(/^0+(?=\d)/, '');
494+
return consolidated.replace(/^0+(?=\d)/, '');
486495
}
487496

488497
export default {

tests/unit/OdometerNormalizationTest.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ describe('normalizeOdometerText', () => {
99
expect(DistanceRequestUtils.normalizeOdometerText('1,5', germanFromLocaleDigit)).toBe('1.5');
1010
});
1111

12-
it("German '1.5' (fifteen, dot is group separator) normalizes to '15'", () => {
13-
expect(DistanceRequestUtils.normalizeOdometerText('1.5', germanFromLocaleDigit)).toBe('15');
12+
it("German '1.5' (dot now treated as decimal) normalizes to '1.5'", () => {
13+
expect(DistanceRequestUtils.normalizeOdometerText('1.5', germanFromLocaleDigit)).toBe('1.5');
1414
});
1515

1616
it("German '1.234,5' (1234.5) normalizes to '1234.5'", () => {
@@ -38,6 +38,28 @@ describe('normalizeOdometerText', () => {
3838
});
3939
});
4040

41+
describe('comma as decimal separator', () => {
42+
const englishFromLocaleDigit = (char: string) => fromLocaleDigit('en', char);
43+
const germanFromLocaleDigit = (char: string) => fromLocaleDigit('de', char);
44+
45+
it("English '123,4' (comma as decimal) normalizes to '123.4'", () => {
46+
expect(DistanceRequestUtils.normalizeOdometerText('123,4', englishFromLocaleDigit)).toBe('123.4');
47+
});
48+
49+
it("English '1,234.5' (comma as group with dot decimal) normalizes to '1234.5'", () => {
50+
expect(DistanceRequestUtils.normalizeOdometerText('1,234.5', englishFromLocaleDigit)).toBe('1234.5');
51+
});
52+
53+
it("German '1.234,5' (dot-group, comma-decimal) normalizes to '1234.5'", () => {
54+
expect(DistanceRequestUtils.normalizeOdometerText('1.234,5', germanFromLocaleDigit)).toBe('1234.5');
55+
});
56+
57+
it("plain comma only: ',5' normalizes to '.5'", () => {
58+
const identity = (char: string) => char;
59+
expect(DistanceRequestUtils.normalizeOdometerText(',5', identity)).toBe('.5');
60+
});
61+
});
62+
4163
describe('leading zeroes', () => {
4264
const identity = (char: string) => char;
4365

0 commit comments

Comments
 (0)