[fix:] import using AddressPatch now working

This commit is contained in:
Elias Fierke
2025-10-04 14:28:23 +02:00
parent 081a705d2d
commit 47942ddd78

View File

@@ -1,5 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection;
namespace Logof_Client; namespace Logof_Client;
@@ -8,7 +11,13 @@ public class DataImport
public static (bool, KasAddressList) ImportKasAddressList(Uri pathToCsv, AddressPatch patch = null, public static (bool, KasAddressList) ImportKasAddressList(Uri pathToCsv, AddressPatch patch = null,
char separator = ',') 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)) if (!File.Exists(pathToCsv.LocalPath))
{ {
Console.WriteLine($"File not found: {pathToCsv}"); Console.WriteLine($"File not found: {pathToCsv}");
@@ -16,8 +25,6 @@ public class DataImport
} }
using var reader = new StreamReader(pathToCsv.LocalPath); using var reader = new StreamReader(pathToCsv.LocalPath);
// Erste Zeile: CSV-Header lesen
var headerLine = reader.ReadLine(); var headerLine = reader.ReadLine();
if (headerLine == null) if (headerLine == null)
{ {
@@ -25,73 +32,173 @@ public class DataImport
return (false, null); 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)); var imported = new KasAddressList(Path.GetFileNameWithoutExtension(pathToCsv.LocalPath));
// Zeilenweise durchgehen
while (!reader.EndOfStream) while (!reader.EndOfStream)
{ {
var line = reader.ReadLine(); var line = reader.ReadLine();
if (string.IsNullOrWhiteSpace(line)) if (string.IsNullOrWhiteSpace(line))
continue; 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 if (parts.Length < 24)
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" Console.WriteLine($"Not enough columns in line: {line}");
continue;
// 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);
} }
try try
{ {
// KasPerson erstellen Reihenfolge der Werte muss mit dem Konstruktor übereinstimmen
var person = new KasPerson( var person = new KasPerson(
ParseInt(values[0]), ParseInt(parts[0]),
values[1], parts[1],
values[2], parts[2],
values[3], parts[3],
values[4], parts[4],
values[5], parts[5],
values[6], parts[6],
values[7], parts[7],
values[8], parts[8],
values[9], parts[9],
ParseInt(values[10]), ParseInt(parts[10]),
values[11], parts[11],
values[12], parts[12],
ParseInt(values[13]), ParseInt(parts[13]),
values[14], parts[14],
values[15], parts[15],
values[16], parts[16],
values[17], parts[17],
values[18], parts[18],
values[19], parts[19],
values[20], parts[20],
values[21], parts[21],
values[22], parts[22],
values[23] 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<string, string>(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); imported.KasPersons.Add(person);