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> 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(); 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(); var warnings = new List(); 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; } }