From b5caefc098bce98d4abd6cf1281e85209d59be78 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Mon, 20 Feb 2023 23:18:55 +0100 Subject: [PATCH] #732 - add csv import settings to database export and import --- .../budgetmaster/database/DatabaseParser.java | 10 +- .../database/DatabaseParser_v10.java | 47 + .../database/DatabaseService.java | 34 +- .../database/InternalDatabase.java | 10 +- .../importer/CsvImportSettingsImporter.java | 29 + .../converter/CsvImportSettingsConverter.java | 53 + .../v10/BackupCsvImportSettings_v10.java | 158 + .../model/v10/BackupDatabase_v10.java | 217 ++ .../database/model/v9/BackupDatabase_v9.java | 41 +- .../budgetmaster/services/ImportService.java | 8 +- .../csvimport/CsvImportSettings.java | 34 +- .../csvimport/CsvImportSettingsService.java | 23 +- .../unit/database/DatabaseExportTest.java | 15 +- .../unit/database/DatabaseParser_v10Test.java | 302 ++ ...baseParser_v10_convertToInternalTest.java} | 62 +- .../unit/database/ImportServiceTest.java | 26 +- .../resources/DatabaseParser_v10Test.json | 3360 +++++++++++++++++ .../src/test/resources/ImportServiceTest.json | 16 +- 18 files changed, 4374 insertions(+), 71 deletions(-) create mode 100644 BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v10.java create mode 100644 BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/importer/CsvImportSettingsImporter.java create mode 100644 BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/converter/CsvImportSettingsConverter.java create mode 100644 BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupCsvImportSettings_v10.java create mode 100644 BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupDatabase_v10.java create mode 100644 BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10Test.java rename BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/{DatabaseParser_v9_convertToInternalTest.java => DatabaseParser_v10_convertToInternalTest.java} (84%) create mode 100644 BudgetMasterServer/src/test/resources/DatabaseParser_v10Test.json diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java index 93887340e..e5694328c 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java @@ -3,6 +3,7 @@ package de.deadlocker8.budgetmaster.database; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import de.deadlocker8.budgetmaster.database.model.BackupDatabase; +import de.deadlocker8.budgetmaster.database.model.v10.BackupDatabase_v10; import de.deadlocker8.budgetmaster.database.model.v4.BackupDatabase_v4; import de.deadlocker8.budgetmaster.database.model.v5.BackupDatabase_v5; import de.deadlocker8.budgetmaster.database.model.v6.BackupDatabase_v6; @@ -20,7 +21,7 @@ public class DatabaseParser final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); private static final int MINIMUM_VERSION = 4; - public static final int LATEST_VERSION = 9; + public static final int LATEST_VERSION = 10; private final String jsonString; @@ -82,6 +83,13 @@ public class DatabaseParser importedDatabase = parsedDatabase; } + if(version == 10) + { + BackupDatabase_v10 parsedDatabase = new DatabaseParser_v10(jsonString).parseDatabaseFromJSON(); + LOGGER.debug(MessageFormat.format("Parsed database with {0} transactions, {1} categories, {2} accounts, {3} templates {4} charts {5} images {6} icons and {7} transaction name keywords", parsedDatabase.getTransactions().size(), parsedDatabase.getCategories().size(), parsedDatabase.getAccounts().size(), parsedDatabase.getTemplates().size(), parsedDatabase.getCharts().size(), parsedDatabase.getImages().size(), parsedDatabase.getIcons().size(), parsedDatabase.getTransactionNameKeywords().size())); + importedDatabase = parsedDatabase; + } + if(importedDatabase == null) { throw new IllegalArgumentException(Localization.getString("error.database.import.unknown.version")); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v10.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v10.java new file mode 100644 index 000000000..a53e3f6fb --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v10.java @@ -0,0 +1,47 @@ +package de.deadlocker8.budgetmaster.database; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import de.deadlocker8.budgetmaster.database.model.v10.BackupCsvImportSettings_v10; +import de.deadlocker8.budgetmaster.database.model.v10.BackupDatabase_v10; +import de.deadlocker8.budgetmaster.database.model.v5.BackupChart_v5; +import de.deadlocker8.budgetmaster.database.model.v5.BackupImage_v5; +import de.deadlocker8.budgetmaster.database.model.v6.BackupTransaction_v6; +import de.deadlocker8.budgetmaster.database.model.v7.BackupAccount_v7; +import de.deadlocker8.budgetmaster.database.model.v7.BackupCategory_v7; +import de.deadlocker8.budgetmaster.database.model.v8.BackupIcon_v8; +import de.deadlocker8.budgetmaster.database.model.v8.BackupTemplateGroup_v8; +import de.deadlocker8.budgetmaster.database.model.v8.BackupTemplate_v8; +import de.deadlocker8.budgetmaster.database.model.v9.BackupTransactionNameKeyword_v9; + +public class DatabaseParser_v10 +{ + private final String jsonString; + + private BackupDatabase_v10 database; + + public DatabaseParser_v10(String json) + { + this.jsonString = json; + this.database = new BackupDatabase_v10(); + } + + public BackupDatabase_v10 parseDatabaseFromJSON() throws IllegalArgumentException + { + database = new BackupDatabase_v10(); + + final JsonObject root = JsonParser.parseString(jsonString).getAsJsonObject(); + database.setImages(BackupItemParser.parseItems(root.get("images").getAsJsonArray(), BackupImage_v5.class)); + database.setIcons(BackupItemParser.parseItems(root.get("icons").getAsJsonArray(), BackupIcon_v8.class)); + database.setAccounts(BackupItemParser.parseItems(root.get("accounts").getAsJsonArray(), BackupAccount_v7.class)); + database.setCategories(BackupItemParser.parseItems(root.get("categories").getAsJsonArray(), BackupCategory_v7.class)); + database.setTransactions(BackupItemParser.parseItems(root.get("transactions").getAsJsonArray(), BackupTransaction_v6.class)); + database.setTemplateGroups(BackupItemParser.parseItems(root.get("templateGroups").getAsJsonArray(), BackupTemplateGroup_v8.class)); + database.setTemplates(BackupItemParser.parseItems(root.get("templates").getAsJsonArray(), BackupTemplate_v8.class)); + database.setCharts(BackupItemParser.parseItems(root.get("charts").getAsJsonArray(), BackupChart_v5.class)); + database.setTransactionNameKeywords(BackupItemParser.parseItems(root.get("transactionNameKeywords").getAsJsonArray(), BackupTransactionNameKeyword_v9.class)); + database.setCsvImportSettings(BackupItemParser.parseItems(root.get("csvImportSettings").getAsJsonArray(), BackupCsvImportSettings_v10.class)); + + return database; + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseService.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseService.java index 64403d98b..5bc406b1a 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseService.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseService.java @@ -10,7 +10,7 @@ import de.deadlocker8.budgetmaster.charts.Chart; import de.deadlocker8.budgetmaster.charts.ChartService; import de.deadlocker8.budgetmaster.charts.ChartType; import de.deadlocker8.budgetmaster.database.model.BackupDatabase; -import de.deadlocker8.budgetmaster.database.model.v9.BackupDatabase_v9; +import de.deadlocker8.budgetmaster.database.model.v10.BackupDatabase_v10; import de.deadlocker8.budgetmaster.hints.HintService; import de.deadlocker8.budgetmaster.icon.Icon; import de.deadlocker8.budgetmaster.icon.IconService; @@ -26,6 +26,8 @@ import de.deadlocker8.budgetmaster.templates.Template; import de.deadlocker8.budgetmaster.templates.TemplateService; import de.deadlocker8.budgetmaster.transactions.Transaction; import de.deadlocker8.budgetmaster.transactions.TransactionService; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettingsService; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordService; import de.deadlocker8.budgetmaster.utils.DateHelper; @@ -69,11 +71,12 @@ public class DatabaseService private final IconService iconService; private final HintService hintService; private final TransactionNameKeywordService transactionNameKeywordService; + private final CsvImportSettingsService csvImportSettingsService; private final List<Resettable> services; @Autowired - public DatabaseService(AccountService accountService, CategoryService categoryService, TransactionService transactionService, TagService tagService, TemplateService templateService, TemplateGroupService templateGroupService, ChartService chartService, SettingsService settingsService, ImageService imageService, IconService iconService, HintService hintService, TransactionNameKeywordService transactionNameKeywordService) + public DatabaseService(AccountService accountService, CategoryService categoryService, TransactionService transactionService, TagService tagService, TemplateService templateService, TemplateGroupService templateGroupService, ChartService chartService, SettingsService settingsService, ImageService imageService, IconService iconService, HintService hintService, TransactionNameKeywordService transactionNameKeywordService, CsvImportSettingsService csvImportSettingsService) { this.accountService = accountService; this.categoryService = categoryService; @@ -87,6 +90,7 @@ public class DatabaseService this.iconService = iconService; this.hintService = hintService; this.transactionNameKeywordService = transactionNameKeywordService; + this.csvImportSettingsService = csvImportSettingsService; this.services = List.of(transactionService, templateService, templateGroupService, categoryService, accountService, tagService, chartService, iconService, imageService, tagService, hintService, transactionNameKeywordService); } @@ -213,22 +217,24 @@ public class DatabaseService public BackupDatabase getDatabaseForJsonSerialization() { - List<Category> categories = categoryService.getAllEntitiesAsc(); - List<Account> accounts = accountService.getRepository().findAll(); - List<Transaction> transactions = transactionService.getRepository().findAll(); - List<Transaction> filteredTransactions = filterRepeatingTransactions(transactions); - List<TemplateGroup> templateGroups = templateGroupService.getRepository().findAll(); - List<Template> templates = templateService.getRepository().findAll(); - List<Chart> charts = chartService.getRepository().findAllByType(ChartType.CUSTOM); - List<Image> images = imageService.getRepository().findAll(); - List<Icon> icons = iconService.getRepository().findAll(); - List<TransactionNameKeyword> transactionNameKeywords = transactionNameKeywordService.getRepository().findAll(); + final List<Category> categories = categoryService.getAllEntitiesAsc(); + final List<Account> accounts = accountService.getRepository().findAll(); + final List<Transaction> transactions = transactionService.getRepository().findAll(); + final List<Transaction> filteredTransactions = filterRepeatingTransactions(transactions); + final List<TemplateGroup> templateGroups = templateGroupService.getRepository().findAll(); + final List<Template> templates = templateService.getRepository().findAll(); + final List<Chart> charts = chartService.getRepository().findAllByType(ChartType.CUSTOM); + final List<Image> images = imageService.getRepository().findAll(); + final List<Icon> icons = iconService.getRepository().findAll(); + final List<TransactionNameKeyword> transactionNameKeywords = transactionNameKeywordService.getRepository().findAll(); + final CsvImportSettings csvImportSettings = csvImportSettingsService.getCsvImportSettings(); + LOGGER.debug(MessageFormat.format("Reduced {0} transactions to {1}", transactions.size(), filteredTransactions.size())); - InternalDatabase database = new InternalDatabase(categories, accounts, filteredTransactions, templateGroups, templates, charts, images, icons, transactionNameKeywords); + InternalDatabase database = new InternalDatabase(categories, accounts, filteredTransactions, templateGroups, templates, charts, images, icons, transactionNameKeywords, List.of(csvImportSettings)); LOGGER.debug(MessageFormat.format("Created database for JSON with {0} transactions, {1} categories, {2} accounts, {3} templates groups, {4} templates, {5} charts {6} images {7} icons and {8} transaction name keywords", database.getTransactions().size(), database.getCategories().size(), database.getAccounts().size(), database.getTemplateGroups().size(), database.getTemplates().size(), database.getCharts().size(), database.getImages().size(), database.getIcons().size(), database.getTransactionNameKeywords().size())); - BackupDatabase_v9 databaseInExternalForm = BackupDatabase_v9.createFromInternalEntities(database); + BackupDatabase_v10 databaseInExternalForm = BackupDatabase_v10.createFromInternalEntities(database); LOGGER.debug("Converted database to external form"); return databaseInExternalForm; } diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/InternalDatabase.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/InternalDatabase.java index 4fe6fb0d6..0cdea82ce 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/InternalDatabase.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/InternalDatabase.java @@ -10,6 +10,7 @@ import de.deadlocker8.budgetmaster.services.EntityType; import de.deadlocker8.budgetmaster.templategroup.TemplateGroup; import de.deadlocker8.budgetmaster.templates.Template; import de.deadlocker8.budgetmaster.transactions.Transaction; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; import java.util.LinkedHashMap; @@ -27,12 +28,13 @@ public class InternalDatabase private List<Image> images; private List<Icon> icons; private List<TransactionNameKeyword> transactionNameKeywords; + private List<CsvImportSettings> csvImportSettings; public InternalDatabase() { } - public InternalDatabase(List<Category> categories, List<Account> accounts, List<Transaction> transactions, List<TemplateGroup> templateGroups, List<Template> templates, List<Chart> charts, List<Image> images, List<Icon> icons, List<TransactionNameKeyword> transactionNameKeywords) + public InternalDatabase(List<Category> categories, List<Account> accounts, List<Transaction> transactions, List<TemplateGroup> templateGroups, List<Template> templates, List<Chart> charts, List<Image> images, List<Icon> icons, List<TransactionNameKeyword> transactionNameKeywords, List<CsvImportSettings> csvImportSettings) { this.categories = categories; this.accounts = accounts; @@ -43,6 +45,7 @@ public class InternalDatabase this.images = images; this.icons = icons; this.transactionNameKeywords = transactionNameKeywords; + this.csvImportSettings = csvImportSettings; } public List<Category> getCategories() @@ -90,6 +93,11 @@ public class InternalDatabase return transactionNameKeywords; } + public List<CsvImportSettings> getCsvImportSettings() + { + return csvImportSettings; + } + public Map<EntityType, Integer> getNumberOfEntitiesByType() { final Map<EntityType, Integer> numberOfEntitiesByType = new LinkedHashMap<>(); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/importer/CsvImportSettingsImporter.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/importer/CsvImportSettingsImporter.java new file mode 100644 index 000000000..08276a6a4 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/importer/CsvImportSettingsImporter.java @@ -0,0 +1,29 @@ +package de.deadlocker8.budgetmaster.database.importer; + +import de.deadlocker8.budgetmaster.services.EntityType; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettingsService; + +public class CsvImportSettingsImporter extends ItemImporter<CsvImportSettings> +{ + private final CsvImportSettingsService csvImportSettingsService; + + public CsvImportSettingsImporter(CsvImportSettingsService csvImportSettingsService) + { + super(csvImportSettingsService.getRepository(), EntityType.TRANSACTION_IMPORT); + this.csvImportSettingsService = csvImportSettingsService; + } + + @Override + protected int importSingleItem(CsvImportSettings csvImportSettings) throws ImportException + { + csvImportSettingsService.updateSettings(csvImportSettings); + return 1; + } + + @Override + protected String getNameForItem(CsvImportSettings item) + { + return String.valueOf(item.toString()); + } +} diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/converter/CsvImportSettingsConverter.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/converter/CsvImportSettingsConverter.java new file mode 100644 index 000000000..fede3a1ce --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/converter/CsvImportSettingsConverter.java @@ -0,0 +1,53 @@ +package de.deadlocker8.budgetmaster.database.model.converter; + +import de.deadlocker8.budgetmaster.database.model.Converter; +import de.deadlocker8.budgetmaster.database.model.v10.BackupCsvImportSettings_v10; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; + +public class CsvImportSettingsConverter implements Converter<CsvImportSettings, BackupCsvImportSettings_v10> +{ + public CsvImportSettings convertToInternalForm(BackupCsvImportSettings_v10 backupCsvImportSettings) + { + if(backupCsvImportSettings == null) + { + return null; + } + + final CsvImportSettings settings = new CsvImportSettings(); + settings.setSeparator(backupCsvImportSettings.getSeparator()); + settings.setEncoding(backupCsvImportSettings.getEncoding()); + settings.setNumberOfLinesToSkip(backupCsvImportSettings.getNumberOfLinesToSkip()); + + settings.setColumnDate(backupCsvImportSettings.getColumnDate()); + settings.setDatePattern(backupCsvImportSettings.getDatePattern()); + settings.setColumnName(backupCsvImportSettings.getColumnName()); + settings.setColumnAmount(backupCsvImportSettings.getColumnAmount()); + settings.setDecimalSeparator(backupCsvImportSettings.getDecimalSeparator()); + settings.setGroupingSeparator(backupCsvImportSettings.getGroupingSeparator()); + settings.setColumnDescription(backupCsvImportSettings.getColumnDescription()); + return settings; + } + + @Override + public BackupCsvImportSettings_v10 convertToExternalForm(CsvImportSettings internalItem) + { + if(internalItem == null) + { + return null; + } + + final BackupCsvImportSettings_v10 settings = new BackupCsvImportSettings_v10(); + settings.setSeparator(internalItem.getSeparator()); + settings.setEncoding(internalItem.getEncoding()); + settings.setNumberOfLinesToSkip(internalItem.getNumberOfLinesToSkip()); + + settings.setColumnDate(internalItem.getColumnDate()); + settings.setDatePattern(internalItem.getDatePattern()); + settings.setColumnName(internalItem.getColumnName()); + settings.setColumnAmount(internalItem.getColumnAmount()); + settings.setDecimalSeparator(internalItem.getDecimalSeparator()); + settings.setGroupingSeparator(internalItem.getGroupingSeparator()); + settings.setColumnDescription(internalItem.getColumnDescription()); + return settings; + } +} diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupCsvImportSettings_v10.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupCsvImportSettings_v10.java new file mode 100644 index 000000000..2dec4554f --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupCsvImportSettings_v10.java @@ -0,0 +1,158 @@ +package de.deadlocker8.budgetmaster.database.model.v10; + +import de.deadlocker8.budgetmaster.database.model.BackupInfo; + +import java.util.Objects; + +public class BackupCsvImportSettings_v10 implements BackupInfo +{ + private String separator; + private String encoding; + private int numberOfLinesToSkip; + + // column settings + private Integer columnDate; + private String datePattern; + private Integer columnName; + private Integer columnAmount; + private String decimalSeparator; + private String groupingSeparator; + private Integer columnDescription; + + public BackupCsvImportSettings_v10() + { + // for GSON + } + + public String getSeparator() + { + return separator; + } + + public void setSeparator(String separator) + { + this.separator = separator; + } + + public String getEncoding() + { + return encoding; + } + + public void setEncoding(String encoding) + { + this.encoding = encoding; + } + + public int getNumberOfLinesToSkip() + { + return numberOfLinesToSkip; + } + + public void setNumberOfLinesToSkip(int numberOfLinesToSkip) + { + this.numberOfLinesToSkip = numberOfLinesToSkip; + } + + public Integer getColumnDate() + { + return columnDate; + } + + public void setColumnDate(Integer columnDate) + { + this.columnDate = columnDate; + } + + public String getDatePattern() + { + return datePattern; + } + + public void setDatePattern(String datePattern) + { + this.datePattern = datePattern; + } + + public Integer getColumnName() + { + return columnName; + } + + public void setColumnName(Integer columnName) + { + this.columnName = columnName; + } + + public Integer getColumnAmount() + { + return columnAmount; + } + + public void setColumnAmount(Integer columnAmount) + { + this.columnAmount = columnAmount; + } + + public String getDecimalSeparator() + { + return decimalSeparator; + } + + public void setDecimalSeparator(String decimalSeparator) + { + this.decimalSeparator = decimalSeparator; + } + + public String getGroupingSeparator() + { + return groupingSeparator; + } + + public void setGroupingSeparator(String groupingSeparator) + { + this.groupingSeparator = groupingSeparator; + } + + public Integer getColumnDescription() + { + return columnDescription; + } + + public void setColumnDescription(Integer columnDescription) + { + this.columnDescription = columnDescription; + } + + @Override + public boolean equals(Object o) + { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + BackupCsvImportSettings_v10 that = (BackupCsvImportSettings_v10) o; + return numberOfLinesToSkip == that.numberOfLinesToSkip && Objects.equals(separator, that.separator) && Objects.equals(encoding, that.encoding) && Objects.equals(columnDate, that.columnDate) && Objects.equals(datePattern, that.datePattern) && Objects.equals(columnName, that.columnName) && Objects.equals(columnAmount, that.columnAmount) && Objects.equals(decimalSeparator, that.decimalSeparator) && Objects.equals(groupingSeparator, that.groupingSeparator) && Objects.equals(columnDescription, that.columnDescription); + } + + @Override + public int hashCode() + { + return Objects.hash(separator, encoding, numberOfLinesToSkip, columnDate, datePattern, columnName, columnAmount, decimalSeparator, groupingSeparator, columnDescription); + } + + @Override + public String toString() + { + return "BackupCsvImportSettings_v10{" + + "separator='" + separator + '\'' + + ", encoding='" + encoding + '\'' + + ", numberOfLinesToSkip=" + numberOfLinesToSkip + + ", columnDate=" + columnDate + + ", datePattern='" + datePattern + '\'' + + ", columnName=" + columnName + + ", columnAmount=" + columnAmount + + ", decimalSeparator='" + decimalSeparator + '\'' + + ", groupingSeparator='" + groupingSeparator + '\'' + + ", columnDescription=" + columnDescription + + '}'; + } +} diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupDatabase_v10.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupDatabase_v10.java new file mode 100644 index 000000000..c1997ea45 --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v10/BackupDatabase_v10.java @@ -0,0 +1,217 @@ +package de.deadlocker8.budgetmaster.database.model.v10; + +import de.deadlocker8.budgetmaster.accounts.Account; +import de.deadlocker8.budgetmaster.categories.Category; +import de.deadlocker8.budgetmaster.charts.Chart; +import de.deadlocker8.budgetmaster.database.InternalDatabase; +import de.deadlocker8.budgetmaster.database.JSONIdentifier; +import de.deadlocker8.budgetmaster.database.model.BackupDatabase; +import de.deadlocker8.budgetmaster.database.model.converter.*; +import de.deadlocker8.budgetmaster.database.model.v5.BackupChart_v5; +import de.deadlocker8.budgetmaster.database.model.v5.BackupImage_v5; +import de.deadlocker8.budgetmaster.database.model.v6.BackupTransaction_v6; +import de.deadlocker8.budgetmaster.database.model.v7.BackupAccount_v7; +import de.deadlocker8.budgetmaster.database.model.v7.BackupCategory_v7; +import de.deadlocker8.budgetmaster.database.model.v8.BackupIcon_v8; +import de.deadlocker8.budgetmaster.database.model.v8.BackupTemplateGroup_v8; +import de.deadlocker8.budgetmaster.database.model.v8.BackupTemplate_v8; +import de.deadlocker8.budgetmaster.database.model.v9.BackupTransactionNameKeyword_v9; +import de.deadlocker8.budgetmaster.icon.Icon; +import de.deadlocker8.budgetmaster.images.Image; +import de.deadlocker8.budgetmaster.templategroup.TemplateGroup; +import de.deadlocker8.budgetmaster.templates.Template; +import de.deadlocker8.budgetmaster.transactions.Transaction; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; +import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; + +import java.util.List; + +public class BackupDatabase_v10 implements BackupDatabase +{ + @SuppressWarnings("unused") + private final String TYPE = JSONIdentifier.BUDGETMASTER_DATABASE.toString(); + + @SuppressWarnings({"FieldCanBeLocal", "squid:S1170"}) + // field can not be static, since static field won't be exported to JSON by GSON + private final int VERSION = 10; + + @SuppressWarnings({"unused", "squid:S2065", "squid:S1170"}) + // field can not be static, since static field won't be exported to JSON by GSON + private final transient String INTRODUCED_IN_VERSION = "v2.14.0"; + + private List<BackupCategory_v7> categories; + private List<BackupAccount_v7> accounts; + private List<BackupTransaction_v6> transactions; + private List<BackupTemplateGroup_v8> templateGroups; + private List<BackupTemplate_v8> templates; + private List<BackupChart_v5> charts; + private List<BackupImage_v5> images; + private List<BackupIcon_v8> icons; + private List<BackupTransactionNameKeyword_v9> transactionNameKeywords; + private List<BackupCsvImportSettings_v10> csvImportSettings; + + public BackupDatabase_v10() + { + // for GSON + } + + public BackupDatabase_v10(List<BackupCategory_v7> categories, List<BackupAccount_v7> accounts, List<BackupTransaction_v6> transactions, List<BackupTemplateGroup_v8> templateGroups, List<BackupTemplate_v8> templates, List<BackupChart_v5> charts, List<BackupImage_v5> images, List<BackupIcon_v8> icons, List<BackupTransactionNameKeyword_v9> transactionNameKeywords, List<BackupCsvImportSettings_v10> csvImportSettings) + { + this.categories = categories; + this.accounts = accounts; + this.transactions = transactions; + this.templateGroups = templateGroups; + this.templates = templates; + this.charts = charts; + this.images = images; + this.icons = icons; + this.transactionNameKeywords = transactionNameKeywords; + this.csvImportSettings = csvImportSettings; + } + + public List<BackupCategory_v7> getCategories() + { + return categories; + } + + public void setCategories(List<BackupCategory_v7> categories) + { + this.categories = categories; + } + + public List<BackupAccount_v7> getAccounts() + { + return accounts; + } + + public void setAccounts(List<BackupAccount_v7> accounts) + { + this.accounts = accounts; + } + + public List<BackupTransaction_v6> getTransactions() + { + return transactions; + } + + public void setTransactions(List<BackupTransaction_v6> transactions) + { + this.transactions = transactions; + } + + public List<BackupTemplate_v8> getTemplates() + { + return templates; + } + + public void setTemplates(List<BackupTemplate_v8> templates) + { + this.templates = templates; + } + + public List<BackupChart_v5> getCharts() + { + return charts; + } + + public void setCharts(List<BackupChart_v5> charts) + { + this.charts = charts; + } + + public List<BackupImage_v5> getImages() + { + return images; + } + + public void setImages(List<BackupImage_v5> images) + { + this.images = images; + } + + public List<BackupIcon_v8> getIcons() + { + return icons; + } + + public void setIcons(List<BackupIcon_v8> icons) + { + this.icons = icons; + } + + public List<BackupTemplateGroup_v8> getTemplateGroups() + { + return templateGroups; + } + + public void setTemplateGroups(List<BackupTemplateGroup_v8> templateGroups) + { + this.templateGroups = templateGroups; + } + + public List<BackupTransactionNameKeyword_v9> getTransactionNameKeywords() + { + return transactionNameKeywords; + } + + public void setTransactionNameKeywords(List<BackupTransactionNameKeyword_v9> transactionNameKeywords) + { + this.transactionNameKeywords = transactionNameKeywords; + } + + public List<BackupCsvImportSettings_v10> getCsvImportSettings() + { + return csvImportSettings; + } + + public void setCsvImportSettings(List<BackupCsvImportSettings_v10> csvImportSettings) + { + this.csvImportSettings = csvImportSettings; + } + + public InternalDatabase convertToInternal() + { + final List<Image> convertedImages = convertItemsToInternal(this.images, new ImageConverter()); + final List<Icon> convertedIcons = convertItemsToInternal(this.icons, new IconConverter(convertedImages)); + final List<Category> convertedCategories = convertItemsToInternal(categories, new CategoryConverter(convertedIcons)); + final List<Account> convertedAccounts = convertItemsToInternal(accounts, new AccountConverter(convertedIcons)); + final List<Transaction> convertedTransactions = convertItemsToInternal(this.transactions, new TransactionConverter(convertedCategories, convertedAccounts)); + final List<TemplateGroup> convertedTemplateGroups = convertItemsToInternal(this.templateGroups, new TemplateGroupConverter()); + final List<Template> convertedTemplates = convertItemsToInternal(this.templates, new TemplateConverter(convertedIcons, convertedCategories, convertedAccounts, convertedTemplateGroups)); + final List<Chart> convertedCharts = convertItemsToInternal(this.charts, new ChartConverter()); + final List<TransactionNameKeyword> convertedKeywords = convertItemsToInternal(this.transactionNameKeywords, new TransactionNameKeywordConverter()); + final List<CsvImportSettings> convertedCsvImportSettings = convertItemsToInternal(this.csvImportSettings, new CsvImportSettingsConverter()); + + return new InternalDatabase(convertedCategories, convertedAccounts, convertedTransactions, convertedTemplateGroups, convertedTemplates, convertedCharts, convertedImages, convertedIcons, convertedKeywords, convertedCsvImportSettings); + } + + @Override + public int getVersion() + { + return VERSION; + } + + @Override + public BackupDatabase upgrade() + { + throw new UnsupportedOperationException(); + } + + public static BackupDatabase_v10 createFromInternalEntities(InternalDatabase database) + { + final BackupDatabase_v10 externalDatabase = new BackupDatabase_v10(); + + externalDatabase.setIcons(externalDatabase.convertItemsToExternal(database.getIcons(), new IconConverter(null))); + externalDatabase.setCategories(externalDatabase.convertItemsToExternal(database.getCategories(), new CategoryConverter(null))); + externalDatabase.setAccounts(externalDatabase.convertItemsToExternal(database.getAccounts(), new AccountConverter(null))); + externalDatabase.setTransactions(externalDatabase.convertItemsToExternal(database.getTransactions(), new TransactionConverter(null, null))); + externalDatabase.setTemplateGroups(externalDatabase.convertItemsToExternal(database.getTemplateGroups(), new TemplateGroupConverter())); + externalDatabase.setTemplates(externalDatabase.convertItemsToExternal(database.getTemplates(), new TemplateConverter(null, null, null, null))); + externalDatabase.setCharts(externalDatabase.convertItemsToExternal(database.getCharts(), new ChartConverter())); + externalDatabase.setImages(externalDatabase.convertItemsToExternal(database.getImages(), new ImageConverter())); + externalDatabase.setTransactionNameKeywords(externalDatabase.convertItemsToExternal(database.getTransactionNameKeywords(), new TransactionNameKeywordConverter())); + externalDatabase.setCsvImportSettings(externalDatabase.convertItemsToExternal(database.getCsvImportSettings(), new CsvImportSettingsConverter())); + + return externalDatabase; + } +} diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v9/BackupDatabase_v9.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v9/BackupDatabase_v9.java index f2c75ba39..a68fd6a1f 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v9/BackupDatabase_v9.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/database/model/v9/BackupDatabase_v9.java @@ -7,6 +7,7 @@ import de.deadlocker8.budgetmaster.database.InternalDatabase; import de.deadlocker8.budgetmaster.database.JSONIdentifier; import de.deadlocker8.budgetmaster.database.model.BackupDatabase; import de.deadlocker8.budgetmaster.database.model.converter.*; +import de.deadlocker8.budgetmaster.database.model.v10.BackupDatabase_v10; import de.deadlocker8.budgetmaster.database.model.v5.BackupChart_v5; import de.deadlocker8.budgetmaster.database.model.v5.BackupImage_v5; import de.deadlocker8.budgetmaster.database.model.v6.BackupTransaction_v6; @@ -157,17 +158,7 @@ public class BackupDatabase_v9 implements BackupDatabase public InternalDatabase convertToInternal() { - final List<Image> convertedImages = convertItemsToInternal(this.images, new ImageConverter()); - final List<Icon> convertedIcons = convertItemsToInternal(this.icons, new IconConverter(convertedImages)); - final List<Category> convertedCategories = convertItemsToInternal(categories, new CategoryConverter(convertedIcons)); - final List<Account> convertedAccounts = convertItemsToInternal(accounts, new AccountConverter(convertedIcons)); - final List<Transaction> convertedTransactions = convertItemsToInternal(this.transactions, new TransactionConverter(convertedCategories, convertedAccounts)); - final List<TemplateGroup> convertedTemplateGroups = convertItemsToInternal(this.templateGroups, new TemplateGroupConverter()); - final List<Template> convertedTemplates = convertItemsToInternal(this.templates, new TemplateConverter(convertedIcons, convertedCategories, convertedAccounts, convertedTemplateGroups)); - final List<Chart> convertedCharts = convertItemsToInternal(this.charts, new ChartConverter()); - final List<TransactionNameKeyword> convertedKeywords = convertItemsToInternal(this.transactionNameKeywords, new TransactionNameKeywordConverter()); - - return new InternalDatabase(convertedCategories, convertedAccounts, convertedTransactions, convertedTemplateGroups, convertedTemplates, convertedCharts, convertedImages, convertedIcons, convertedKeywords); + throw new UnsupportedOperationException(); } @Override @@ -179,23 +170,19 @@ public class BackupDatabase_v9 implements BackupDatabase @Override public BackupDatabase upgrade() { - throw new UnsupportedOperationException(); - } - - public static BackupDatabase_v9 createFromInternalEntities(InternalDatabase database) - { - final BackupDatabase_v9 externalDatabase = new BackupDatabase_v9(); + final BackupDatabase_v10 upgradedDatabase = new BackupDatabase_v10(); - externalDatabase.setIcons(externalDatabase.convertItemsToExternal(database.getIcons(), new IconConverter(null))); - externalDatabase.setCategories(externalDatabase.convertItemsToExternal(database.getCategories(), new CategoryConverter(null))); - externalDatabase.setAccounts(externalDatabase.convertItemsToExternal(database.getAccounts(), new AccountConverter(null))); - externalDatabase.setTransactions(externalDatabase.convertItemsToExternal(database.getTransactions(), new TransactionConverter(null, null))); - externalDatabase.setTemplateGroups(externalDatabase.convertItemsToExternal(database.getTemplateGroups(), new TemplateGroupConverter())); - externalDatabase.setTemplates(externalDatabase.convertItemsToExternal(database.getTemplates(), new TemplateConverter(null, null, null, null))); - externalDatabase.setCharts(externalDatabase.convertItemsToExternal(database.getCharts(), new ChartConverter())); - externalDatabase.setImages(externalDatabase.convertItemsToExternal(database.getImages(), new ImageConverter())); - externalDatabase.setTransactionNameKeywords(externalDatabase.convertItemsToExternal(database.getTransactionNameKeywords(), new TransactionNameKeywordConverter())); + upgradedDatabase.setCategories(categories); + upgradedDatabase.setAccounts(accounts); + upgradedDatabase.setTransactions(transactions); + upgradedDatabase.setTemplateGroups(templateGroups); + upgradedDatabase.setTemplates(templates); + upgradedDatabase.setCharts(charts); + upgradedDatabase.setImages(images); + upgradedDatabase.setIcons(icons); + upgradedDatabase.setTransactionNameKeywords(List.of()); + upgradedDatabase.setCsvImportSettings(List.of()); - return externalDatabase; + return upgradedDatabase; } } diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java index a0348aa08..831978aa0 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java @@ -14,6 +14,7 @@ import de.deadlocker8.budgetmaster.templategroup.TemplateGroupRepository; import de.deadlocker8.budgetmaster.templategroup.TemplateGroupType; import de.deadlocker8.budgetmaster.templates.TemplateRepository; import de.deadlocker8.budgetmaster.transactions.TransactionRepository; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettingsService; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordRepository; import de.deadlocker8.budgetmaster.utils.DateHelper; import org.slf4j.Logger; @@ -40,13 +41,13 @@ public class ImportService private final AccountRepository accountRepository; private final IconRepository iconRepository; private final TransactionNameKeywordRepository transactionNameKeywordRepository; - + private final CsvImportSettingsService csvImportSettingsService; private InternalDatabase database; @Autowired public ImportService(CategoryRepository categoryRepository, TransactionRepository transactionRepository, TemplateGroupRepository templateGroupRepository, TemplateRepository templateRepository, - TagRepository tagRepository, ChartService chartService, ImageRepository imageRepository, RepeatingTransactionUpdater repeatingTransactionUpdater, AccountRepository accountRepository, IconRepository iconRepository, TransactionNameKeywordRepository transactionNameKeywordRepository) + TagRepository tagRepository, ChartService chartService, ImageRepository imageRepository, RepeatingTransactionUpdater repeatingTransactionUpdater, AccountRepository accountRepository, IconRepository iconRepository, TransactionNameKeywordRepository transactionNameKeywordRepository, CsvImportSettingsService csvImportSettingsService) { this.categoryRepository = categoryRepository; this.transactionRepository = transactionRepository; @@ -59,6 +60,7 @@ public class ImportService this.accountRepository = accountRepository; this.iconRepository = iconRepository; this.transactionNameKeywordRepository = transactionNameKeywordRepository; + this.csvImportSettingsService = csvImportSettingsService; } public List<ImportResultItem> importDatabase(InternalDatabase database, Boolean importTemplateGroups, Boolean importTemplates, Boolean importCharts) @@ -106,6 +108,8 @@ public class ImportService new TransactionNameKeywordImporter(transactionNameKeywordRepository).importItems(database.getTransactionNameKeywords()); + new CsvImportSettingsImporter(csvImportSettingsService).importItems(database.getCsvImportSettings()); + LOGGER.debug("Updating repeating transactions..."); repeatingTransactionUpdater.updateRepeatingTransactions(DateHelper.getCurrentDate()); diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettings.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettings.java index 277a241cc..38336fa8b 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettings.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettings.java @@ -1,14 +1,17 @@ package de.deadlocker8.budgetmaster.transactions.csvimport; +import de.deadlocker8.budgetmaster.utils.ProvidesID; + import javax.persistence.Entity; import javax.persistence.Id; +import java.util.Objects; @Entity -public class CsvImportSettings +public class CsvImportSettings implements ProvidesID { @Id - private int ID = 1; + private Integer ID = 1; private String separator; private String encoding; private int numberOfLinesToSkip; @@ -45,6 +48,18 @@ public class CsvImportSettings return defaultSettings; } + @Override + public Integer getID() + { + return null; + } + + @Override + public void setID(Integer ID) + { + this.ID = ID; + } + public String getSeparator() { return separator; @@ -145,6 +160,21 @@ public class CsvImportSettings this.columnDescription = columnDescription; } + @Override + public boolean equals(Object o) + { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + CsvImportSettings settings = (CsvImportSettings) o; + return ID == settings.ID && numberOfLinesToSkip == settings.numberOfLinesToSkip && Objects.equals(separator, settings.separator) && Objects.equals(encoding, settings.encoding) && Objects.equals(columnDate, settings.columnDate) && Objects.equals(datePattern, settings.datePattern) && Objects.equals(columnName, settings.columnName) && Objects.equals(columnAmount, settings.columnAmount) && Objects.equals(decimalSeparator, settings.decimalSeparator) && Objects.equals(groupingSeparator, settings.groupingSeparator) && Objects.equals(columnDescription, settings.columnDescription); + } + + @Override + public int hashCode() + { + return Objects.hash(ID, separator, encoding, numberOfLinesToSkip, columnDate, datePattern, columnName, columnAmount, decimalSeparator, groupingSeparator, columnDescription); + } + @Override public String toString() { diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettingsService.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettingsService.java index dbade9210..f2fcfb2ae 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettingsService.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvimport/CsvImportSettingsService.java @@ -76,7 +76,6 @@ public class CsvImportSettingsService if(hasContent(columnSettings.decimalSeparator())) { settings.setDecimalSeparator(columnSettings.decimalSeparator()); - } if(hasContent(columnSettings.groupingSeparator())) { @@ -86,6 +85,23 @@ public class CsvImportSettingsService settings.setColumnDescription(columnSettings.columnDescription()); } + @Transactional + public void updateSettings(CsvImportSettings newSettings) + { + final CsvImportSettings settings = getCsvImportSettings(); + + settings.setSeparator(newSettings.getSeparator()); + settings.setEncoding(newSettings.getEncoding()); + settings.setNumberOfLinesToSkip(newSettings.getNumberOfLinesToSkip()); + settings.setColumnDate(newSettings.getColumnDate()); + settings.setDatePattern(newSettings.getDatePattern()); + settings.setColumnName(newSettings.getColumnName()); + settings.setColumnAmount(newSettings.getColumnAmount()); + settings.setDecimalSeparator(newSettings.getDecimalSeparator()); + settings.setGroupingSeparator(newSettings.getGroupingSeparator()); + settings.setColumnDescription(newSettings.getColumnDescription()); + } + private boolean hasContent(String value) { if(value == null) @@ -100,4 +116,9 @@ public class CsvImportSettingsService return !value.isBlank(); } + + public CsvImportSettingsRepository getRepository() + { + return csvImportSettingsRepository; + } } \ No newline at end of file diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseExportTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseExportTest.java index b6f3b4f44..c25c689c9 100644 --- a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseExportTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseExportTest.java @@ -38,6 +38,8 @@ import de.deadlocker8.budgetmaster.templates.TemplateService; import de.deadlocker8.budgetmaster.transactions.Transaction; import de.deadlocker8.budgetmaster.transactions.TransactionRepository; import de.deadlocker8.budgetmaster.transactions.TransactionService; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettingsService; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordRepository; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordService; @@ -121,6 +123,9 @@ class DatabaseExportTest @Mock private TransactionNameKeywordService transactionNameKeywordService; + @Mock + private CsvImportSettingsService csvImportSettingsService; + @InjectMocks private DatabaseService databaseService; @@ -173,6 +178,10 @@ class DatabaseExportTest Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of()); Mockito.when(transactionNameKeywordService.getRepository()).thenReturn(transactionNameKeywordRepository); + // csv import settings + final CsvImportSettings csvImportSettings = CsvImportSettings.getDefault(); + Mockito.when(csvImportSettingsService.getCsvImportSettings()).thenReturn(csvImportSettings); + // act Path exportPath = Files.createFile(tempFolder.resolve("exportTest.json")); databaseService.exportDatabase(exportPath); @@ -311,6 +320,10 @@ class DatabaseExportTest Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(keyword1, keyword2)); Mockito.when(transactionNameKeywordService.getRepository()).thenReturn(transactionNameKeywordRepository); + // csv import settings + final CsvImportSettings csvImportSettings = CsvImportSettings.getDefault(); + Mockito.when(csvImportSettingsService.getCsvImportSettings()).thenReturn(csvImportSettings); + // act Path exportPath = Files.createFile(tempFolder.resolve("exportTest.json")); databaseService.exportDatabase(exportPath); @@ -328,6 +341,6 @@ class DatabaseExportTest assertThat(importedDatabase.getCharts()).containsExactly(chart); assertThat(importedDatabase.getImages()).containsExactly(image); assertThat(importedDatabase.getIcons()).containsExactly(iconImage, iconBuiltin); - assertThat(importedDatabase.getTransactionNameKeywords()).containsExactly(new TransactionNameKeyword( "income"), new TransactionNameKeyword( "abc")); + assertThat(importedDatabase.getTransactionNameKeywords()).containsExactly(new TransactionNameKeyword("income"), new TransactionNameKeyword("abc")); } } diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10Test.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10Test.java new file mode 100644 index 000000000..f3d6f514f --- /dev/null +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10Test.java @@ -0,0 +1,302 @@ +package de.deadlocker8.budgetmaster.unit.database; + +import de.deadlocker8.budgetmaster.accounts.AccountState; +import de.deadlocker8.budgetmaster.accounts.AccountType; +import de.deadlocker8.budgetmaster.categories.CategoryType; +import de.deadlocker8.budgetmaster.charts.ChartType; +import de.deadlocker8.budgetmaster.database.DatabaseParser_v10; +import de.deadlocker8.budgetmaster.database.model.v10.BackupCsvImportSettings_v10; +import de.deadlocker8.budgetmaster.database.model.v10.BackupDatabase_v10; +import de.deadlocker8.budgetmaster.database.model.v4.BackupRepeatingEndOption_v4; +import de.deadlocker8.budgetmaster.database.model.v4.BackupRepeatingModifier_v4; +import de.deadlocker8.budgetmaster.database.model.v4.BackupRepeatingOption_v4; +import de.deadlocker8.budgetmaster.database.model.v4.BackupTag_v4; +import de.deadlocker8.budgetmaster.database.model.v5.BackupChart_v5; +import de.deadlocker8.budgetmaster.database.model.v6.BackupTransaction_v6; +import de.deadlocker8.budgetmaster.database.model.v7.BackupAccount_v7; +import de.deadlocker8.budgetmaster.database.model.v7.BackupCategory_v7; +import de.deadlocker8.budgetmaster.database.model.v8.BackupIcon_v8; +import de.deadlocker8.budgetmaster.database.model.v8.BackupTemplateGroup_v8; +import de.deadlocker8.budgetmaster.database.model.v8.BackupTemplate_v8; +import de.deadlocker8.budgetmaster.database.model.v9.BackupTransactionNameKeyword_v9; +import de.deadlocker8.budgetmaster.images.ImageFileExtension; +import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndAfterXTimes; +import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierDays; +import de.deadlocker8.budgetmaster.templategroup.TemplateGroupType; +import de.thecodelabs.utils.util.Localization; +import de.thecodelabs.utils.util.Localization.LocalizationDelegate; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; + + +class DatabaseParser_v10Test +{ + @BeforeEach + public void before() + { + Localization.setDelegate(new LocalizationDelegate() + { + @Override + public Locale getLocale() + { + return Locale.ENGLISH; + } + + @Override + public String getBaseResource() + { + return "languages/base"; + } + }); + Localization.load(); + } + + @Test + void test_Charts() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + final BackupChart_v5 chart = new BackupChart_v5(9, "The best chart", "/* This list will be dynamically filled with all the transactions between\r\n* the start and and date you select on the \"Show Chart\" page\r\n* and filtered according to your specified filter.\r\n* An example entry for this list and tutorial about how to create custom charts ca be found in the BudgetMaster wiki:\r\n* https://github.com/deadlocker8/BudgetMaster/wiki/How-to-create-custom-charts\r\n*/\r\nvar transactionData \u003d [];\r\n\r\n// Prepare your chart settings here (mandatory)\r\nvar plotlyData \u003d [{\r\n x: [],\r\n y: [],\r\n type: \u0027bar\u0027\r\n}];\r\n\r\n// Add your Plotly layout settings here (optional)\r\nvar plotlyLayout \u003d {};\r\n\r\n// Add your Plotly configuration settings here (optional)\r\nvar plotlyConfig \u003d {\r\n showSendToCloud: false,\r\n displaylogo: false,\r\n showLink: false,\r\n responsive: true\r\n};\r\n\r\n// Don\u0027t touch this line\r\nPlotly.newPlot(\"containerID\", plotlyData, plotlyLayout, plotlyConfig);\r\n", ChartType.CUSTOM, 7); + + assertThat(database.getCharts()).hasSize(1) + .contains(chart); + } + + @Test + void test_Categories() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + final BackupCategory_v7 category = new BackupCategory_v7(3, "0815", "#ffcc00", CategoryType.CUSTOM, 2); + + assertThat(database.getCategories()).hasSize(3) + .contains(category); + } + + @Test + void test_Accounts() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + final BackupAccount_v7 account = new BackupAccount_v7(3, "Second Account", AccountState.FULL_ACCESS, AccountType.CUSTOM, 1); + + assertThat(database.getAccounts()).hasSize(3) + .contains(account); + assertThat(database.getAccounts().get(2).getIconReferenceID()) + .isOne(); + } + + @Test + void test_Images() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + assertThat(database.getImages()).hasSize(1); + assertThat(database.getImages().get(0)).hasFieldOrPropertyWithValue("fileExtension", ImageFileExtension.PNG); + assertThat(database.getImages().get(0).getImage()) + .isNotNull() + .hasSizeGreaterThan(1); + } + + @Test + void test_TemplateGroups() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + BackupTemplateGroup_v8 templateGroup = new BackupTemplateGroup_v8(); + templateGroup.setID(1); + templateGroup.setName("My Template Group Deluxe"); + templateGroup.setType(TemplateGroupType.CUSTOM); + + assertThat(database.getTemplateGroups()).hasSize(1) + .contains(templateGroup); + } + + @Test + void test_Templates() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + BackupTemplate_v8 template = new BackupTemplate_v8(); + template.setTemplateName("Template with icon"); + template.setExpenditure(true); + template.setIconReferenceID(1); + template.setTags(List.of()); + + BackupTemplate_v8 templateWithGroup = new BackupTemplate_v8(); + templateWithGroup.setTemplateName("Template with associated group"); + templateWithGroup.setTags(List.of()); + templateWithGroup.setTemplateGroupID(1); + + assertThat(database.getTemplates()).hasSize(5) + .contains(template, templateWithGroup); + assertThat(database.getTemplates().get(3).getIconReferenceID()) + .isOne(); + } + + @Test + void test_Transactions() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + BackupTransaction_v6 normalTransaction_1 = new BackupTransaction_v6(); + normalTransaction_1.setAmount(35000); + normalTransaction_1.setDate("2018-03-13"); + normalTransaction_1.setCategoryID(1); + normalTransaction_1.setName("Income"); + normalTransaction_1.setDescription("Lorem Ipsum"); + normalTransaction_1.setTags(new ArrayList<>()); + normalTransaction_1.setAccountID(2); + normalTransaction_1.setExpenditure(false); + + BackupTransaction_v6 normalTransaction_2 = new BackupTransaction_v6(); + normalTransaction_2.setAmount(-2000); + normalTransaction_2.setDate("2018-06-15"); + normalTransaction_2.setName("Simple"); + normalTransaction_2.setDescription(""); + normalTransaction_2.setAccountID(3); + normalTransaction_2.setCategoryID(3); + normalTransaction_2.setExpenditure(true); + + List<BackupTag_v4> tags = new ArrayList<>(); + BackupTag_v4 tag = new BackupTag_v4("0815"); + tags.add(tag); + normalTransaction_2.setTags(tags); + + BackupTransaction_v6 repeatingTransaction_1 = new BackupTransaction_v6(); + repeatingTransaction_1.setAmount(-12300); + String repeatingTransaction_1Date = "2018-03-13"; + repeatingTransaction_1.setDate(repeatingTransaction_1Date); + repeatingTransaction_1.setCategoryID(1); + repeatingTransaction_1.setName("Test"); + repeatingTransaction_1.setDescription(""); + repeatingTransaction_1.setAccountID(2); + BackupRepeatingOption_v4 repeatingOption_1 = new BackupRepeatingOption_v4(); + repeatingOption_1.setModifier(new BackupRepeatingModifier_v4(10, new RepeatingModifierDays(10).getLocalizationKey())); + repeatingOption_1.setStartDate(repeatingTransaction_1Date); + BackupRepeatingEndOption_v4 endOption = new BackupRepeatingEndOption_v4(); + endOption.setTimes(2); + endOption.setLocalizationKey(new RepeatingEndAfterXTimes(2).getLocalizationKey()); + repeatingOption_1.setEndOption(endOption); + repeatingTransaction_1.setRepeatingOption(repeatingOption_1); + repeatingTransaction_1.setTags(new ArrayList<>()); + repeatingTransaction_1.setExpenditure(true); + + BackupTransaction_v6 transferTransaction = new BackupTransaction_v6(); + transferTransaction.setAmount(-250); + transferTransaction.setDate("2018-06-15"); + transferTransaction.setName("Transfer"); + transferTransaction.setDescription(""); + transferTransaction.setAccountID(3); + transferTransaction.setTransferAccountID(2); + transferTransaction.setCategoryID(3); + transferTransaction.setTags(new ArrayList<>()); + transferTransaction.setExpenditure(true); + + BackupTransaction_v6 repeatingTransferTransaction = new BackupTransaction_v6(); + repeatingTransferTransaction.setAmount(-6000); + String repeatingTransferTransaction_Date = "2018-03-15"; + repeatingTransferTransaction.setDate(repeatingTransferTransaction_Date); + repeatingTransferTransaction.setCategoryID(1); + repeatingTransferTransaction.setName("repeat my transfer"); + repeatingTransferTransaction.setDescription(""); + repeatingTransferTransaction.setAccountID(2); + BackupRepeatingOption_v4 repeatingOption_2 = new BackupRepeatingOption_v4(); + repeatingOption_2.setModifier(new BackupRepeatingModifier_v4(10, new RepeatingModifierDays(10).getLocalizationKey())); + repeatingOption_2.setStartDate(repeatingTransferTransaction_Date); + BackupRepeatingEndOption_v4 endOption_2 = new BackupRepeatingEndOption_v4(); + endOption_2.setTimes(2); + endOption_2.setLocalizationKey(new RepeatingEndAfterXTimes(2).getLocalizationKey()); + repeatingOption_2.setEndOption(endOption_2); + repeatingTransferTransaction.setRepeatingOption(repeatingOption_2); + repeatingTransferTransaction.setTags(new ArrayList<>()); + repeatingTransferTransaction.setExpenditure(true); + repeatingTransferTransaction.setTransferAccountID(2); + + assertThat(database.getTransactions()).hasSize(5) + .contains(normalTransaction_1, + normalTransaction_2, + repeatingTransaction_1, + transferTransaction, + repeatingTransferTransaction); + } + + @Test + void test_Icons() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + final BackupIcon_v8 expectedIconWithImage = new BackupIcon_v8(1, 1, null, null); + final BackupIcon_v8 expectedIBuiltinIcon = new BackupIcon_v8(2, null, "fas fa-icons", "#FF0000"); + + assertThat(database.getIcons()) + .hasSize(2) + .containsExactlyInAnyOrder(expectedIconWithImage, expectedIBuiltinIcon); + } + + @Test + void test_TransactionNameKeywords() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + final BackupTransactionNameKeyword_v9 expectedKeyword1 = new BackupTransactionNameKeyword_v9("income"); + final BackupTransactionNameKeyword_v9 expectedKeyword2 = new BackupTransactionNameKeyword_v9("xyz"); + + assertThat(database.getTransactionNameKeywords()) + .hasSize(2) + .containsExactlyInAnyOrder(expectedKeyword1, expectedKeyword2); + } + + @Test + void test_CsvImportSettings() throws URISyntaxException, IOException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 parser = new DatabaseParser_v10(json); + BackupDatabase_v10 database = parser.parseDatabaseFromJSON(); + + final BackupCsvImportSettings_v10 expectedSettings = new BackupCsvImportSettings_v10(); + expectedSettings.setSeparator(";"); + expectedSettings.setEncoding("UTF-8"); + expectedSettings.setNumberOfLinesToSkip(1); + + expectedSettings.setColumnDate(1); + expectedSettings.setDatePattern("dd.MM.yyyy"); + expectedSettings.setColumnName(2); + expectedSettings.setColumnAmount(3); + expectedSettings.setDecimalSeparator("."); + expectedSettings.setGroupingSeparator(","); + expectedSettings.setColumnDescription(2); + + assertThat(database.getCsvImportSettings()) + .hasSize(1) + .containsExactly(expectedSettings); + } +} \ No newline at end of file diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v9_convertToInternalTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10_convertToInternalTest.java similarity index 84% rename from BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v9_convertToInternalTest.java rename to BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10_convertToInternalTest.java index 739e398bc..1b723f189 100644 --- a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v9_convertToInternalTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v10_convertToInternalTest.java @@ -8,7 +8,7 @@ import de.deadlocker8.budgetmaster.charts.Chart; import de.deadlocker8.budgetmaster.charts.ChartDisplayType; import de.deadlocker8.budgetmaster.charts.ChartGroupType; import de.deadlocker8.budgetmaster.charts.ChartType; -import de.deadlocker8.budgetmaster.database.DatabaseParser_v9; +import de.deadlocker8.budgetmaster.database.DatabaseParser_v10; import de.deadlocker8.budgetmaster.database.InternalDatabase; import de.deadlocker8.budgetmaster.icon.Icon; import de.deadlocker8.budgetmaster.images.Image; @@ -19,6 +19,7 @@ import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierDays; import de.deadlocker8.budgetmaster.tags.Tag; import de.deadlocker8.budgetmaster.templates.Template; import de.deadlocker8.budgetmaster.transactions.Transaction; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; import de.thecodelabs.utils.util.Localization; import de.thecodelabs.utils.util.Localization.LocalizationDelegate; @@ -37,7 +38,7 @@ import java.util.Locale; import static org.assertj.core.api.Assertions.assertThat; -class DatabaseParser_v9_convertToInternalTest +class DatabaseParser_v10_convertToInternalTest { @BeforeEach public void before() @@ -64,8 +65,8 @@ class DatabaseParser_v9_convertToInternalTest { try { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final Chart chart = new Chart("The best chart", "/* This list will be dynamically filled with all the transactions between\r\n* the start and and date you select on the \"Show Chart\" page\r\n* and filtered according to your specified filter.\r\n* An example entry for this list and tutorial about how to create custom charts ca be found in the BudgetMaster wiki:\r\n* https://github.com/deadlocker8/BudgetMaster/wiki/How-to-create-custom-charts\r\n*/\r\nvar transactionData \u003d [];\r\n\r\n// Prepare your chart settings here (mandatory)\r\nvar plotlyData \u003d [{\r\n x: [],\r\n y: [],\r\n type: \u0027bar\u0027\r\n}];\r\n\r\n// Add your Plotly layout settings here (optional)\r\nvar plotlyLayout \u003d {};\r\n\r\n// Add your Plotly configuration settings here (optional)\r\nvar plotlyConfig \u003d {\r\n showSendToCloud: false,\r\n displaylogo: false,\r\n showLink: false,\r\n responsive: true\r\n};\r\n\r\n// Don\u0027t touch this line\r\nPlotly.newPlot(\"containerID\", plotlyData, plotlyLayout, plotlyConfig);\r\n", ChartType.CUSTOM, 7, ChartDisplayType.CUSTOM, ChartGroupType.NONE, null); @@ -85,8 +86,8 @@ class DatabaseParser_v9_convertToInternalTest { try { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final Icon icon = new Icon("fas fa-icons"); @@ -110,8 +111,8 @@ class DatabaseParser_v9_convertToInternalTest { try { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final Image accountImage = new Image(new Byte[0], "awesomeIcon.png", ImageFileExtension.PNG); @@ -142,8 +143,8 @@ class DatabaseParser_v9_convertToInternalTest { try { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final Image image = new Image(new Byte[0], "awesomeIcon.png", ImageFileExtension.PNG); @@ -166,8 +167,8 @@ class DatabaseParser_v9_convertToInternalTest { try { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final Image templateImage = new Image(new Byte[0], "awesomeIcon.png", ImageFileExtension.PNG); @@ -201,8 +202,8 @@ class DatabaseParser_v9_convertToInternalTest { try { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); Account account1 = new Account("Default", AccountType.CUSTOM); @@ -317,8 +318,8 @@ class DatabaseParser_v9_convertToInternalTest @Test void test_Icons() throws IOException, URISyntaxException { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final Image image = new Image(new Byte[0], "awesomeIcon.png", ImageFileExtension.PNG); @@ -342,8 +343,8 @@ class DatabaseParser_v9_convertToInternalTest @Test void test_TransactionNameKeywords() throws IOException, URISyntaxException { - String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v9Test.json").toURI()))); - DatabaseParser_v9 importer = new DatabaseParser_v9(json); + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); final TransactionNameKeyword keyword1 = new TransactionNameKeyword("income"); @@ -353,4 +354,29 @@ class DatabaseParser_v9_convertToInternalTest .hasSize(2) .containsExactly(keyword1, keyword2); } + + @Test + void test_CsvImportSettings() throws IOException, URISyntaxException + { + String json = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("DatabaseParser_v10Test.json").toURI()))); + DatabaseParser_v10 importer = new DatabaseParser_v10(json); + InternalDatabase database = importer.parseDatabaseFromJSON().convertToInternal(); + + final CsvImportSettings expectedSettings = new CsvImportSettings(); + expectedSettings.setSeparator(";"); + expectedSettings.setEncoding("UTF-8"); + expectedSettings.setNumberOfLinesToSkip(1); + + expectedSettings.setColumnDate(1); + expectedSettings.setDatePattern("dd.MM.yyyy"); + expectedSettings.setColumnName(2); + expectedSettings.setColumnAmount(3); + expectedSettings.setDecimalSeparator("."); + expectedSettings.setGroupingSeparator(","); + expectedSettings.setColumnDescription(2); + + assertThat(database.getCsvImportSettings()) + .hasSize(1) + .containsExactly(expectedSettings); + } } \ No newline at end of file diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/ImportServiceTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/ImportServiceTest.java index 4c1c9da30..32c43f8b2 100644 --- a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/ImportServiceTest.java +++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/database/ImportServiceTest.java @@ -32,6 +32,8 @@ import de.deadlocker8.budgetmaster.templates.Template; import de.deadlocker8.budgetmaster.templates.TemplateRepository; import de.deadlocker8.budgetmaster.transactions.Transaction; import de.deadlocker8.budgetmaster.transactions.TransactionRepository; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettings; +import de.deadlocker8.budgetmaster.transactions.csvimport.CsvImportSettingsService; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword; import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordService; import de.deadlocker8.budgetmaster.utils.Strings; @@ -139,6 +141,9 @@ class ImportServiceTest @Autowired private ImportService importService; + @Autowired + private CsvImportSettingsService csvImportSettingsService; + @Test void test_importFullDatabase() throws URISyntaxException, IOException { @@ -415,6 +420,21 @@ class ImportServiceTest .containsExactly(defaultKeyword1, defaultKeyword2, defaultKeyword3, defaultKeyword4, defaultKeyword5, defaultKeyword6, defaultKeyword7, defaultKeyword8, defaultKeyword9, defaultKeyword10, defaultKeyword11, keyword1); + // csv import settings + final CsvImportSettings expectedSettings = new CsvImportSettings(); + expectedSettings.setSeparator(","); + expectedSettings.setEncoding("cp1252"); + expectedSettings.setNumberOfLinesToSkip(12); + expectedSettings.setColumnDate(3); + expectedSettings.setDatePattern("dd.MM.yy"); + expectedSettings.setColumnName(1); + expectedSettings.setColumnAmount(2); + expectedSettings.setDecimalSeparator(","); + expectedSettings.setGroupingSeparator("."); + expectedSettings.setColumnDescription(1); + + assertThat(csvImportSettingsService.getCsvImportSettings()).isEqualTo(expectedSettings); + assertThat(importService.getCollectedErrorMessages(importResultItems)).isEmpty(); } @@ -461,7 +481,7 @@ class ImportServiceTest template.setTags(new ArrayList<>()); // database - InternalDatabase database = new InternalDatabase(List.of(), List.of(), List.of(), List.of(), List.of(template), List.of(), List.of(), List.of(), List.of()); + InternalDatabase database = new InternalDatabase(List.of(), List.of(), List.of(), List.of(), List.of(template), List.of(), List.of(), List.of(), List.of(), List.of()); // act importService.importDatabase(database, true, false, true); @@ -484,7 +504,7 @@ class ImportServiceTest Mockito.when(templateGroupRepository.findFirstByType(TemplateGroupType.DEFAULT)).thenReturn(templateGroupDefault); // database - InternalDatabase database = new InternalDatabase(List.of(), List.of(), List.of(), List.of(templateGroup), List.of(templateWithGroup), List.of(), List.of(), List.of(), List.of()); + InternalDatabase database = new InternalDatabase(List.of(), List.of(), List.of(), List.of(templateGroup), List.of(templateWithGroup), List.of(), List.of(), List.of(), List.of(), List.of()); // act importService.importDatabase(database, false, true, true); @@ -514,7 +534,7 @@ class ImportServiceTest chart.setVersion(7); // database - InternalDatabase database = new InternalDatabase(List.of(), List.of(), List.of(), List.of(), List.of(), List.of(chart), List.of(), List.of(), List.of()); + InternalDatabase database = new InternalDatabase(List.of(), List.of(), List.of(), List.of(), List.of(), List.of(chart), List.of(), List.of(), List.of(), List.of()); Mockito.when(chartService.getHighestUsedID()).thenReturn(8); final ChartRepository chartRepositoryMock = Mockito.mock(ChartRepository.class); diff --git a/BudgetMasterServer/src/test/resources/DatabaseParser_v10Test.json b/BudgetMasterServer/src/test/resources/DatabaseParser_v10Test.json new file mode 100644 index 000000000..f17992ae0 --- /dev/null +++ b/BudgetMasterServer/src/test/resources/DatabaseParser_v10Test.json @@ -0,0 +1,3360 @@ +{ + "TYPE": "BUDGETMASTER_DATABASE", + "VERSION": 10, + "categories": [ + { + "ID": 1, + "name": "Keine Kategorie", + "color": "#FFFFFF", + "type": "NONE" + }, + { + "ID": 2, + "name": "Übertrag", + "color": "#FFFF00", + "type": "REST" + }, + { + "ID": 3, + "name": "0815", + "color": "#ffcc00", + "type": "CUSTOM", + "iconReferenceID": 2 + } + ], + "accounts": [ + { + "ID": 1, + "name": "Placeholder", + "accountState": "FULL_ACCESS", + "type": "ALL" + }, + { + "ID": 2, + "name": "Default", + "accountState": "FULL_ACCESS", + "type": "CUSTOM" + }, + { + "ID": 3, + "name": "Second Account", + "accountState": "FULL_ACCESS", + "type": "CUSTOM", + "iconReferenceID": 1 + } + ], + "transactions": [ + { + "ID": 5, + "amount": 35000, + "isExpenditure": false, + "date": "2018-03-13", + "accountID": 2, + "categoryID": 1, + "name": "Income", + "description": "Lorem Ipsum", + "tags": [] + }, + { + "ID": 12, + "amount": -2000, + "isExpenditure": true, + "date": "2018-06-15", + "accountID": 3, + "categoryID": 3, + "name": "Simple", + "description": "", + "tags": [ + { + "ID": 1, + "name": "0815" + } + ] + }, + { + "ID": 13, + "amount": -12300, + "isExpenditure": true, + "date": "2018-03-13", + "accountID": 2, + "categoryID": 1, + "name": "Test", + "description": "", + "tags": [], + "repeatingOption": { + "ID": 2, + "startDate": "2018-03-13", + "modifier": { + "ID": 3, + "quantity": 10, + "localizationKey": "repeating.modifier.days" + }, + "endOption": { + "times": 2, + "ID": 3, + "localizationKey": "repeating.end.key.afterXTimes" + } + } + }, + { + "ID": 16, + "amount": -250, + "isExpenditure": true, + "date": "2018-06-15", + "accountID": 3, + "categoryID": 3, + "name": "Transfer", + "description": "", + "tags": [], + "transferAccountID": 2 + }, + { + "ID": 17, + "amount": -6000, + "isExpenditure": true, + "date": "2018-03-15", + "accountID": 2, + "categoryID": 1, + "name": "repeat my transfer", + "description": "", + "tags": [], + "transferAccountID": 2, + "repeatingOption": { + "ID": 3, + "startDate": "2018-03-15", + "modifier": { + "ID": 3, + "quantity": 10, + "localizationKey": "repeating.modifier.days" + }, + "endOption": { + "times": 2, + "ID": 3, + "localizationKey": "repeating.end.key.afterXTimes" + } + } + } + ], + "templateGroups": [ + { + "ID": 1, + "name": "My Template Group Deluxe", + "type": "CUSTOM" + } + ], + "templates": [ + { + "ID": 5, + "amount": 1500, + "accountID": 2, + "categoryID": 1, + "name": "Income", + "templateName": "My Simple Template", + "description": "Lorem Ipsum", + "tags": [ + { + "name": "0815" + } + ] + }, + { + "ID": 6, + "templateName": "My Minimal Template", + "tags": [] + }, + { + "ID": 7, + "amount": -35000, + "accountID": 3, + "categoryID": 3, + "name": "Income", + "templateName": "My Transfer Template", + "description": "Lorem Ipsum", + "tags": [ + { + "name": "0815" + } + ], + "transferAccountID": 2 + }, + { + "ID": 8, + "templateName": "Template with icon", + "isExpenditure": true, + "tags": [], + "iconReferenceID": 1 + }, + { + "ID": 9, + "templateName": "Template with associated group", + "tags": [], + "templateGroupID": 1 + } + ], + "charts": [ + { + "ID": 9, + "name": "The best chart", + "script": "/* This list will be dynamically filled with all the transactions between\r\n* the start and and date you select on the \"Show Chart\" page\r\n* and filtered according to your specified filter.\r\n* An example entry for this list and tutorial about how to create custom charts ca be found in the BudgetMaster wiki:\r\n* https://github.com/deadlocker8/BudgetMaster/wiki/How-to-create-custom-charts\r\n*/\r\nvar transactionData \u003d [];\r\n\r\n// Prepare your chart settings here (mandatory)\r\nvar plotlyData \u003d [{\r\n x: [],\r\n y: [],\r\n type: \u0027bar\u0027\r\n}];\r\n\r\n// Add your Plotly layout settings here (optional)\r\nvar plotlyLayout \u003d {};\r\n\r\n// Add your Plotly configuration settings here (optional)\r\nvar plotlyConfig \u003d {\r\n showSendToCloud: false,\r\n displaylogo: false,\r\n showLink: false,\r\n responsive: true\r\n};\r\n\r\n// Don\u0027t touch this line\r\nPlotly.newPlot(\"containerID\", plotlyData, plotlyLayout, plotlyConfig);\r\n", + "type": "CUSTOM", + "version": 7 + } + ], + "images": [ + { + "ID": 1, + "image": [ + -119, + 80, + 78, + 71, + 13, + 10, + 26, + 10, + 0, + 0, + 0, + 13, + 73, + 72, + 68, + 82, + 0, + 0, + 0, + -76, + 0, + 0, + 0, + -76, + 8, + 6, + 0, + 0, + 0, + 61, + -51, + 6, + 50, + 0, + 0, + 11, + -14, + 73, + 68, + 65, + 84, + 120, + -100, + -19, + -35, + 79, + 108, + 84, + -41, + 21, + -57, + 113, + -85, + 21, + -91, + 73, + 85, + 117, + 31, + -87, + 93, + 84, + -35, + 53, + -72, + 106, + -73, + 93, + -92, + -35, + -107, + 101, + -108, + -126, + -64, + 6, + 20, + 112, + -30, + -40, + -109, + -72, + -31, + -97, + -120, + -99, + -80, + -120, + 42, + 85, + -79, + -33, + -104, + 58, + -111, + 72, + -112, + -6, + 7, + 37, + -87, + -102, + 98, + 4, + 111, + -58, + 99, + -20, + 98, + 76, + -109, + 66, + -101, + 82, + -64, + 48, + 80, + 100, + 91, + 14, + -123, + 96, + -89, + 82, + 9, + 18, + -119, + 106, + 53, + -76, + -58, + -40, + -89, + -117, + -26, + -103, + 97, + 124, + 103, + 124, + -17, + 123, + -9, + -34, + 115, + -17, + 123, + -65, + -81, + 116, + -106, + -58, + -29, + 59, + 31, + 14, + -113, + -7, + -25, + -122, + 6, + -124, + 16, + -110, + 41, + -105, + -53, + 125, + -46, + -34, + -34, + 78, + -43, + -61, + 125, + -69, + 16, + 82, + -86, + -75, + -75, + 117, + -107, + 8, + 50, + 96, + 35, + -17, + -54, + -27, + 114, + 45, + 50, + -104, + -127, + 26, + 121, + -111, + 10, + 102, + -96, + 70, + 78, + 23, + 7, + 51, + 64, + 35, + 103, + -117, + 11, + 26, + -88, + -111, + -109, + 1, + 52, + -14, + 62, + -39, + 71, + 52, + 100, + 38, + -105, + -53, + -123, + -36, + 63, + 15, + -54, + 88, + -71, + 92, + -18, + 51, + 93, + -128, + -79, + -71, + 17, + 75, + -19, + -19, + -19, + 115, + 54, + 17, + 3, + 55, + -46, + -34, + -38, + -75, + 107, + 87, + 115, + 3, + 6, + 110, + 79, + 107, + -20, + 26, + 33, + 87, + -26, + -47, + -82, + 17, + 118, + -84, + -14, + -45, + -58, + 126, + 94, + -107, + -13, + -19, + -82, + 19, + -33, + -25, + -74, + -60, + 30, + -9, + -99, + -32, + 26, + -28, + -25, + 95, + 120, + -122, + 94, + -23, + 111, + -10, + 26, + 54, + -73, + 41, + -74, + -72, + 15, + 62, + 26, + 110, + -60, + -47, + -28, + 11, + 77, + 75, + 19, + -25, + -21, + -71, + -49, + -79, + 98, + -58, + -72, + 109, + 89, + -49, + -127, + 67, + 119, + 6, + -13, + 75, + -81, + 109, + 125, + 0, + 115, + 18, + -44, + 79, + -25, + -74, + -77, + -97, + 105, + 99, + 87, + 6, + -73, + 52, + -9, + -127, + 127, + -73, + 115, + -104, + 29, + 114, + -11, + 86, + -82, + -98, + -82, + -34, + 109, + -79, + -1, + 92, + -18, + -13, + 109, + 124, + -15, + -60, + 21, + 110, + 99, + 86, + -29, + 60, + -20, + 31, + -19, + -6, + 53, + 59, + -28, + -18, + -61, + -51, + 117, + 49, + 39, + -39, + -46, + -82, + -96, + -26, + 54, + 102, + -83, + -58, + -50, + -29, + -9, + 56, + 15, + -102, + 27, + -77, + 12, + -28, + 52, + -96, + -26, + 118, + 102, + -83, + -84, + 98, + 14, + 20, + 33, + 71, + -45, + -79, + -93, + -51, + 75, + -44, + -36, + -50, + -84, + -107, + 69, + -52, + 113, + 32, + -21, + -38, + -46, + 45, + -49, + -18, + 1, + 104, + -109, + -15, + 96, + 78, + -74, + -27, + -72, + 32, + -5, + 124, + -23, + -63, + -19, + -52, + 90, + -103, + -40, + -50, + 109, + 122, + 49, + -25, + 11, + 77, + -44, + -42, + -106, + -28, + 54, + -27, + 0, + -38, + 84, + -74, + 15, + -74, + -83, + 61, + -25, + -19, + 86, + -10, + 121, + 75, + 115, + 59, + -77, + 86, + 90, + -73, + 115, + -101, + -127, + -83, + -84, + 19, + -11, + 51, + -19, + 29, + 0, + 109, + 34, + -107, + 67, + -47, + -111, + -17, + 91, + 121, + 25, + -24, + 4, + -105, + 30, + 73, + 3, + 104, + 65, + 54, + 65, + 47, + 44, + 44, + -104, + -59, + -100, + -77, + -117, + 57, + -23, + -106, + 6, + 104, + 3, + -39, + 4, + -35, + -46, + -46, + -30, + -51, + 86, + -18, + 27, + -38, + 68, + 65, + -72, + -47, + 40, + 106, + -128, + 54, + -112, + 77, + -48, + 38, + 32, + -17, + -2, + -23, + 83, + -38, + 49, + 15, + -50, + -20, + 94, + 26, + -128, + -10, + 44, + -37, + -41, + -48, + 58, + -45, + 13, + -7, + -32, + -103, + -42, + 7, + 48, + -85, + -94, + -74, + 29, + 64, + 11, + -14, + 17, + -12, + -47, + 63, + -65, + 106, + 116, + 43, + 87, + -113, + -20, + -45, + -28, + 61, + -31, + 122, + -85, + -25, + 0, + -48, + -126, + 124, + 3, + -83, + 27, + -14, + -47, + -85, + -37, + -21, + 98, + 118, + 121, + 75, + 3, + -76, + 32, + 95, + 64, + -9, + -124, + -21, + -83, + 110, + 101, + 31, + 80, + 3, + -76, + 32, + 31, + 64, + -21, + -122, + 92, + -102, + -34, + -91, + -116, + 89, + 5, + 116, + 80, + -40, + 104, + -27, + 92, + 0, + 90, + -112, + -53, + -96, + -69, + 29, + -40, + -54, + 46, + 111, + 105, + -128, + 22, + -28, + 42, + 104, + -41, + 32, + -69, + -120, + 26, + -96, + 5, + -71, + 6, + 90, + -27, + -55, + 12, + 14, + -52, + 42, + -96, + -5, + 79, + -25, + -115, + -98, + 21, + 64, + 11, + 114, + 9, + -76, + -21, + -112, + 93, + -37, + -46, + 0, + 45, + -56, + 5, + -48, + -70, + 33, + 7, + -122, + 49, + 15, + -50, + -20, + -90, + -30, + -11, + -99, + -20, + -88, + 1, + 90, + 16, + 55, + 104, + -97, + -74, + 114, + -36, + 45, + 61, + -3, + -15, + -108, + -111, + -77, + 3, + 104, + 65, + 92, + -96, + 117, + 67, + -18, + 45, + 53, + 91, + -59, + -20, + -62, + -91, + 7, + 64, + 11, + -78, + 13, + 122, + -18, + -18, + 127, + -68, + -34, + -54, + -43, + -13, + -42, + -7, + 54, + 54, + -44, + 0, + 45, + -56, + 38, + 104, + -35, + -112, + -33, + -8, + -61, + 86, + 86, + -52, + -86, + 91, + -6, + -18, + -4, + -100, + 6, + -58, + -9, + 3, + 104, + 65, + 54, + 64, + -113, + 125, + 48, + -102, + -86, + -83, + -20, + -54, + -91, + 7, + 64, + 11, + 50, + 13, + 90, + 55, + -28, + 119, + -2, + -10, + 28, + 59, + 94, + -47, + -12, + 13, + 109, + -74, + -114, + 26, + -96, + 5, + -103, + 4, + -99, + -10, + -83, + -52, + -67, + -91, + 1, + 90, + -112, + 15, + -96, + -117, + 31, + -18, + 100, + -57, + -22, + 34, + 106, + -128, + 22, + -28, + -6, + 37, + 7, + 55, + 80, + -43, + -23, + 81, + 120, + -22, + 30, + -96, + 13, + 100, + 26, + -12, + 127, + 99, + 62, + 76, + 87, + -102, + -26, + -57, + -23, + -6, + -106, + 6, + 104, + 65, + -90, + 65, + 19, + -87, + 111, + 105, + 110, + -112, + -66, + -96, + 6, + 104, + 65, + 54, + 64, + -85, + -96, + -26, + -122, + -88, + 107, + 100, + 95, + 53, + 24, + -124, + 27, + 0, + 90, + 103, + -74, + 64, + 79, + -50, + -116, + 101, + 14, + -75, + -23, + 45, + 13, + -48, + -126, + 108, + -127, + 38, + -110, + -33, + -46, + -59, + -21, + -2, + 60, + -86, + -63, + -119, + 26, + -96, + 5, + -39, + 4, + -83, + -126, + -102, + 27, + -94, + -82, + 9, + 66, + -71, + -97, + -73, + 59, + -4, + 49, + 64, + -21, + -56, + 54, + -24, + -73, + -33, + 125, + 57, + 115, + -88, + 77, + 109, + 105, + -128, + 22, + 100, + 27, + 52, + 81, + -10, + -74, + -76, + 41, + -44, + 0, + 45, + -120, + 3, + 116, + 22, + 81, + -53, + -2, + -68, + 7, + -122, + 119, + 0, + 116, + -110, + -72, + 64, + -65, + 114, + -28, + 113, + -96, + -82, + -102, + 114, + -71, + 76, + -27, + 114, + -103, + 46, + 94, + -68, + 8, + -48, + 113, + -29, + 2, + 77, + -108, + -67, + 45, + 61, + 56, + 45, + 70, + -3, + -50, + -24, + -66, + 37, + -52, + -47, + 0, + 116, + -52, + 56, + 65, + 103, + 17, + 117, + -83, + -83, + 44, + 26, + -128, + -114, + 17, + 55, + 104, + -39, + -49, + -84, + 11, + -62, + -115, + -20, + 24, + 117, + -94, + 62, + 125, + -10, + 100, + 93, + -52, + 50, + -105, + 30, + 0, + 45, + -120, + 27, + 52, + 81, + -10, + -74, + -12, + 74, + -112, + 101, + -73, + 52, + 64, + 11, + 114, + 1, + -76, + -53, + -88, + 117, + 126, + 127, + 21, + -56, + 50, + -88, + 1, + 90, + -112, + 43, + -96, + -125, + -126, + -20, + -117, + 121, + -52, + 95, + 122, + 28, + 120, + 111, + -101, + -10, + -65, + 92, + 113, + 49, + -105, + -53, + 101, + -102, + -100, + -100, + 4, + 104, + -39, + 92, + 1, + 77, + -28, + -58, + -106, + -34, + 63, + -6, + -92, + -12, + -19, + -112, + -71, + 61, + 73, + 32, + -81, + -76, + -91, + 1, + 90, + -112, + 75, + -96, + 93, + 64, + -83, + -118, + -71, + -10, + 109, + -38, + -91, + 13, + 115, + 45, + -44, + 0, + 45, + -56, + 87, + -48, + -7, + 34, + -33, + -89, + -118, + -42, + -101, + 35, + 83, + -37, + -75, + 67, + -114, + -26, + -42, + -83, + 91, + 0, + -67, + 82, + -82, + -127, + 86, + 65, + -19, + 26, + -24, + 32, + -36, + 96, + 12, + -77, + 104, + 75, + 3, + -76, + 32, + 23, + 65, + 115, + -96, + 78, + -118, + -39, + 52, + 100, + 17, + 106, + -128, + 22, + -28, + 59, + -24, + -41, + 53, + 125, + 28, + 88, + 92, + -56, + 61, + -31, + 122, + -85, + -104, + -53, + -27, + 50, + -51, + -49, + -49, + 3, + 116, + -83, + 92, + 5, + -83, + -126, + -102, + 11, + -76, + 109, + -56, + -43, + 91, + 26, + -96, + 5, + -71, + 12, + 122, + -10, + -50, + -89, + -42, + 80, + -85, + 64, + 126, + 125, + -16, + 39, + -84, + -104, + -93, + 1, + 104, + 65, + 46, + -125, + 38, + -110, + -33, + -46, + -3, + -29, + 29, + 86, + 64, + 115, + 35, + -82, + -100, + 111, + -18, + 57, + 14, + -48, + -43, + -71, + 14, + 90, + 5, + -75, + 73, + -48, + -91, + 83, + 111, + -79, + 3, + 78, + -78, + -91, + -71, + -99, + 89, + -53, + 7, + -48, + -89, + -82, + 28, + 49, + -114, + -38, + -105, + -83, + 28, + 23, + 53, + -73, + 51, + 107, + -7, + 0, + -102, + 72, + 126, + 75, + -105, + 110, + -24, + -5, + 45, + -79, + 127, + 29, + 123, + -97, + 29, + -85, + -52, + -84, + 1, + -24, + -5, + -7, + 2, + 90, + 5, + -75, + 14, + -48, + -36, + 72, + 117, + 111, + 105, + 110, + 103, + -42, + -14, + 9, + -12, + -2, + 33, + -7, + -33, + 103, + 18, + 23, + -12, + -91, + -14, + 37, + 118, + -100, + 38, + 80, + 115, + 59, + -77, + -106, + 79, + -96, + -119, + -52, + 109, + -23, + -46, + -76, + -2, + 23, + 19, + 1, + 52, + 67, + -66, + -127, + 38, + -46, + -113, + -102, + 27, + -94, + 13, + -44, + -36, + -50, + -84, + -27, + 35, + -24, + -18, + -93, + -21, + -76, + -96, + 46, + 25, + 120, + -119, + -89, + 11, + 3, + -48, + -98, + -127, + 38, + 74, + -66, + -91, + -71, + -47, + 1, + -76, + -95, + 124, + 5, + 77, + 20, + 15, + 117, + 105, + 102, + 39, + 59, + 56, + 14, + -44, + -36, + -50, + -84, + -27, + 51, + -24, + 32, + -36, + 32, + 5, + 58, + 122, + 31, + 34, + 55, + 50, + -101, + 115, + -31, + 66, + 25, + -96, + 125, + 3, + 77, + 36, + -73, + -91, + 3, + 15, + 31, + 87, + -42, + -67, + -91, + -71, + -99, + 89, + -53, + 119, + -48, + 68, + -11, + 81, + 115, + -93, + -30, + -100, + -30, + -24, + 89, + -128, + -10, + 17, + -76, + -24, + 35, + 16, + 126, + 53, + -68, + -105, + 29, + 20, + -25, + 68, + -25, + 0, + -48, + 30, + -126, + 38, + 34, + 108, + -27, + -49, + -25, + -19, + -111, + -97, + 45, + -5, + -53, + 13, + -48, + 30, + -126, + 38, + 34, + 58, + -7, + -105, + 65, + 118, + 80, + 46, + 108, + -27, + -22, + 89, + -45, + 9, + -48, + 94, + -126, + -26, + 6, + -59, + 53, + -67, + -123, + 45, + 43, + -2, + -57, + -104, + -37, + -103, + -75, + -46, + 4, + -6, + -26, + -51, + -101, + -20, + -72, + 108, + 79, + 32, + -7, + 88, + 124, + 102, + 80, + -89, + 9, + 52, + 81, + 118, + -74, + 116, + 105, + -26, + -2, + -21, + -66, + 1, + -70, + -94, + -76, + -127, + 38, + 74, + 63, + -22, + 36, + -17, + -119, + -28, + -10, + 102, + -68, + 52, + -126, + 30, + 31, + 31, + 103, + 71, + 103, + 6, + 114, + -19, + 119, + -29, + -32, + -46, + -29, + -13, + -46, + 8, + -102, + 40, + 125, + 91, + 90, + -25, + 59, + -41, + -71, + -51, + 25, + 45, + -83, + -96, + -119, + -46, + -127, + 90, + -9, + -69, + -41, + 83, + -113, + 26, + -96, + 93, + -99, + 75, + -44, + 115, + 84, + -3, + -61, + -35, + 101, + 65, + -25, + 11, + 77, + 11, + -36, + -10, + -116, + -92, + 5, + -12, + -28, + 87, + 106, + -49, + -62, + 93, + 123, + -126, + 5, + -15, + -61, + 84, + -97, + 90, + 47, + 125, + -59, + -106, + -106, + 40, + 54, + -24, + 122, + -120, + 107, + 13, + 83, + -36, + 64, + 101, + 103, + -20, + -62, + -7, + 101, + -24, + -30, + -128, + -50, + 52, + 106, + 101, + -48, + 19, + 95, + -117, + -121, + -103, + 17, + 54, + 55, + 84, + -43, + -83, + 108, + 19, + 116, + 111, + -79, + -7, + -97, + -36, + 6, + -75, + -90, + 4, + 58, + 41, + 100, + -96, + 94, + 54, + -57, + 78, + -1, + -74, + 46, + -72, + -72, + -96, + 51, + -69, + -91, + 89, + 48, + 71, + -13, + -39, + 7, + -103, + 70, + 45, + -125, + 45, + 9, + -24, + -46, + -12, + -82, + -20, + -95, + 102, + -61, + -52, + -80, + -87, + -71, + 1, + 71, + 115, + -32, + -40, + 78, + 105, + 104, + 73, + 64, + -85, + 93, + 122, + 52, + -3, + -110, + -37, + -94, + -106, + 88, + 49, + 103, + 16, + -75, + -62, + -61, + 106, + 90, + 64, + 103, + -18, + -46, + -93, + 30, + -26, + 71, + -10, + -100, + -80, + 3, + 58, + 3, + -88, + -69, + 67, + -7, + -49, + 18, + -47, + 13, + -6, + -56, + -44, + -13, + -39, + 65, + -51, + -66, + -99, + 51, + 0, + 58, + 14, + -28, + 124, + -95, + -119, + -6, + -122, + 54, + 107, + 1, + -83, + -78, + -91, + -13, + 3, + 91, + 26, + -71, + 77, + 38, + -86, + 22, + -26, + 117, + -35, + -121, + -20, + -126, + 78, + 33, + -22, + -96, + 32, + -9, + 49, + 11, + 38, + -73, + 115, + -26, + 46, + 61, + -100, + -40, + -50, + 12, + -96, + 23, + 22, + 22, + -100, + -36, + -54, + -47, + 4, + 6, + 64, + -1, + -30, + 79, + 79, + -91, + 31, + 117, + 86, + 65, + 19, + -103, + -39, + -46, + -79, + -2, + -103, + -73, + -80, + -99, + 85, + 111, + -45, + -31, + -61, + -21, + -66, + -56, + 109, + 51, + 86, + 78, + -127, + -10, + 28, + 117, + -30, + -21, + 87, + -61, + -104, + 51, + 113, + -23, + 33, + -62, + -4, + -40, + -34, + -31, + -52, + -128, + -98, + -99, + -99, + 53, + 6, + -71, + 122, + -126, + 112, + -7, + -25, + -121, + -40, + -58, + 60, + 56, + -77, + -101, + 126, + 62, + -40, + -100, + 94, + -44, + 34, + -48, + 31, + -99, + -7, + 65, + 102, + 64, + 19, + 37, + -39, + -46, + -105, + 18, + -63, + 26, + -120, + -7, + -5, + 96, + -80, + -91, + -21, + 36, + -66, + -36, + 88, + -107, + 41, + -48, + 113, + 80, + 115, + 65, + 4, + -22, + 21, + 18, + -127, + 126, + -13, + -48, + -34, + -52, + -127, + -66, + 118, + -19, + -102, + 20, + -28, + 51, + -25, + 79, + -77, + 67, + -44, + 53, + 50, + -105, + 64, + -34, + -95, + 22, + -127, + -2, + -58, + 11, + 22, + -97, + 33, + 116, + 4, + 52, + -47, + -54, + 91, + -38, + -10, + -75, + 46, + -74, + 116, + -116, + -100, + 122, + -108, + 99, + 98, + 21, + 43, + -24, + 90, + -88, + 15, + -99, + -20, + 91, + 118, + 7, + -1, + -18, + -54, + 115, + -20, + 24, + -127, + 90, + -112, + 83, + -96, + 29, + -24, + -14, + -27, + -53, + -46, + 79, + -112, + 112, + 67, + -44, + 53, + -87, + -6, + 8, + 4, + -128, + 94, + 94, + -71, + 92, + -90, + -66, + -127, + 22, + 39, + 30, + 51, + -58, + -106, + 86, + -52, + -103, + 23, + 39, + -115, + 127, + -127, + -37, + -15, + 3, + -55, + -34, + -63, + 3, + 31, + -14, + 61, + -12, + 6, + -44, + -126, + -100, + 1, + -19, + 96, + -78, + 119, + 48, + 55, + 68, + -37, + -96, + -13, + -59, + -90, + 57, + 110, + -73, + 53, + 115, + -30, + 5, + -2, + -41, + -73, + 113, + -37, + 21, + 118, + 112, + -76, + 11, + -88, + 125, + -37, + -46, + 43, + -127, + 126, + -94, + -89, + 63, + -109, + -37, + 57, + 42, + 107, + -96, + 75, + -66, + -93, + -106, + 123, + 79, + -31, + -105, + -36, + -57, + 60, + 123, + 78, + -4, + -25, + 79, + 36, + -1, + 30, + 89, + 67, + 45, + -5, + -13, + -10, + 14, + 52, + -97, + -29, + -10, + -69, + 44, + 25, + -48, + -58, + 80, + 39, + -19, + 31, + 61, + -118, + -33, + -13, + -31, + 88, + -33, + 70, + -12, + 75, + -119, + -128, + -38, + -47, + 45, + 45, + 11, + -70, + -79, + 107, + -124, + 104, + 126, + -42, + 13, + -52, + -13, + -1, + 78, + -10, + -67, + 99, + 60, + -127, + 3, + -48, + -98, + -96, + 86, + 2, + 29, + -59, + -71, + -107, + 25, + -1, + -123, + -56, + 10, + 106, + 21, + -52, + -7, + 66, + 19, + -19, + 43, + 110, + -38, + -62, + -19, + 120, + -87, + 88, + -96, + -105, + 112, + -83, + -106, + -57, + -77, + -72, + -24, + 22, + -26, + 24, + -88, + 101, + 47, + 61, + -126, + -48, + 79, + -44, + -86, + -112, + -99, + -36, + -46, + -119, + 64, + 87, + 55, + 119, + -101, + 104, + -22, + 59, + 68, + -73, + -113, + -59, + 20, + 91, + 39, + 19, + -104, + 99, + -96, + 78, + -29, + -106, + 30, + -72, + 33, + -1, + 9, + 75, + -50, + -93, + -42, + 10, + -38, + 84, + 38, + 49, + 103, + 28, + -75, + 14, + -56, + -47, + -68, + -4, + -34, + -109, + 95, + -26, + -10, + 12, + -48, + -47, + 76, + 60, + 36, + 125, + 115, + 100, + -17, + 96, + 19, + -17, + -36, + -42, + 53, + -3, + 19, + 29, + 90, + 49, + 99, + 67, + -53, + 102, + 3, + 115, + -58, + -74, + -76, + 110, + -56, + -67, + -59, + -26, + 78, + 110, + -57, + 75, + 57, + 13, + 122, + -15, + -98, + 93, + -48, + 41, + 71, + -3, + -58, + -69, + 91, + -45, + -71, + -107, + 43, + 115, + 26, + -76, + 109, + -52, + -122, + 64, + -65, + -6, + 123, + 125, + 31, + -23, + -27, + -54, + 86, + -34, + 87, + -36, + -16, + 117, + 110, + -69, + -62, + 0, + 58, + 62, + 104, + 34, + -9, + -73, + 116, + 111, + 81, + -2, + 35, + 11, + -68, + -35, + -54, + -107, + 1, + 116, + 50, + -44, + -13, + -9, + -26, + -99, + 69, + -99, + 41, + -56, + 81, + -50, + -126, + -42, + -7, + 52, + -69, + 35, + 91, + -6, + -32, + -103, + 86, + 43, + -112, + -125, + 80, + 47, + 100, + 111, + 48, + 55, + 52, + 56, + 12, + -6, + -22, + 15, + -67, + 1, + 77, + -28, + -50, + -91, + 71, + 102, + 33, + 71, + 57, + 11, + -102, + 11, + 115, + 76, + -48, + 55, + 63, + -7, + -120, + 21, + -75, + 110, + -56, + 94, + 98, + 110, + 104, + 112, + 24, + -12, + -11, + -57, + -67, + 2, + 77, + 36, + -65, + -91, + 11, + 127, + -33, + -31, + 52, + 102, + 110, + -109, + -119, + 114, + 22, + -12, + -62, + 93, + -17, + 64, + 19, + -39, + -67, + -12, + -48, + -66, + -107, + -117, + -98, + 99, + 110, + 104, + 112, + 24, + 52, + 17, + 15, + -26, + -124, + 31, + 118, + 115, + 124, + -20, + 55, + 86, + 80, + 99, + 43, + -41, + 8, + -96, + -11, + 109, + -25, + 40, + -109, + -96, + 117, + 67, + -18, + 45, + 54, + -35, + -31, + 54, + -88, + 53, + -128, + -42, + 15, + -102, + 72, + 63, + -22, + -16, + -22, + 14, + 108, + 101, + -103, + -100, + 6, + 77, + 100, + 25, + 116, + -68, + -9, + 28, + -118, + 122, + 109, + -16, + 105, + 109, + -88, + 13, + 92, + 43, + -97, + -30, + 118, + 103, + 44, + -128, + -42, + -65, + -99, + -93, + -110, + -126, + 126, + -13, + 92, + 27, + -74, + -78, + 106, + -50, + -125, + 38, + -78, + -125, + 121, + -30, + -85, + 70, + 110, + 122, + 92, + -44, + -70, + 33, + 7, + -123, + 77, + 79, + 112, + 91, + -77, + -110, + 23, + -96, + 39, + 30, + -10, + 110, + 59, + 71, + 5, + -95, + -4, + -17, + 42, + 28, + -100, + -39, + 77, + 125, + 67, + -101, + -75, + 99, + 110, + -20, + 26, + 73, + -1, + 102, + -114, + -14, + 2, + 52, + -111, + -105, + -104, + -93, + -76, + 95, + 3, + 75, + -50, + -9, + 94, + 26, + 90, + -70, + -17, + -72, + -99, + 89, + -53, + 27, + -48, + 68, + 94, + 98, + -114, + -78, + -115, + -71, + -6, + -66, + -29, + 118, + 102, + 45, + -81, + 64, + 19, + -3, + -1, + -67, + 127, + -98, + 97, + 38, + 82, + -5, + -12, + -91, + 36, + -13, + 104, + -89, + -8, + -66, + -29, + 118, + 102, + 45, + -17, + 64, + 71, + 37, + -127, + -4, + -81, + -9, + 89, + 110, + -78, + -19, + -83, + 12, + -48, + 62, + -127, + -114, + 82, + -127, + 124, + -11, + 49, + -18, + 91, + 107, + 4, + -14, + 26, + -119, + -5, + -114, + -37, + -103, + -75, + -68, + 7, + 93, + -39, + -115, + 61, + -9, + 47, + 73, + 38, + 30, + 34, + -102, + 122, + -124, + -5, + 22, + 45, + 75, + 47, + -26, + -115, + -46, + -9, + 29, + -73, + 51, + 107, + -91, + 10, + -76, + 39, + -23, + -64, + 76, + 68, + -46, + -9, + 27, + 64, + 3, + -76, + -47, + 22, + 23, + 23, + 99, + 67, + -18, + 9, + -41, + 47, + -3, + 57, + 0, + 45, + 8, + -96, + 121, + -118, + -69, + -107, + 43, + 3, + 104, + 65, + 0, + -51, + -105, + 44, + -28, + -3, + 67, + -49, + 10, + -65, + 30, + -96, + 5, + 1, + 52, + 95, + -77, + 119, + 62, + 85, + -34, + -54, + -107, + 1, + -76, + 32, + -128, + -26, + -83, + 22, + -28, + 63, + 94, + 14, + 87, + -4, + 90, + -128, + 22, + 4, + -48, + -4, + -87, + 108, + -27, + -54, + 0, + 90, + 16, + 64, + -13, + 55, + 126, + -29, + 44, + -27, + 11, + 77, + 116, + 123, + -10, + 99, + -91, + -81, + 3, + 104, + 65, + 0, + -19, + 111, + 0, + 45, + 8, + -96, + -3, + 13, + -96, + 5, + 1, + -76, + -65, + 1, + -76, + 32, + -128, + -10, + 55, + -128, + 22, + 4, + -48, + -2, + 6, + -48, + -126, + 84, + 14, + 5, + -29, + -17, + 112, + 59, + -77, + 22, + -9, + 65, + 99, + 0, + 90, + 107, + -36, + 7, + -115, + 1, + 104, + -83, + 113, + 31, + 52, + 6, + -96, + -75, + -58, + 125, + -48, + 24, + -128, + -42, + 26, + -9, + 65, + 99, + 0, + 90, + 107, + -115, + 47, + -98, + 96, + 63, + 108, + 12, + 64, + 107, + -115, + -5, + -80, + 49, + 0, + -83, + 53, + -18, + -61, + -58, + 0, + -76, + -42, + -72, + 15, + 27, + 3, + -52, + -38, + -29, + 62, + 116, + 12, + 64, + 107, + -19, + 91, + 29, + -61, + -85, + -71, + 15, + 30, + 3, + -52, + -38, + -29, + -66, + 3, + 48, + -64, + -116, + -112, + -109, + -3, + 15, + 62, + -114, + 31, + -125, + -73, + -124, + 107, + 78, + 0, + 0, + 0, + 0, + 73, + 69, + 78, + 68, + -82, + 66, + 96, + -126 + ], + "fileName": "awesomeIcon.png", + "fileExtension": "PNG" + } + ], + "icons": [ + { + "ID": 1, + "imageID": 1 + }, + { + "ID": 2, + "builtinIdentifier": "fas fa-icons", + "fontColor": "#FF0000" + } + ], + "transactionNameKeywords": [ + { + "value": "income" + }, + { + "value": "xyz" + } + ], + "csvImportSettings": [ + { + "separator": ";", + "encoding": "UTF-8", + "numberOfLinesToSkip": 1, + "columnDate": 1, + "datePattern": "dd.MM.yyyy", + "columnName": 2, + "columnAmount": 3, + "decimalSeparator": ".", + "groupingSeparator": ",", + "columnDescription": 2 + } + ] +} \ No newline at end of file diff --git a/BudgetMasterServer/src/test/resources/ImportServiceTest.json b/BudgetMasterServer/src/test/resources/ImportServiceTest.json index 02a4193a4..ea21f6c46 100644 --- a/BudgetMasterServer/src/test/resources/ImportServiceTest.json +++ b/BudgetMasterServer/src/test/resources/ImportServiceTest.json @@ -1,6 +1,6 @@ { "TYPE": "BUDGETMASTER_DATABASE", - "VERSION": 9, + "VERSION": 10, "categories": [ { "ID": 3, @@ -2245,5 +2245,19 @@ { "value": "xyz" } + ], + "csvImportSettings": [ + { + "separator": ",", + "encoding": "cp1252", + "numberOfLinesToSkip": 12, + "columnDate": 3, + "datePattern": "dd.MM.yy", + "columnName": 1, + "columnAmount": 2, + "decimalSeparator": ",", + "groupingSeparator": ".", + "columnDescription": 1 + } ] } \ No newline at end of file -- GitLab