Skip to content

Commit

Permalink
#724 - parse date from csv
Browse files Browse the repository at this point in the history
  • Loading branch information
deadlocker8 committed Jan 14, 2023
1 parent 31250ff commit 9fc90b8
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import de.deadlocker8.budgetmaster.categories.CategoryService;
import de.deadlocker8.budgetmaster.categories.CategoryType;
import de.deadlocker8.budgetmaster.controller.BaseController;
import de.deadlocker8.budgetmaster.services.DateFormatStyle;
import de.deadlocker8.budgetmaster.services.HelpersService;
import de.deadlocker8.budgetmaster.settings.SettingsService;
import de.deadlocker8.budgetmaster.transactions.csvimport.*;
import de.deadlocker8.budgetmaster.utils.Mappings;
import de.thecodelabs.utils.util.Localization;
Expand Down Expand Up @@ -60,14 +62,16 @@ private RequestAttributeNames()
private final HelpersService helpers;
private final CategoryService categoryService;
private final AccountService accountService;
private final SettingsService settingsService;

@Autowired
public TransactionImportController(TransactionService transactionService, HelpersService helpers, CategoryService categoryService, AccountService accountService)
public TransactionImportController(TransactionService transactionService, HelpersService helpers, CategoryService categoryService, AccountService accountService, SettingsService settingsService)
{
this.transactionService = transactionService;
this.helpers = helpers;
this.categoryService = categoryService;
this.accountService = accountService;
this.settingsService = settingsService;
}

@GetMapping
Expand Down Expand Up @@ -159,25 +163,17 @@ public String columnSettings(WebRequest request,
final CsvRow csvRow = csvRows.get(i);
try
{
final String date = csvRow.getColumns().get(csvColumnSettings.columnDate() - 1);
final String name = csvRow.getColumns().get(csvColumnSettings.columnName() - 1);
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);
if(parsedAmountOptional.isEmpty())
{
errors.add(Localization.getString("transactions.import.error.parse.amount", i, csvRow));
continue;
}

csvTransactions.add(new CsvTransaction(date, name, parsedAmountOptional.get(), description, CsvTransactionStatus.PENDING));
csvTransactions.add(createCsvTransactionFromCsvRow(csvRow, csvColumnSettings, i));
}
catch(IndexOutOfBoundsException e)
{
LOGGER.error("Invalid access to column", e);
errors.add(Localization.getString("transactions.import.error.column", i, csvRow));
}
catch(CsvTransactionParseException e)
{
errors.add(e.getMessage());
}
}

request.setAttribute(RequestAttributeNames.ERRORS_COLUMN_SETTINGS, errors, RequestAttributes.SCOPE_SESSION);
Expand All @@ -186,6 +182,28 @@ public String columnSettings(WebRequest request,
return ReturnValues.REDIRECT_IMPORT;
}

private CsvTransaction createCsvTransactionFromCsvRow(CsvRow csvRow, CsvColumnSettings csvColumnSettings, Integer index) throws CsvTransactionParseException
{
final String date = csvRow.getColumns().get(csvColumnSettings.columnDate() - 1);
final Optional<LocalDate> parsedDateOptional = DateParser.parse(date, DateFormatStyle.LONG.getKey(), settingsService.getSettings().getLanguage().getLocale());
if(parsedDateOptional.isEmpty())
{
throw new CsvTransactionParseException(Localization.getString("transactions.import.error.parse.date", index, csvRow));
}

final String name = csvRow.getColumns().get(csvColumnSettings.columnName() - 1);
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);
if(parsedAmountOptional.isEmpty())
{
throw new CsvTransactionParseException(Localization.getString("transactions.import.error.parse.amount", index, csvRow));
}

return new CsvTransaction(parsedDateOptional.get(), name, parsedAmountOptional.get(), description, CsvTransactionStatus.PENDING);
}

