From 47942ddd788517a1c0de1c28848504efed54bb29 Mon Sep 17 00:00:00 2001 From: Elias Fierke Date: Sat, 4 Oct 2025 14:28:23 +0200 Subject: [PATCH] [fix:] import using AddressPatch now working --- DataImport.cs | 221 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 164 insertions(+), 57 deletions(-) diff --git a/DataImport.cs b/DataImport.cs index 245331c..d73bfa2 100644 --- a/DataImport.cs +++ b/DataImport.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Reflection; namespace Logof_Client; @@ -8,7 +11,13 @@ public class DataImport public static (bool, KasAddressList) ImportKasAddressList(Uri pathToCsv, AddressPatch patch = null, char separator = ',') { - // Prüfen, ob die Datei existiert + if (patch == null) + return ImportKasAddressListWithoutPatch(pathToCsv, separator); + return ImportKasAddressListWithPatch(pathToCsv, patch, separator); + } + + private static (bool, KasAddressList) ImportKasAddressListWithoutPatch(Uri pathToCsv, char separator) + { if (!File.Exists(pathToCsv.LocalPath)) { Console.WriteLine($"File not found: {pathToCsv}"); @@ -16,8 +25,6 @@ public class DataImport } using var reader = new StreamReader(pathToCsv.LocalPath); - - // Erste Zeile: CSV-Header lesen var headerLine = reader.ReadLine(); if (headerLine == null) { @@ -25,73 +32,173 @@ public class DataImport return (false, null); } - var headers = headerLine.Split(separator); // Header in Spaltennamen aufteilen (z. B. name, vorname, ort, ...) - - // Neue Adressliste anlegen var imported = new KasAddressList(Path.GetFileNameWithoutExtension(pathToCsv.LocalPath)); - // Zeilenweise durchgehen while (!reader.EndOfStream) { var line = reader.ReadLine(); if (string.IsNullOrWhiteSpace(line)) continue; - var parts = line.Split(separator); + var parts = line.Split(separator).Select(p => p.Trim()).ToArray(); - // Werte-Array vorbereiten – immer 24 Felder für KasPerson - var values = new string[24]; - for (var i = 0; i < 24; i++) - if (i < parts.Length) - values[i] = parts[i]; - else - values[i] = ""; // fehlende Spalten leer lassen - - // Patch anwenden (falls vorhanden) - if (patch != null) - for (var i = 0; i < headers.Length; i++) - { - var header = headers[i].Trim(); // z. B. "name", "vorname", "ort" - - // Das zugehörige Patch-Feld heißt z. B. "name_is" - var patchProperty = typeof(AddressPatch).GetProperty(header + "_is"); - var hasProperty = typeof(AddressPatch).GetProperty("has_" + header); - - if (patchProperty != null && hasProperty != null) - // Prüfen, ob das Patch-Feld aktiv ist - if ((bool)hasProperty.GetValue(patch)) - // Dann den Wert aus dem Patch übernehmen - values[i] = (string)patchProperty.GetValue(patch); - } + if (parts.Length < 24) + { + Console.WriteLine($"Not enough columns in line: {line}"); + continue; + } try { - // KasPerson erstellen – Reihenfolge der Werte muss mit dem Konstruktor übereinstimmen var person = new KasPerson( - ParseInt(values[0]), - values[1], - values[2], - values[3], - values[4], - values[5], - values[6], - values[7], - values[8], - values[9], - ParseInt(values[10]), - values[11], - values[12], - ParseInt(values[13]), - values[14], - values[15], - values[16], - values[17], - values[18], - values[19], - values[20], - values[21], - values[22], - values[23] + ParseInt(parts[0]), + parts[1], + parts[2], + parts[3], + parts[4], + parts[5], + parts[6], + parts[7], + parts[8], + parts[9], + ParseInt(parts[10]), + parts[11], + parts[12], + ParseInt(parts[13]), + parts[14], + parts[15], + parts[16], + parts[17], + parts[18], + parts[19], + parts[20], + parts[21], + parts[22], + parts[23] + ); + imported.KasPersons.Add(person); + } + catch (Exception ex) + { + Console.WriteLine($"Error while parsing line: {line} - {ex.Message}"); + Console.WriteLine(ex.StackTrace); + return (false, null); + } + } + + return (true, imported); + } + + private static (bool, KasAddressList) ImportKasAddressListWithPatch(Uri pathToCsv, AddressPatch patch, + char separator) + { + if (!File.Exists(pathToCsv.LocalPath)) + { + Console.WriteLine($"File not found: {pathToCsv}"); + return (false, null); + } + + using var reader = new StreamReader(pathToCsv.LocalPath); + var headerLine = reader.ReadLine(); + if (headerLine == null) + { + Console.WriteLine("File is empty."); + return (false, null); + } + + var headers = headerLine.Split(separator).Select(h => h.Trim()).ToArray(); + + var imported = new KasAddressList(Path.GetFileNameWithoutExtension(pathToCsv.LocalPath)); + var patchType = typeof(AddressPatch); + var binding = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase; + + var hasProperties = patchType.GetProperties(binding) + .Where(p => p.PropertyType == typeof(bool) && p.Name.StartsWith("has_", StringComparison.OrdinalIgnoreCase)) + .ToArray(); + + while (!reader.EndOfStream) + { + var line = reader.ReadLine(); + if (string.IsNullOrWhiteSpace(line)) + continue; + + var parts = line.Split(separator).Select(p => p.Trim()).ToArray(); + + var fieldValues = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var hasProp in hasProperties) + { + var fieldName = hasProp.Name.Substring(4); + + var hasObj = hasProp.GetValue(patch); + var has = hasObj is bool b && b; + + var patchProp = patchType.GetProperty(fieldName + "_is", binding); + + string desiredHeader = null; + if (has && patchProp != null) + desiredHeader = patchProp.GetValue(patch)?.ToString(); + else + desiredHeader = fieldName; + + var resolvedValue = ""; + + if (!string.IsNullOrEmpty(desiredHeader)) + { + var idx = Array.FindIndex(headers, + h => string.Equals(h, desiredHeader, StringComparison.OrdinalIgnoreCase)); + if (idx >= 0 && idx < parts.Length) + { + resolvedValue = parts[idx]; + } + else + { + var altIdx = Array.FindIndex(headers, h => + string.Equals(h, fieldName, StringComparison.OrdinalIgnoreCase) || + string.Equals(h, fieldName + "_is", StringComparison.OrdinalIgnoreCase)); + + if (altIdx >= 0 && altIdx < parts.Length) + resolvedValue = parts[altIdx]; + else + resolvedValue = ""; + } + } + + fieldValues[fieldName] = resolvedValue ?? ""; + } + + string GetField(string name) + { + return fieldValues.TryGetValue(name, out var v) ? v : ""; + } + + try + { + var person = new KasPerson( + ParseInt(GetField("refsid")), + GetField("anrede"), + GetField("titel"), + GetField("vorname"), + GetField("adel"), + GetField("name"), + GetField("namezus"), + GetField("anredzus"), + GetField("strasse"), + GetField("strasse2"), + ParseInt(GetField("plz")), + GetField("ort"), + GetField("land"), + ParseInt(GetField("pplz")), + GetField("postfach"), + GetField("name1"), + GetField("name2"), + GetField("name3"), + GetField("name4"), + GetField("name5"), + GetField("funktion"), + GetField("funktion2"), + GetField("abteilung"), + GetField("funktionad") ); imported.KasPersons.Add(person);