Files
logofclient/Tasks/CombineAddresses.cs

351 lines
13 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
namespace Logof_Client;
public class CombineAddresses
{
private readonly ProgressWindow _progress;
public CombineAddresses(ProgressWindow progressWindow)
{
_progress = progressWindow;
}
public async Task<(KasAddressList,KasAddressList)> Perform(List<KasAddressList> address_lists, string type, bool? exportUnused)
{
var res = await Task.Run(async () =>
{
if (type == "difference") return Difference(address_lists, exportUnused);
if (type == "union") return Union(address_lists, exportUnused);
if (type == "intersection") return Intersection(address_lists, exportUnused);
if (type == "symdiff") return SymmetricDifference(address_lists, exportUnused);
return null;
});
return res.Result;
// KasAddressList result = new("Ergebnis_" + DateTime.Now.ToString("ddMMyy_HHmmss"));
// await Task.Run(async () =>
// {
// for (var i = 0; i < address_lists.Count; i++)
// if (i == 0)
// lock (result)
// {
// result = address_lists[i];
// }
// else
// lock (result)
// {
// result = Merge(result, address_lists[i], i + 1, address_lists.Count).Result;
// }
// });
// return result;
return (null,null);
}
/// <summary>
/// Returns true if the addresses are the same.
/// </summary>
/// <param name="first">First address to compare</param>
/// <param name="second">Second address to compare</param>
/// <param name="only_refsid">If true, only a refsid-check will be done</param>
/// <returns></returns>
public bool CompareAddresses(KasPerson first, KasPerson second, bool only_refsid = false)
{
if (first.refsid == second.refsid) return true;
if (!only_refsid)
if (first.name == second.name &&
first.anrede == second.anrede &&
first.anredzus == second.anredzus &&
first.namezus == second.namezus &&
first.titel == second.titel &&
first.adel == second.adel &&
first.strasse == second.strasse &&
first.strasse2 == second.strasse2 &&
first.vorname == second.vorname &&
first.ort == second.ort &&
first.land == second.land &&
first.plz == second.plz &&
first.pplz == second.pplz &&
first.funktion == second.funktion &&
first.funktion2 == second.funktion2 &&
first.funktionad == second.funktionad &&
first.abteilung == second.abteilung &&
first.postfach == second.postfach &&
first.name1 == second.name1 &&
first.name2 == second.name2 &&
first.name3 == second.name3 &&
first.name4 == second.name4 &&
first.name5 == second.name5)
return true;
return false;
}
public async Task<(KasAddressList,KasAddressList)> Difference(List<KasAddressList> address_lists, bool? return_unused,
Progress? progress = null)
{
if (address_lists == null || address_lists.Count == 0)
return (new KasAddressList(KasAddressList.GenerateName("difference")),null);
progress ??= new Progress
{
TotalPersons = address_lists.Sum(l => l.KasPersons.Count),
ComparedPersons = 0
};
// Vereinigung aller Listen außer der ersten
var restUnion = new List<KasPerson>();
for (var i = 1; i < address_lists.Count; i++)
restUnion.AddRange(address_lists[i].KasPersons);
var result = new KasAddressList(KasAddressList.GenerateName("difference"));
var second_result = new KasAddressList(KasAddressList.GenerateName("difference_rest"));
foreach (var person in address_lists[0].KasPersons)
{
var isDouble = restUnion.Any(p => CompareAddresses(person, p));
if (!isDouble)
result.KasPersons.Add(person);
else
second_result.KasPersons.Add(person);
progress.Increment();
if (progress.LogAction == null) continue;
var logMessage =
$"Person mit refsid {person.refsid} verglichen mit {restUnion.Count} Personen des Restes.";
await Dispatcher.UIThread.InvokeAsync(() => progress.LogAction?.Invoke(logMessage));
}
if(return_unused == true) return (result,second_result);
else return (result, null);
}
public async Task<(KasAddressList,KasAddressList)> Union(List<KasAddressList> address_lists, bool? return_unused, Progress progress = null)
{
var result = new KasAddressList(KasAddressList.GenerateName("union"));
var second_result = new KasAddressList(KasAddressList.GenerateName("union_rest"));
if (address_lists == null || address_lists.Count == 0)
return (result,null);
var total = address_lists.Sum(l => l.KasPersons.Count);
var processed = 0;
foreach (var list in address_lists)
foreach (var person in list.KasPersons)
{
if (!result.KasPersons.Any(existing => CompareAddresses(existing, person)))
result.KasPersons.Add(person);
else
second_result.KasPersons.Add(person);
processed++;
var percent = processed / (double)total * 100;
var logMessage =
$"{percent:F1}%: Person mit {person.refsid} hinzugefügt (aktuell {result.KasPersons.Count} Einträge)";
if (progress == null) continue;
if (Dispatcher.UIThread.CheckAccess())
progress.LogAction?.Invoke(logMessage);
else
Dispatcher.UIThread.Post(() => progress.LogAction?.Invoke(logMessage));
}
if(return_unused == true) return (result,second_result);
else return (result, null);
}
public async Task<KasAddressList> MoveDuplicatesToNew()
{
return null;
}
public async Task<(KasAddressList,KasAddressList)> Intersection(List<KasAddressList> address_lists, bool? return_unused, Progress progress = null)
{
var result = new KasAddressList(KasAddressList.GenerateName("intersection"));
var second_result = new KasAddressList(KasAddressList.GenerateName("intersection_rest"));
if (address_lists == null || address_lists.Count == 0)
return (result,null);
// Nur die erste Liste als Ausgangspunkt verwenden
var baseList = address_lists[0];
var otherLists = address_lists.Skip(1).ToList();
var total = baseList.KasPersons.Count;
var processed = 0;
foreach (var person in baseList.KasPersons)
{
// Prüfen, ob Person in *allen* anderen Listen vorkommt
var isInAll = otherLists.All(list =>
list.KasPersons.Any(existing => CompareAddresses(existing, person)));
if (isInAll)
result.KasPersons.Add(person);
else
second_result.KasPersons.Add(person);
processed++;
var percent = processed / (double)total * 100;
var logMessage =
$"{percent:F1}%: Person mit {person.refsid} geprüft {(isInAll ? "in allen enthalten" : "nicht überall vorhanden")}";
// Sicher und nicht blockierend loggen
if (progress != null)
{
if (Dispatcher.UIThread.CheckAccess())
progress.LogAction?.Invoke(logMessage);
else
Dispatcher.UIThread.Post(() => progress.LogAction?.Invoke(logMessage));
}
}
if(return_unused == true) return (result,second_result);
else return (result, null);
}
public async Task<(KasAddressList,KasAddressList)> SymmetricDifference(List<KasAddressList> address_lists, bool? return_unused, Progress progress = null)
{
var result = new KasAddressList(KasAddressList.GenerateName("symmetric_difference"));
var second_result = new KasAddressList(KasAddressList.GenerateName("symmetric_rest"));
if (address_lists == null || address_lists.Count == 0)
return (result, null);
var total = address_lists.Sum(l => l.KasPersons.Count);
var processed = 0;
// Wir sammeln alle Personen + zählen, wie oft sie vorkommen
var allPersons = new List<(KasPerson person, int count)>();
foreach (var list in address_lists)
foreach (var person in list.KasPersons)
{
// Prüfen, ob schon vorhanden
var existing = allPersons.FirstOrDefault(p => CompareAddresses(p.person, person));
if (existing.person != null)
{
// Falls schon drin → Vorkommen erhöhen
var index = allPersons.IndexOf(existing);
allPersons[index] = (existing.person, existing.count + 1);
}
else
{
// Neu hinzufügen
allPersons.Add((person, 1));
}
processed++;
var percent = processed / (double)total * 100;
var logMessage =
$"{percent:F1}%: Person mit {person.refsid} verarbeitet (Zwischengröße {allPersons.Count})";
if (progress != null)
{
if (Dispatcher.UIThread.CheckAccess())
progress.LogAction?.Invoke(logMessage);
else
Dispatcher.UIThread.Post(() => progress.LogAction?.Invoke(logMessage));
}
}
// Nur diejenigen übernehmen, die *genau einmal* vorkamen
foreach (var (person, count) in allPersons)
if (count == 1)
result.KasPersons.Add(person);
else
second_result.KasPersons.Add(person);
if(return_unused == true) return (result,second_result);
else return (result, null);
}
// private async Task<KasAddressList> Merge(KasAddressList first, KasAddressList second, int num, int total)
// {
// foreach (var sec in second.KasPersons)
// {
// var is_new = true;
// foreach (var fi in first.KasPersons)
// {
// if (fi.refsid == sec.refsid)
// {
// is_new = false;
// break;
// }
//
// if (fi.name == sec.name &&
// fi.anrede == sec.anrede &&
// fi.anredzus == sec.anredzus &&
// fi.namezus == sec.namezus &&
// fi.titel == sec.titel &&
// fi.adel == sec.adel &&
// fi.strasse == sec.strasse &&
// fi.strasse2 == sec.strasse2 &&
// fi.vorname == sec.vorname &&
// fi.ort == sec.ort &&
// fi.land == sec.land &&
// fi.plz == sec.plz &&
// fi.pplz == sec.pplz &&
// fi.funktion == sec.funktion &&
// fi.funktion2 == sec.funktion2 &&
// fi.funktionad == sec.funktionad &&
// fi.abteilung == sec.abteilung &&
// fi.postfach == sec.postfach &&
// fi.name1 == sec.name1 &&
// fi.name2 == sec.name2 &&
// fi.name3 == sec.name3 &&
// fi.name4 == sec.name4 &&
// fi.name5 == sec.name5)
// {
// is_new = false;
// break;
// }
// }
//
// if (is_new) first.KasPersons.Add(sec);
// var subperc = second.KasPersons.IndexOf(sec) / second.KasPersons.Count;
// var percent = (num + (double)subperc) / total * 100;
// await Dispatcher.UIThread.InvokeAsync(() =>
// {
// if (is_new)
// _progress.AddToLog($"Person mit refsid {sec.refsid} ergänzt");
// else
// _progress.AddToLog($"Person mit refsid {sec.refsid} bereits vorhanden");
//
// _progress.ChangePercentage(percent);
// });
// }
//
// return first;
// }
}
public class Progress
{
public int TotalPersons { get; set; } // Gesamtzahl der zu prüfenden Personen
public int ComparedPersons { get; set; } // Schon verglichene Personen
public double Percentage => TotalPersons == 0 ? 0 : (double)ComparedPersons / TotalPersons * 100;
public Action<string>? LogAction { get; set; } // z.B. Dispatcher-UI-Callback
public void Increment()
{
var comparedPersons = ComparedPersons;
Interlocked.Increment(ref comparedPersons);
}
}