@GetMapping("/cancel")
public String cancel(WebRequest request)
{
Expand Down Expand Up @@ -223,8 +241,7 @@ public String newTransaction(WebRequest request,

final Transaction newTransaction = createTransactionFromCsvTransaction(csvTransaction);

// TODO use csvTransaction.getDate() instead of debug date
transactionService.prepareModelNewOrEdit(model, false, LocalDate.now(), false, newTransaction, accountService.getAllActivatedAccountsAsc());
transactionService.prepareModelNewOrEdit(model, false, csvTransaction.getDate(), false, newTransaction, accountService.getAllActivatedAccountsAsc());

if(type.equals("transfer"))
{
Expand Down Expand Up @@ -260,8 +277,7 @@ public String newTransactionInPlace(WebRequest request,
private Transaction createTransactionFromCsvTransaction(CsvTransaction csvTransaction)
{
final Transaction newTransaction = new Transaction();
// TODO parse first
// newTransaction.setDate(csvTransaction.getDate());
newTransaction.setDate(csvTransaction.getDate());
newTransaction.setName(csvTransaction.getName());
newTransaction.setDescription(csvTransaction.getDescription());
newTransaction.setAmount(csvTransaction.getAmount());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package de.deadlocker8.budgetmaster.transactions.csvimport;

import java.time.LocalDate;
import java.util.Objects;

public final class CsvTransaction
{
private final String date;
private final LocalDate date;
private String name;
private final Integer amount;
private String description;
private CsvTransactionStatus status;

public CsvTransaction(String date, String name, Integer amount, String description, CsvTransactionStatus status)
public CsvTransaction(LocalDate date, String name, Integer amount, String description, CsvTransactionStatus status)
{
this.date = date;
this.name = name;
Expand All @@ -19,7 +20,7 @@ public CsvTransaction(String date, String name, Integer amount, String descripti
this.status = status;
}

public String getDate()
public LocalDate getDate()
{
return date;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.deadlocker8.budgetmaster.transactions.csvimport;

public class CsvTransactionParseException extends Exception
{
public CsvTransactionParseException(String message)
{
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package de.deadlocker8.budgetmaster.transactions.csvimport;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import java.util.Optional;

public class DateParser
{

private DateParser()
{
}

public static Optional<LocalDate> parse(String dateString, String pattern, Locale locale)
{
if(dateString == null || pattern == null || locale == null)
{
return Optional.empty();
}

try
{
return Optional.of(LocalDate.parse(dateString, DateTimeFormatter.ofPattern(pattern).withLocale(locale)));
}
catch(DateTimeParseException e)
{
return Optional.empty();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ transactions.import.status.skipped=übersprungen
transactions.import.actions=Aktionen
transactions.import.error.column=Zugeordnete Spalten in Zeile {0} (Zählung beginnt relativ zu Anzahl übersprungener Zeilen) nicht gefunden: {1}
transactions.import.error.parse.amount=Fehler beim Parsen des Betrags in Zeile {0} (Zählung beginnt relativ zu Anzahl übersprungener Zeilen)
transactions.import.error.parse.date=Fehler beim Parsen des Datums in Zeile {0} (Zählung beginnt relativ zu Anzahl übersprungener Zeilen)

repeating.button.add=Wiederholung hinzufügen
repeating.button.remove=Wiederholung entfernen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ transactions.import.status.skipped=skipped
transactions.import.actions=Actions
transactions.import.error.column=Associated columns not found in row {0} (counting starts relative to the number of skipped rows): {1}
transactions.import.error.parse.amount=Error parsing the amount in line {0} (counting starts relative to number of skipped lines)
transactions.import.error.parse.date=Error parsing the date in line {0} (counting starts relative to number of skipped lines)

repeating.button.add=Add repetition
repeating.button.remove=Remove repetition
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package de.deadlocker8.budgetmaster.unit.transaction.csvimport;

import de.deadlocker8.budgetmaster.transactions.csvimport.DateParser;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;

class DateParserTest
{
@Test
void test_nullText()
{
assertThat(DateParser.parse(null, "dd.MM", Locale.ENGLISH))
.isEmpty();
}

@Test
void test_nullPattern()
{
assertThat(DateParser.parse("14.01.23", null, Locale.ENGLISH))
.isEmpty();
}

@Test
void test_textNotMatchingPattern()
{
assertThat(DateParser.parse("14.01.23", "dd.MM", Locale.ENGLISH))
.isEmpty();
}

@Test
void test_matchingPattern()
{
assertThat(DateParser.parse("14.01.23", "dd.MM.yy", Locale.ENGLISH))
.isPresent()
.get().isEqualTo(LocalDate.of(2023, 1, 14));
}
}

0 comments on commit 9fc90b8

Please sign in to comment.