diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportService.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportService.java index eaf3ecde728f5917986fa62b246f26ab22b9fae6..cc7ddc6471154d238679d2fee440b6bbdf7d0cbe 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportService.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportService.java @@ -41,7 +41,7 @@ public class TransactionImportService final String description = csvRow.getColumns().get(csvColumnSettings.columnDescription() - 1); final String amount = csvRow.getColumns().get(csvColumnSettings.columnAmount() - 1); - final Optional<Integer> parsedAmountOptional = AmountParser.parse(amount); + final Optional<Integer> parsedAmountOptional = AmountParser.parse(amount, '.', ','); if(parsedAmountOptional.isEmpty()) { throw new CsvTransactionParseException(Localization.getString("transactions.import.error.parse.amount", index + 1)); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/AmountParser.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/AmountParser.java index 2d87372d59dcbf11bc9c20a788cdd185f2ce357d..4b3ef7fdbf91c122a789129211d7536ac22edab4 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/AmountParser.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/AmountParser.java @@ -1,19 +1,22 @@ package de.deadlocker8.budgetmaster.transactions.csvimport; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.MessageFormat; +import java.text.ParseException; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AmountParser { - private static final Pattern PATTERN_AMOUNT = Pattern.compile("^\\s*([-+]?)\\s*(\\d+(,\\d+)?(\\.\\d+)?)"); + private static final Pattern PATTERN_AMOUNT = Pattern.compile("^\\s*([-+]?)\\s*(\\d+(.*\\d+)?)"); private AmountParser() { } - public static Optional<Integer> parse(String amountString) + public static Optional<Integer> parse(String amountString, char decimalSeparator, char groupingSeparator) { if(amountString == null) { @@ -24,17 +27,28 @@ public class AmountParser boolean matchFound = matcher.find(); if(matchFound) { - final String sign = matcher.group(1); - String amount = matcher.group(2); - amount = amount.replace(',', '.'); + String sign = matcher.group(1); + if(sign.equals("+")) + { + sign = ""; + } + + final String amount = matcher.group(2); + + final DecimalFormat decimalFormat = new DecimalFormat(); + final DecimalFormatSymbols symbols = new DecimalFormatSymbols(); + symbols.setDecimalSeparator(decimalSeparator); + symbols.setGroupingSeparator(groupingSeparator); + decimalFormat.setNegativePrefix("-"); + decimalFormat.setDecimalFormatSymbols(symbols); final String parseableString = MessageFormat.format("{0}{1}", sign, amount); try { - final double parseDouble = Double.parseDouble(parseableString); + final double parseDouble = decimalFormat.parse(parseableString).doubleValue(); return Optional.of((int) (parseDouble * 100)); } - catch(NumberFormatException e) + catch(ParseException e) { return Optional.empty(); } diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/transaction/csvimport/AmountParserTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/transaction/csvimport/AmountParserTest.java index 5fdf610d80920043f34d79942337928f808fed9a..ed074cb52890bfbe2cf9eb9a66a2ff4f8d545ed4 100644 --- a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/transaction/csvimport/AmountParserTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/transaction/csvimport/AmountParserTest.java @@ -13,7 +13,7 @@ class AmountParserTest @Test void test_dot_positive_noCurrency() { - assertThat(AmountParser.parse("12.03")) + assertThat(AmountParser.parse("12.03", '.', ',')) .isPresent() .get().isEqualTo(1203); } @@ -21,7 +21,7 @@ class AmountParserTest @Test void test_dot_negative_noCurrency() { - assertThat(AmountParser.parse("-18.41")) + assertThat(AmountParser.parse("-18.41", '.', ',')) .isPresent() .get().isEqualTo(-1841); } @@ -29,7 +29,7 @@ class AmountParserTest @Test void test_dot_negativeWithSpace_noCurrency() { - assertThat(AmountParser.parse("- 200.30")) + assertThat(AmountParser.parse("- 200.30", '.', ',')) .isPresent() .get().isEqualTo(-20030); } @@ -37,7 +37,7 @@ class AmountParserTest @Test void test_dot_positive_currency() { - assertThat(AmountParser.parse("12.03 €")) + assertThat(AmountParser.parse("12.03 €", '.', ',')) .isPresent() .get().isEqualTo(1203); } @@ -45,7 +45,7 @@ class AmountParserTest @Test void test_dot_negative_currency() { - assertThat(AmountParser.parse("-18.41€")) + assertThat(AmountParser.parse("-18.41€", '.', ',')) .isPresent() .get().isEqualTo(-1841); } @@ -53,7 +53,7 @@ class AmountParserTest @Test void test_dot_positiveWithSign_noCurrency() { - assertThat(AmountParser.parse("+12.03")) + assertThat(AmountParser.parse("+12.03", '.', ',')) .isPresent() .get().isEqualTo(1203); } @@ -61,7 +61,7 @@ class AmountParserTest @Test void test_dot_positiveWithSignWithSpace_noCurrency() { - assertThat(AmountParser.parse("+ 12.03")) + assertThat(AmountParser.parse("+ 12.03", '.', ',')) .isPresent() .get().isEqualTo(1203); } @@ -69,7 +69,7 @@ class AmountParserTest @Test void test_comma_positive_noCurrency() { - assertThat(AmountParser.parse("12,03")) + assertThat(AmountParser.parse("12,03", ',', '.')) .isPresent() .get().isEqualTo(1203); } @@ -77,7 +77,7 @@ class AmountParserTest @Test void test_comma_negative_noCurrency() { - assertThat(AmountParser.parse("-18,41")) + assertThat(AmountParser.parse("-18,41", ',', '.')) .isPresent() .get().isEqualTo(-1841); } @@ -85,7 +85,7 @@ class AmountParserTest @Test void test_comma_negativeWithSpace_noCurrency() { - assertThat(AmountParser.parse("- 200,30")) + assertThat(AmountParser.parse("- 200,30", ',', '.')) .isPresent() .get().isEqualTo(-20030); } @@ -93,7 +93,7 @@ class AmountParserTest @Test void test_comma_positive_currency() { - assertThat(AmountParser.parse("12,03 €")) + assertThat(AmountParser.parse("12,03 €", ',', '.')) .isPresent() .get().isEqualTo(1203); } @@ -101,7 +101,7 @@ class AmountParserTest @Test void test_comma_negative_currency() { - assertThat(AmountParser.parse("-18,41€")) + assertThat(AmountParser.parse("-18,41€", ',', '.')) .isPresent() .get().isEqualTo(-1841); } @@ -109,7 +109,7 @@ class AmountParserTest @Test void test_comma_positiveWithSign_noCurrency() { - assertThat(AmountParser.parse("+12,03")) + assertThat(AmountParser.parse("+12,03", ',', '.')) .isPresent() .get().isEqualTo(1203); } @@ -117,7 +117,7 @@ class AmountParserTest @Test void test_comma_positiveWithSignWithSpace_noCurrency() { - assertThat(AmountParser.parse("+12,03")) + assertThat(AmountParser.parse("+12,03", ',', '.')) .isPresent() .get().isEqualTo(1203); } @@ -125,35 +125,35 @@ class AmountParserTest @Test void test_invalid_null() { - assertThat(AmountParser.parse(null)) + assertThat(AmountParser.parse(null, '.', ',')) .isEmpty(); } @Test void test_invalid_empty() { - assertThat(AmountParser.parse("")) + assertThat(AmountParser.parse("", '.', ',')) .isEmpty(); } @Test void test_invalid_empty2() { - assertThat(AmountParser.parse(" ")) + assertThat(AmountParser.parse(" ", '.', ',')) .isEmpty(); } @Test void test_invalid() { - assertThat(AmountParser.parse("abc.42€")) + assertThat(AmountParser.parse("abc.42€", '.', ',')) .isEmpty(); } @Test void test_integer_positive_noCurrency() { - assertThat(AmountParser.parse("12")) + assertThat(AmountParser.parse("12", '.', ',')) .isPresent() .get().isEqualTo(1200); } @@ -161,7 +161,7 @@ class AmountParserTest @Test void test_integer_negative_noCurrency() { - assertThat(AmountParser.parse("-18")) + assertThat(AmountParser.parse("-18", '.', ',')) .isPresent() .get().isEqualTo(-1800); } @@ -169,7 +169,7 @@ class AmountParserTest @Test void test_integer_negativeWithSpace_noCurrency() { - assertThat(AmountParser.parse("- 200")) + assertThat(AmountParser.parse("- 200", '.', ',')) .isPresent() .get().isEqualTo(-20000); } @@ -177,7 +177,7 @@ class AmountParserTest @Test void test_integer_positive_currency() { - assertThat(AmountParser.parse("12 €")) + assertThat(AmountParser.parse("12 €", '.', ',')) .isPresent() .get().isEqualTo(1200); } @@ -185,7 +185,7 @@ class AmountParserTest @Test void test_integer_negative_currency() { - assertThat(AmountParser.parse("-18€")) + assertThat(AmountParser.parse("-18€", '.', ',')) .isPresent() .get().isEqualTo(-1800); } @@ -193,7 +193,7 @@ class AmountParserTest @Test void test_integer_positiveWithSign_noCurrency() { - assertThat(AmountParser.parse("+12")) + assertThat(AmountParser.parse("+12", '.', ',')) .isPresent() .get().isEqualTo(1200); } @@ -201,8 +201,56 @@ class AmountParserTest @Test void test_integer_positiveWithSignWithSpace_noCurrency() { - assertThat(AmountParser.parse("+ 12")) + assertThat(AmountParser.parse("+ 12", '.', ',')) .isPresent() .get().isEqualTo(1200); } + + @Test + void test_thousandsDelimiter_integer() + { + assertThat(AmountParser.parse("1,234", '.', ',')) + .isPresent() + .get().isEqualTo(123400); + } + + @Test + void test_thousandsDelimiter_dot() + { + assertThat(AmountParser.parse("1,234.03", '.', ',')) + .isPresent() + .get().isEqualTo(123403); + } + + @Test + void test_thousandsDelimiter_withCurrency() + { + assertThat(AmountParser.parse("1,234.03 €", '.', ',')) + .isPresent() + .get().isEqualTo(123403); + } + + @Test + void test_thousandsDelimiter_negative() + { + assertThat(AmountParser.parse("-1,234.03 €", '.', ',')) + .isPresent() + .get().isEqualTo(-123403); + } + + @Test + void test_thousandsDelimiter_specialDelimiter() + { + assertThat(AmountParser.parse("-1.234,03 €", ',', '.')) + .isPresent() + .get().isEqualTo(-123403); + } + + @Test + void test_thousandsDelimiter_bigNumber() + { + assertThat(AmountParser.parse("-1.234.567,03 €", ',', '.')) + .isPresent() + .get().isEqualTo(-123456703); + } }