From 3a8e77342581f128c87a9d8803593e0a7123a7a8 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Wed, 11 Jan 2023 23:43:57 +0100 Subject: [PATCH] #724 - collect column access errors and display them --- .../TransactionImportController.java | 27 +++++++++++---- .../resources/languages/base_de.properties | 1 + .../resources/languages/base_en.properties | 3 +- .../resources/static/js/transactionImport.js | 2 ++ .../transactions/transactionImport.ftl | 33 ++++++++++++++++++- 5 files changed, 58 insertions(+), 8 deletions(-) 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 d405b46fe..502eccdec 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 1d8969f49..b2bbdc2fc 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 5df53283d..1ea66828f 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 1460c264b..095abfcaa 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 0291db3ba..0b360a88b 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"> -- GitLab