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 5b938c723a1c5ef1dd0cfa7a27181acf33a61437..732c833e85644fee9b7d44f3bd4c55c3bbb7e5ec 100644 --- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java @@ -2,22 +2,43 @@ package de.deadlocker8.budgetmaster.transactions; import de.deadlocker8.budgetmaster.controller.BaseController; import de.deadlocker8.budgetmaster.services.HelpersService; +import de.deadlocker8.budgetmaster.transactions.csvImport.CsvRow; import de.deadlocker8.budgetmaster.utils.Mappings; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; +import java.nio.charset.StandardCharsets; +import java.util.List; @Controller @RequestMapping(Mappings.TRANSACTION_IMPORT) public class TransactionImportController extends BaseController { + private static class ModelAttributes + { + public static final String ERROR_UPLOAD = "errorUpload"; + } + private static class ReturnValues { public static final String TRANSACTION_IMPORT = "transactions/transactionImport"; + public static final String REDIRECT_CANCEL = "redirect:/transactionImport/cancel"; + + } + + private static class RequestAttributeNames + { + public static final String IMPORTED_FILE = "importedFile"; + public static final String CSV_ROWS = "csvRows"; } private final TransactionService transactionService; @@ -35,4 +56,44 @@ public class TransactionImportController extends BaseController { return ReturnValues.TRANSACTION_IMPORT; } + + @PostMapping("/upload") + public String upload(WebRequest request, Model model, @RequestParam("file") MultipartFile file) + { + if(file.isEmpty()) + { + return ReturnValues.REDIRECT_CANCEL; + } + + try + { + final String csvString = new String(file.getBytes(), StandardCharsets.UTF_8); + + String fileName = file.getOriginalFilename(); + if(fileName == null) + { + fileName = file.getName(); + } + + request.setAttribute(RequestAttributeNames.IMPORTED_FILE, fileName, RequestAttributes.SCOPE_SESSION); + request.setAttribute(RequestAttributeNames.CSV_ROWS, List.of(new CsvRow("12.12.22", "sdfghjklö", "12.30")), RequestAttributes.SCOPE_SESSION); + } + catch(Exception e) + { + LOGGER.error("CSV upload failed", e); + + model.addAttribute(ModelAttributes.ERROR_UPLOAD, e.getMessage()); + } + + return ReturnValues.TRANSACTION_IMPORT; + } + + @GetMapping("/cancel") + public String cancel(WebRequest request) + { + request.removeAttribute(RequestAttributeNames.IMPORTED_FILE, RequestAttributes.SCOPE_SESSION); + request.removeAttribute(RequestAttributeNames.CSV_ROWS, RequestAttributes.SCOPE_SESSION); + + return ReturnValues.TRANSACTION_IMPORT; + } } \ No newline at end of file diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvRow.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvRow.java new file mode 100644 index 0000000000000000000000000000000000000000..d09d23d0971ef207489e322aa7a7438f9bef900c --- /dev/null +++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvRow.java @@ -0,0 +1,33 @@ +package de.deadlocker8.budgetmaster.transactions.csvImport; + +import java.util.List; + +public class CsvRow +{ + private final List<String> columns; + + public CsvRow(List<String> columns) + { + this.columns = columns; + } + + public CsvRow(String... columns) + { + this.columns = List.of(columns); + } + + public List<String> getColumns() + { + return columns; + } + + @Override + public String toString() + { + return "CsvRow{" + + "columns=" + columns + + '}'; + } +} + + diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties index 0840702580d5b6c19ab1d6f2598ad2c6676d4751..344f4bef3819de11fc78f81ff96a2f280f96ee50 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_de.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties @@ -368,6 +368,8 @@ transaction.new.label.repeating=Wiederholung transaction.new.label.repeating.all=Alle transactions.recurring.headline=Aktive wiederholende Buchungen transactions.recurring.placeholder=Keine aktiven wiederholenden Buchungen +transactions.import.overview=Übersicht +transactions.import.column=Spalte 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 be2bde2432fc2c1a8d79cac9f8a23f4fafb07c12..d0c244cf978f5270f9bbe9d1c871f8c5f2ebbcd0 100644 --- a/BudgetMasterServer/src/main/resources/languages/base_en.properties +++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties @@ -368,6 +368,8 @@ 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.overview=Overview +transactions.import.column=Column repeating.button.add=Add repetition repeating.button.remove=Remove repetition diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl index ac7adb4e04baa0798fb0dc2280f75e3c415dec09..41cac76727a76a641aee055c5c2ec40b3978ae22 100644 --- a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl +++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl @@ -20,6 +20,27 @@ </div> <@header.content> + <div class="container"> + <#if importedFile??> + <div class="row center-align"> + <div class="col s12 m12 l8 offset-l2 headline-small text-green"> + <i class="fas fa-file-csv"></i> ${importedFile} + </div> + </div> + + <div class="row center-align"> + <div class="col s12"> + <@header.buttonLink url='/transactionImport/cancel' icon='clear' localizationKey='cancel' color='red' classes='text-white'/> + </div> + </div> + <#else> + <@csvUpload/> + </#if> + </div> + + <#if csvRows??> + <@renderCsvRows/> + </#if> </@header.content> </div> </main> @@ -28,4 +49,54 @@ <#import "../helpers/scripts.ftl" as scripts> <@scripts.scripts/> </@header.body> -</html> \ No newline at end of file +</html> + +<#macro csvUpload> + <form id="form-csv-import" method="POST" action="<@s.url '/transactionImport/upload'/>" enctype="multipart/form-data" accept-charset="UTF-8"> + <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> + + <div class="row"> + <div class="col s12 m12 l8 offset-l2 file-field input-field"> + <div class="btn background-blue"> + <i class="fas fa-file-csv"></i> + <input id="inputCsvImport" type="file" accept=".csv" name="file"> + </div> + <div class="file-path-wrapper"> + <input class="file-path validate" type="text"> + </div> + </div> + </div> + + <div class="row"> + <div class="col s12 center-align"> + <@header.buttonSubmit name='action' icon='cloud_upload' localizationKey='settings.database.import' id='button-confirm-csv-import' classes='text-white'/> + </div> + </div> + </form> +</#macro> + +<#macro renderCsvRows> + <div class="container"> + <div class="section center-align"> + <div class="headline-small">${locale.getString("transactions.import.overview")}</div> + </div> + </div> + + <div class="container"> + <table class="bordered centered"> + <tr> + <#list 1..csvRows[0].getColumns()?size as i> + <td class="bold">${locale.getString("transactions.import.column")} ${i?c}</td> + </#list> + </tr> + + <#list csvRows as cswRow> + <tr> + <#list cswRow.getColumns() as csvColumn> + <td>${csvColumn}</td> + </#list> + </tr> + </#list> + </table> + </div> +</#macro> \ No newline at end of file