From 5a77051a725eb2dedfebd06888410bcd475fed85 Mon Sep 17 00:00:00 2001
From: Wizmaster <code@wizmaster.fr>
Date: Thu, 16 May 2024 17:02:27 +0200
Subject: [PATCH] Make comma's and period interchangeable when entering figures
 (#2672)

- Only allowed for formats not using period or comma as a thousand separator
---
 packages/loot-core/src/shared/arithmetic.ts | 23 +++--------------
 packages/loot-core/src/shared/util.ts       | 28 +++++++++++++++------
 upcoming-release-notes/2672.md              |  6 +++++
 3 files changed, 30 insertions(+), 27 deletions(-)
 create mode 100644 upcoming-release-notes/2672.md

diff --git a/packages/loot-core/src/shared/arithmetic.ts b/packages/loot-core/src/shared/arithmetic.ts
index ac8227864..f69543b1d 100644
--- a/packages/loot-core/src/shared/arithmetic.ts
+++ b/packages/loot-core/src/shared/arithmetic.ts
@@ -1,5 +1,5 @@
 // @ts-strict-ignore
-import { getNumberFormat } from './util';
+import { currencyToAmount } from './util';
 
 function fail(state, msg) {
   throw new Error(
@@ -37,31 +37,16 @@ function parsePrimary(state) {
     next(state);
   }
 
-  if (/\p{Sc}/u.test(char(state))) {
-    next(state);
-  }
-
-  // TODO: The regex should probably respect the number format better,
-  // and we should do more strict parsing
   let numberStr = '';
-  while (char(state) && char(state).match(/[0-9,.]/)) {
-    const thousandsSep = getNumberFormat().separator === ',' ? '.' : ',';
-
-    // Don't include the thousands separator
-    if (char(state) === thousandsSep) {
-      next(state);
-    } else {
-      numberStr += next(state);
-    }
+  while (char(state) && char(state).match(/[0-9,. ]|\p{Sc}/u)) {
+    numberStr += next(state);
   }
 
   if (numberStr === '') {
     fail(state, 'Unexpected character');
   }
 
-  const number = parseFloat(
-    numberStr.replace(getNumberFormat().separator, '.'),
-  );
+  const number = currencyToAmount(numberStr);
   return isNegative ? -number : number;
 }
 
diff --git a/packages/loot-core/src/shared/util.ts b/packages/loot-core/src/shared/util.ts
index ac2680712..7429e58ef 100644
--- a/packages/loot-core/src/shared/util.ts
+++ b/packages/loot-core/src/shared/util.ts
@@ -255,13 +255,14 @@ export function getNumberFormat({
   format?: NumberFormats;
   hideFraction: boolean;
 } = numberFormatConfig) {
-  let locale, regex, separator;
+  let locale, regex, separator, separatorRegex;
 
   switch (format) {
     case 'space-comma':
       locale = 'en-SE';
-      regex = /[^-0-9,]/g;
+      regex = /[^-0-9,.]/g;
       separator = ',';
+      separatorRegex = /[,.]/g;
       break;
     case 'dot-comma':
       locale = 'de-DE';
@@ -270,8 +271,9 @@ export function getNumberFormat({
       break;
     case 'space-dot':
       locale = 'dje';
-      regex = /[^-0-9.]/g;
+      regex = /[^-0-9,.]/g;
       separator = '.';
+      separatorRegex = /[,.]/g;
       break;
     case 'comma-dot-in':
       locale = 'en-IN';
@@ -293,6 +295,7 @@ export function getNumberFormat({
       maximumFractionDigits: hideFraction ? 0 : 2,
     }),
     regex,
+    separatorRegex,
   };
 }
 
@@ -342,11 +345,20 @@ export function amountToCurrencyNoDecimal(n) {
 }
 
 export function currencyToAmount(str: string) {
-  const amount = parseFloat(
-    str
-      .replace(getNumberFormat().regex, '')
-      .replace(getNumberFormat().separator, '.'),
-  );
+  let amount;
+  if (getNumberFormat().separatorRegex) {
+    amount = parseFloat(
+      str
+        .replace(getNumberFormat().regex, '')
+        .replace(getNumberFormat().separatorRegex, '.'),
+    );
+  } else {
+    amount = parseFloat(
+      str
+        .replace(getNumberFormat().regex, '')
+        .replace(getNumberFormat().separator, '.'),
+    );
+  }
   return isNaN(amount) ? null : amount;
 }
 
diff --git a/upcoming-release-notes/2672.md b/upcoming-release-notes/2672.md
new file mode 100644
index 000000000..6940f9cd9
--- /dev/null
+++ b/upcoming-release-notes/2672.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [Wizmaster]
+---
+
+Comma and period decimal separator can both be used for number format not using those as thousand separator.
-- 
GitLab