From f706d12fa40e8570d71b5adad6c76a42f380925a Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Sun, 8 Jan 2023 15:11:47 +0100
Subject: [PATCH] #724 - new input to configure number of lines to skip

---
 .../transactions/TransactionImportController.java         | 4 ++--
 .../budgetmaster/transactions/csvImport/CsvImport.java    | 2 +-
 .../budgetmaster/transactions/csvImport/CsvParser.java    | 3 ++-
 .../src/main/resources/languages/base_de.properties       | 1 +
 .../src/main/resources/languages/base_en.properties       | 1 +
 .../templates/transactions/transactionImport.ftl          | 8 ++++++--
 6 files changed, 13 insertions(+), 6 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 bd88f02cd..55d6d20d6 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionImportController.java
@@ -58,7 +58,7 @@ public class TransactionImportController extends BaseController
 	@GetMapping
 	public String transactionImport(HttpServletRequest request, Model model)
 	{
-		model.addAttribute(RequestAttributeNames.CSV_IMPORT, new CsvImport(null, ";", StandardCharsets.UTF_8.name()));
+		model.addAttribute(RequestAttributeNames.CSV_IMPORT, new CsvImport(null, ";", StandardCharsets.UTF_8.name(), 0));
 		return ReturnValues.TRANSACTION_IMPORT;
 	}
 
@@ -93,7 +93,7 @@ public class TransactionImportController extends BaseController
 		try
 		{
 			final String csvString = new String(csvImport.file().getBytes(), csvImport.encoding());
-			final List<CsvRow> csvRows = CsvParser.parseCsv(csvString, csvImport.separator().charAt(0));
+			final List<CsvRow> csvRows = CsvParser.parseCsv(csvString, csvImport.separator().charAt(0), csvImport.numberOfLinesToSkip());
 
 			request.setAttribute(RequestAttributeNames.CSV_IMPORT, csvImport, RequestAttributes.SCOPE_SESSION);
 			request.setAttribute(RequestAttributeNames.CSV_ROWS, csvRows, RequestAttributes.SCOPE_SESSION);
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java
index 2fd561af1..9e7e34e87 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvImport.java
@@ -7,7 +7,7 @@ import org.springframework.web.multipart.MultipartFile;
 import java.nio.charset.Charset;
 import java.text.MessageFormat;
 
-public record CsvImport(MultipartFile file, String separator, String encoding)
+public record CsvImport(MultipartFile file, String separator, String encoding, int numberOfLinesToSkip)
 {
 	private static final Logger LOGGER = LoggerFactory.getLogger(CsvImport.class);
 
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java
index 98098d25b..3b4adf3a2 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/csvImport/CsvParser.java
@@ -17,7 +17,7 @@ public class CsvParser
 	{
 	}
 
-	public static List<CsvRow> parseCsv(String csvString, char separator) throws IOException, CsvValidationException
+	public static List<CsvRow> parseCsv(String csvString, char separator, int numberOfLinesToSkip) throws IOException, CsvValidationException
 	{
 		final ArrayList<CsvRow> csvRows = new ArrayList<>();
 
@@ -28,6 +28,7 @@ public class CsvParser
 		try(CSVReader reader = new CSVReaderBuilder(
 				new StringReader(csvString))
 				.withCSVParser(csvParser)
+				.withSkipLines(numberOfLinesToSkip)
 				.build())
 		{
 			String[] columns;
diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties
index 905dd650b..ccaf34e97 100644
--- a/BudgetMasterServer/src/main/resources/languages/base_de.properties
+++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties
@@ -374,6 +374,7 @@ transactions.import.overview=Übersicht
 transactions.import.column=Spalte
 transactions.import.separator=Trennzeichen
 transactions.import.encoding=Kodierung
+transactions.import.numberOfLinesToSkip=Zeilen überspringen
 
 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 c3733f01d..7d1ec8045 100644
--- a/BudgetMasterServer/src/main/resources/languages/base_en.properties
+++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties
@@ -373,6 +373,7 @@ transactions.import.overview=Overview
 transactions.import.column=Column
 transactions.import.separator=Separator
 transactions.import.encoding=Encoding
+transactions.import.numberOfLinesToSkip=Skip lines
 
 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 84cde3554..e2cbec1df 100644
--- a/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl
+++ b/BudgetMasterServer/src/main/resources/templates/transactions/transactionImport.ftl
@@ -69,14 +69,18 @@
         </div>
 
         <div class="row">
-            <div class="input-field col s2 offset-s4">
+            <div class="input-field col s2 offset-s3">
                 <input id="separator" type="text" name="separator" <@validation.validation "separator" "center-align"/> value="<#if csvImport??>${csvImport.separator()}</#if>">
                 <label class="input-label" for="separator">${locale.getString("transactions.import.separator")}</label>
             </div>
             <div class="input-field col s2">
-                <input id="encoding" type="text" name="encoding"" <@validation.validation "encoding" "center-align"/> value="<#if csvImport??>${csvImport.encoding()?upper_case}</#if>">
+                <input id="encoding" type="text" name="encoding" <@validation.validation "encoding" "center-align"/> value="<#if csvImport??>${csvImport.encoding()?upper_case}</#if>">
                 <label class="input-label" for="encoding">${locale.getString("transactions.import.encoding")}</label>
             </div>
+            <div class="input-field col s2">
+                <input id="numberOfLinesToSkip" type="number" name="quantity" min="0" name="numberOfLinesToSkip" <@validation.validation "encoding" "center-align"/> value="<#if csvImport??>${csvImport.numberOfLinesToSkip()?c}</#if>">
+                <label class="input-label" for="numberOfLinesToSkip">${locale.getString("transactions.import.numberOfLinesToSkip")}</label>
+            </div>
         </div>
 
         <div class="row">
-- 
GitLab