diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java index d405b46fe92a9a9a79210f67ea196cb04cae6159..502eccdec42788aa4cf2e746a7d1fcd6a03c252a 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java @@ -7,6 +7,7 @@ import de.deadlocker8.budgetmaster.controller.BaseController; import de.deadlocker8.budgetmaster.services.HelpersService; import de.deadlocker8.budgetmaster.transactions.csvimport.*; import de.deadlocker8.budgetmaster.utils.Mappings; +import de.thecodelabs.utils.util.Localization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -33,7 +34,7 @@ public class TransactionImportController extends BaseController private static class ReturnValues { - public static final String TRANSACTION_IMPORT = "transactions/transactionImport"; + public static final String TRANSACTION_IMPORT = "TRANSACTIONS/transactionImport"; public static final String REDIRECT_IMPORT = "redirect:/transactionImport"; public static final String REDIRECT_CANCEL = "redirect:/transactionImport/cancel"; public static final String NEW_TRANSACTION_NORMAL = "transactions/newTransactionNormal"; @@ -51,6 +52,8 @@ public class TransactionImportController extends BaseController public static final String CSV_TRANSACTIONS = "csvTransactions"; public static final String ERROR_UPLOAD = "errorUpload"; public static final String ERROR_UPLOAD_FILE = "errorUploadFile"; + public static final String ERRORS_COLUMN_SETTINGS = "errorsColumnSettings"; + } private final TransactionService transactionService; @@ -150,14 +153,25 @@ public class TransactionImportController extends BaseController final List<CsvRow> csvRows = (List<CsvRow>) attribute; final List<CsvTransaction> csvTransactions = new ArrayList<>(); - for(CsvRow csvRow : csvRows) + final List<String> errors = new ArrayList<>(); + for(int i = 0; i < csvRows.size(); i++) { - final String date = csvRow.getColumns().get(csvColumnSettings.columnDate() - 1); - final String name = csvRow.getColumns().get(csvColumnSettings.columnName() - 1); - final String amount = csvRow.getColumns().get(csvColumnSettings.columnAmount() - 1); - csvTransactions.add(new CsvTransaction(date, name, amount, CsvTransactionStatus.PENDING)); + final CsvRow csvRow = csvRows.get(i); + try + { + final String date = csvRow.getColumns().get(csvColumnSettings.columnDate() - 1); + final String name = csvRow.getColumns().get(csvColumnSettings.columnName() - 1); + final String amount = csvRow.getColumns().get(csvColumnSettings.columnAmount() - 1); + csvTransactions.add(new CsvTransaction(date, name, amount, CsvTransactionStatus.PENDING)); + } + catch(IndexOutOfBoundsException e) + { + LOGGER.error("Invalid access to column", e); + errors.add(Localization.getString("transactions.import.error.column", i, csvRow)); + } } + request.setAttribute(RequestAttributeNames.ERRORS_COLUMN_SETTINGS, errors, RequestAttributes.SCOPE_SESSION); request.setAttribute(RequestAttributeNames.CSV_TRANSACTIONS, csvTransactions, RequestAttributes.SCOPE_SESSION); return ReturnValues.REDIRECT_IMPORT; @@ -255,6 +269,7 @@ public class TransactionImportController extends BaseController request.removeAttribute(RequestAttributeNames.CSV_TRANSACTIONS, RequestAttributes.SCOPE_SESSION); request.removeAttribute(RequestAttributeNames.ERROR_UPLOAD, RequestAttributes.SCOPE_SESSION); request.removeAttribute(RequestAttributeNames.ERROR_UPLOAD_FILE, RequestAttributes.SCOPE_SESSION); + request.removeAttribute(RequestAttributeNames.ERRORS_COLUMN_SETTINGS, RequestAttributes.SCOPE_SESSION); } private Optional<CsvTransaction> getTransactionByIndex(WebRequest request, Integer index) diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties index 1d8969f497205d713b5df451a51b2f65435ecde8..b2bbdc2fc536b3b2d04a208925edeb4e3e1b71e8 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_de.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties @@ -380,6 +380,7 @@ transactions.import.status.pending=ausstehend transactions.import.status.imported=importiert transactions.import.status.skipped=übersprungen transactions.import.actions=Aktionen +transactions.import.error.column=Zugeordnete Spalten in Zeile {0} (Zählung beginnt relativ zu Anzahl übersprungener Zeilen) nicht gefunden: {1} repeating.button.add=Wiederholung hinzufügen repeating.button.remove=Wiederholung entfernen diff --git a/BudgetMasterServer/src/main/resources/languages/base_en.properties b/BudgetMasterServer/src/main/resources/languages/base_en.properties index 5df53283dd35cd3b83b6b855725f75c32850c7ba..1ea66828fe851020af69aadc80ec29af6e9f9a9f 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_en.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties @@ -369,7 +369,7 @@ transaction.new.label.repeating=Repeating transaction.new.label.repeating.all=Every transactions.recurring.headline=Active Recurring Transactions transactions.recurring.placeholder=No active recurring transactions -transactions.import.matchColumns=Match columns +transactions.import.matchColumns=Associate columns transactions.import.column=Column transactions.import.separator=Separator transactions.import.encoding=Encoding @@ -379,6 +379,7 @@ transactions.import.status.pending=pending transactions.import.status.imported=imported transactions.import.status.skipped=skipped transactions.import.actions=Actions +transactions.import.error.column=Associated columns not found in row {0} (counting starts relative to the number of skipped rows): {1} repeating.button.add=Add repetition repeating.button.remove=Remove repetition diff --git a/BudgetMasterServer/src/main/resources/static/js/transactionImport.js b/BudgetMasterServer/src/main/resources/static/js/transactionImport.js index 1460c264b8c5b80ea3341c1c6fe284e701bb14fd..095abfcaa2ea65e4ca8f44d20dca6affd6385270 100644 --- a/BudgetMasterServer/src/main/resources/static/js/transactionImport.js +++ b/BudgetMasterServer/src/main/resources/static/js/transactionImport.js @@ -4,4 +4,6 @@ $(document).ready(function() direction: 'left', hoverEnabled: false }); + + $('.collapsible').collapsible(); }); \ No newline at end of file diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl index 0291db3bab878e36e9466726e510afebec507a46..0b360a88bf883f3f7af1d8bd823da478184293cb 100644 --- a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl +++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl @@ -6,6 +6,7 @@ <@header.header "BudgetMaster - ${locale.getString('menu.transactions.import')}"/> <@header.style "transactions"/> <@header.style "transactionImport"/> + <@header.style "collapsible"/> <#import "/spring.ftl" as s> </head> <@header.body> @@ -43,6 +44,7 @@ <#if csvTransactions??> <@renderCsvTransactions/> + <@showColumnSettingsErrors/> <#elseif csvRows?? > <div class="container"> <div class="section center-align"> @@ -217,7 +219,7 @@ </td> <td>${csvTransaction.getAmount()}</td> <td> - <@header.buttonSubmit name='action' icon='save' localizationKey='' classes='text-white'/> + <@header.buttonSubmit name='action' icon='save' localizationKey='' classes='text-white'/> <div class="fixed-action-btn edit-transaction-button"> <a class="btn-floating btn-flat waves-effect waves-light no-padding text-default edit-transaction-button-link"> <i class="material-icons">edit</i> @@ -243,6 +245,35 @@ </tr> </#macro> +<#macro showColumnSettingsErrors> + <#if errorsColumnSettings?has_content> + <div class="container"> + <div class="row"> + <div class="col s12"> + <ul class="collapsible"> + <li> + <div class="collapsible-header bold"> + <i class="fas fa-exclamation-triangle text-red"></i> + ${locale.getString("info.database.import.result.errors")} + </div> + <div class="collapsible-body"> + <table class="bordered"> + <#list errorsColumnSettings as error> + <tr> + <td><i class="fas fa-exclamation-triangle text-red"></i></td> + <td>${error}</td> + </tr> + </#list> + </table> + </div> + </li> + </ul> + </div> + </div> + </div> + </#if> +</#macro> + <#macro statusBanner status> <#if status.name() == "PENDING"> <#assign bannerClasses="background-blue text-white">