Files
logofclient/Tasks/AddressCheck.cs

272 lines
9.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
namespace Logof_Client;
public class AddressCheck
{
public enum ErrorTypes
{
PlzNotUsable,
PPlzNotUsable,
MayBeSameAddress,
NoPLZorPPLZ
}
public enum WarningTypes
{
NoCity,
NoStreet,
NoLastName,
NoFirstName,
NoStreetNumber,
NoPLZ,
NoPPLZ,
DoubledRefsid,
FullAddressTooLong
}
private readonly ProgressWindow _progress;
public AddressCheck(ProgressWindow progressWindow)
{
_progress = progressWindow;
}
public async Task<List<KasPerson>> Perform(int id)
{
try
{
// Find the index of the address set with the given id
var adset_index = -1;
for (var i = 0; i < Settings._instance.addressSets.addresses.Count; i++)
if (Settings._instance.addressSets.addresses[i].ID == id)
{
adset_index = i;
break;
}
if (adset_index == -1) return new List<KasPerson>();
var adset = Settings._instance.addressSets.addresses[adset_index];
var total = adset.KasPersons.Count;
var current = 0;
await Task.Run(async () =>
{
// Refsids, die mehrfach vorkommen
var doubledRefsids = adset.KasPersons
.Where(p => p.refsid > 0)
.GroupBy(p => p.refsid)
.Where(g => g.Count() > 1)
.ToDictionary(g => g.Key, g => true);
// Adressen, die mehrfach vorkommen
var doubledAddresses = adset.KasPersons
.GroupBy(p => (
p.name,
p.strasse,
p.vorname,
p.ort,
p.funktion,
p.funktion2,
p.funktionad,
p.abteilung,
p.name1,
p.name2,
p.name3,
p.name4,
p.name5))
.Where(g => g.Count() > 1)
.ToDictionary(g => g.Key, g => true);
foreach (var person in adset.KasPersons)
{
var errors = new List<ErrorTypes>();
var warnings = new List<WarningTypes>();
var hasFaults = false;
var address_component_count = 2; // cause anrede and name are first
// PLZ-Prüfung
if (person.plz == "" || person.plz == null)
{
hasFaults = true;
warnings.Add(WarningTypes.NoPLZ);
}
else
{
if (!AddressCreator.CheckPLZ(person.plz, person.land))
{
hasFaults = true;
errors.Add(ErrorTypes.PlzNotUsable);
}
}
// PPLZ-Prüfung
if (person.pplz == "" || person.pplz == null)
{
hasFaults = true;
warnings.Add(WarningTypes.NoPPLZ);
}
else
{
if (!AddressCreator.CheckPLZ(person.pplz, person.land))
{
hasFaults = true;
errors.Add(ErrorTypes.PPlzNotUsable);
}
}
if (warnings.Contains(WarningTypes.NoPLZ) && warnings.Contains(WarningTypes.NoPPLZ))
{
hasFaults = true;
errors.Add(ErrorTypes.NoPLZorPPLZ);
}
// Ort-Prüfung
if (string.IsNullOrWhiteSpace(person.ort))
{
hasFaults = true;
warnings.Add(WarningTypes.NoCity);
}
else
{
address_component_count++;
}
// Street-Number
var street = person.strasse.ToCharArray();
var intcount = 0;
foreach (var c in street)
{
int maybe;
if (int.TryParse(c.ToString(), out maybe)) intcount++;
}
if (intcount == 0)
{
hasFaults = true;
warnings.Add(WarningTypes.NoStreetNumber);
}
// Last-Name
if (string.IsNullOrWhiteSpace(person.name))
{
hasFaults = true;
warnings.Add(WarningTypes.NoLastName);
}
// First-Name
if (string.IsNullOrWhiteSpace(person.vorname))
{
hasFaults = true;
warnings.Add(WarningTypes.NoFirstName);
}
// Street-Check
if (string.IsNullOrWhiteSpace(person.strasse))
{
hasFaults = true;
warnings.Add(WarningTypes.NoStreet);
}
else
{
address_component_count++;
}
// Address-Component-Count
// Double-Refsid
if (person.refsid > 0 &&
doubledRefsids.ContainsKey(person.refsid))
{
hasFaults = true;
warnings.Add(WarningTypes.DoubledRefsid);
}
// Double-Address
var addressKey = (
person.name,
person.strasse,
person.vorname,
person.ort,
person.funktion,
person.funktion2,
person.funktionad,
person.abteilung,
person.name1,
person.name2,
person.name3,
person.name4,
person.name5);
if (doubledAddresses.ContainsKey(addressKey))
{
hasFaults = true;
errors.Add(ErrorTypes.MayBeSameAddress);
}
// Adressen-Länge
if (address_component_count > 10)
{
hasFaults = true;
warnings.Add(WarningTypes.FullAddressTooLong);
}
if (hasFaults)
lock (Settings._instance.addressSets.addresses)
{
// Directly set PersonError in the address set
var person_index = adset.KasPersons.IndexOf(person);
if (person_index >= 0)
Settings._instance.addressSets.addresses[adset_index].KasPersons[person_index]
.PersonError =
new KasPersonError((errors, warnings));
}
// Fortschritt aktualisieren
// Interlocked.Increment(ref current);
// var percent = current / (double)total * 100;
// await Dispatcher.UIThread.InvokeAsync(() =>
// {
// if (hasFaults)
// _progress.AddToLog($"Person mit id {person.id} ist fehlerhaft",
// Convert.ToInt32(percent).ToString());
//
// _progress.ChangePercentage(percent);
// });
var cd = Interlocked.Increment(ref current);
if (cd % 10 == 0)
{
var percent = cd / (double)total * 100;
await Dispatcher.UIThread.InvokeAsync(() =>
_progress.ChangePercentage(percent));
}
}
});
Settings.Save();
// Return only the persons with errors from the address set
return Settings._instance.addressSets.addresses[adset_index].KasPersons
.Where(p => p.PersonError != null)
.ToList();
}
catch (Exception ex)
{
Logger.Log($"Error while performing address check: {ex.Message}", Logger.LogType.Error);
}
return null;
}
}