using Elwig.Helpers; using Elwig.Models.Entities; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System; using Microsoft.EntityFrameworkCore; using Elwig.Documents; using System.Windows.Input; using System.Windows; using Elwig.Helpers.Billing; using Elwig.Models.Dtos; using Elwig.Helpers.Export; using Microsoft.Win32; using Elwig.ViewModels; using System.IO; using System.Net.Http; namespace Elwig.Services { public static class MemberService { public enum ExportSubject { All, AllActive, FromFilters, Selected, }; public static async Task InitInputs(this MemberAdminViewModel vm) { using var ctx = new AppDbContext(); vm.MgNrString = $"{await ctx.NextMgNr()}"; vm.EntryDate = DateTime.Now.ToString("dd.MM.yyyy"); if (vm.BranchSource.Count() == 1) vm.Branch = vm.BranchSource.First(); vm.IsActive = true; vm.ContactViaPost = true; vm.EnableMemberReferenceButton = false; } public static void ClearInputs(this MemberAdminViewModel vm) { vm.IsMemberSelected = false; vm.MemberHasEmail = false; vm.MemberCanSendEmail = false; vm.EnableMemberReferenceButton = false; vm.StatusDeliveriesLastSeason = "-"; vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}"; vm.StatusDeliveriesLastSeasonToolTip = null; vm.StatusDeliveriesThisSeason = "-"; vm.StatusDeliveriesThisSeasonInfo = $"{Utils.CurrentLastSeason}"; vm.StatusDeliveriesThisSeasonToolTip = null; vm.StatusAreaCommitment = "-"; vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}"; vm.StatusAreaCommitmentToolTip = null; vm.Age = "-"; } public static void FillInputs(this MemberAdminViewModel vm, Member m) { vm.IsMemberSelected = true; vm.MgNrString = $"{m.MgNr}"; vm.PredecessorMgNrString = $"{m.PredecessorMgNr}"; vm.IsJuridicalPerson = m.IsJuridicalPerson; vm.EnableMemberReferenceButton = m.PredecessorMgNr != null; vm.Prefix = m.Prefix; vm.GivenName = m.GivenName; vm.Name = m.Name; vm.Suffix = m.Suffix; vm.ForTheAttentionOf = m.ForTheAttentionOf; vm.Birthday = (m.Birthday != null) ? string.Join(".", m.Birthday.Split("-").Reverse()) : null; if (m.Birthday?.Length == 10) { vm.Age = Utils.GetAge(DateOnly.ParseExact(m.Birthday, "yyyy-MM-dd")).ToString(); } else if (m.Birthday != null) { vm.Age = "ca. " + (DateTime.Now.Year - int.Parse(m.Birthday[^4..])).ToString(); } else { vm.Age = "-"; } vm.IsDeceased = m.IsDeceased; vm.Address = m.Address; if (m.PostalDest.AtPlz is AT_PlzDest p) { vm.PlzString = $"{p.Plz}"; vm.Ort = ControlUtils.GetItemFromSource(vm.OrtSource, p); } else { vm.PlzString = null; vm.Ort = null; } var emailAddrs = m.EmailAddresses.OrderBy(a => a.Nr).ToList(); for (int i = 0; i < vm.EmailAddresses.Count; i++) { if (i < emailAddrs.Count) { var emailAddr = emailAddrs[i]; vm.EmailAddresses[i] = emailAddr.Address; } else { vm.EmailAddresses[i] = null; } } var phoneNrs = m.TelephoneNumbers.OrderBy(p => p.Nr).ToList(); for (int i = 0; i < vm.PhoneNrs.Count; i++) { if (i < phoneNrs.Count) { var phoneNr = phoneNrs[i]; var idx = vm.PhoneNrTypes.Select((e, i) => (e, i)).FirstOrDefault(kv => kv.e.Key == phoneNr.Type).i; vm.PhoneNrs[i] = new(idx, phoneNr.Number, phoneNr.Comment); } else { vm.PhoneNrs[i] = new(); } } vm.Iban = m.Iban; vm.Bic = m.Bic; vm.UstIdNr = m.UstIdNr; vm.LfbisNr = m.LfbisNr; vm.IsBuchführend = m.IsBuchführend; vm.IsOrganic = m.IsOrganic; var billingAddr = m.BillingAddress; if (billingAddr != null) { vm.BillingName = billingAddr.FullName; vm.BillingAddress = billingAddr.Address; if (billingAddr.PostalDest.AtPlz is AT_PlzDest b) { vm.BillingPlzString = $"{b.Plz}"; vm.BillingOrt = ControlUtils.GetItemFromSource(vm.BillingOrtSource, b); } } else { vm.BillingName = null; vm.BillingAddress = null; vm.BillingPlzString = null; vm.BillingOrt = null; } vm.EntryDate = (m.EntryDateString != null) ? string.Join(".", m.EntryDateString.Split("-").Reverse()) : null; vm.ExitDate = (m.ExitDateString != null) ? string.Join(".", m.ExitDateString.Split("-").Reverse()) : null; vm.BusinessSharesString = $"{m.BusinessShares}"; vm.AccountingNr = m.AccountingNr; vm.Branch = (Branch?)ControlUtils.GetItemFromSourceWithPk(vm.BranchSource, m.ZwstId); vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr); vm.Comment = m.Comment; vm.IsActive = m.IsActive; vm.IsVollLieferant = m.IsVollLieferant; vm.IsFunktionär = m.IsFunktionär; vm.ContactViaPost = m.ContactViaPost; vm.ContactViaEmail = m.ContactViaEmail; vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}"; vm.StatusDeliveriesLastSeason = "..."; vm.StatusDeliveriesLastSeasonToolTip = null; vm.StatusDeliveriesThisSeasonInfo = $"{Utils.CurrentLastSeason}"; vm.StatusDeliveriesThisSeason = "..."; vm.StatusDeliveriesThisSeasonToolTip = null; vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}"; vm.StatusAreaCommitment = "..."; vm.StatusAreaCommitmentToolTip = null; Utils.RunBackground("Mitgliederdaten laden", async () => { using var ctx = new AppDbContext(); var d1 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason - 1 && d.MgNr == m.MgNr); var (_, d1GridData, _, _) = await DeliveryService.GenerateToolTipData(d1.SelectMany(d => d.Parts)); var textLast = $"{await d1.CountAsync():N0} ({await d1.SumAsync(d => d.Parts.Count):N0}), {await d1.SelectMany(d => d.Parts).SumAsync(p => p.Weight):N0} kg"; var d2 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason && d.MgNr == m.MgNr); var (_, d2GridData, _, _) = await DeliveryService.GenerateToolTipData(d2.SelectMany(d => d.Parts)); var textThis = $"{await d2.CountAsync():N0} ({await d2.SumAsync(d => d.Parts.Count):N0}), {await d2.SelectMany(d => d.Parts).SumAsync(p => p.Weight):N0} kg"; var c = m.ActiveAreaCommitments(ctx, Utils.CurrentLastSeason); int maxKgPerHa = 10_000; try { var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year)); if (s != null) maxKgPerHa = s.MaxKgPerHa; } catch { } var (text, gridData) = await AreaComService.GenerateToolTipData(c, maxKgPerHa); var deliveries = await ctx.Deliveries .Where(d => d.MgNr == m.MgNr) .GroupBy(d => d.Year) .ToDictionaryAsync(g => g.Key, g => g.Any()); await App.MainDispatcher.BeginInvoke(() => { var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []); var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []); var grid = AreaComService.GenerateToolTip(gridData); vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}"; vm.StatusDeliveriesLastSeason = textLast; vm.StatusDeliveriesLastSeasonToolTip = d1Grid; vm.StatusDeliveriesThisSeasonInfo = $"{Utils.CurrentLastSeason}"; vm.StatusDeliveriesThisSeason = textThis; vm.StatusDeliveriesThisSeasonToolTip = d2Grid; vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}"; vm.StatusAreaCommitment = text; vm.StatusAreaCommitmentToolTip = grid; vm.MemberHasDeliveries = Enumerable.Range(0, 9999).Select(i => deliveries.GetValueOrDefault(i, false)).ToList(); }); }); vm.MemberHasEmail = m.EmailAddresses.Count > 0; vm.MemberCanSendEmail = App.Config.Smtp != null && m.EmailAddresses.Count > 0; vm.MemberHasDeliveries = Enumerable.Range(0, 9999).Select(i => false).ToList(); } public static async Task<(List, IQueryable, List)> GetFilters(this MemberAdminViewModel vm, AppDbContext ctx) { List filterNames = []; IQueryable memberQuery = ctx.Members; if (vm.ShowOnlyActiveMembers) { memberQuery = memberQuery.Where(m => m.IsActive); filterNames.Add("aktive Mitglieder"); } var filterMgNr = new List(); var filterZwst = new List(); var filterKgNr = new List(); var filterLfbisNr = new List(); var filterUstIdNr = new List(); var filterAreaCom = new List(); var filter = vm.TextFilter; if (filter.Count > 0) { var branches = await ctx.Branches.ToListAsync(); var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m); var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg); var areaComs = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t); for (int i = 0; i < filter.Count; i++) { var e = filter[i]; if (e.Length >= 5 && e.Length <= 10 && "funktionär".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.IsFunktionär); filter.RemoveAt(i--); filterNames.Add("Funktionäre"); } else if (e.Length >= 6 && e.Length <= 11 && e[0] == '!' && "funktionär".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.IsFunktionär); filter.RemoveAt(i--); filterNames.Add("Nicht-Funktionäre"); } else if (e.Equals("bio", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.IsOrganic); filter.RemoveAt(i--); filterNames.Add("Bio-Betriebe"); } else if (e.Equals("!bio", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.IsOrganic); filter.RemoveAt(i--); filterNames.Add("Nicht-Bio-Betriebe"); } else if (e.Length >= 4 && e.Length <= 13 && "volllieferant".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.IsVollLieferant); filter.RemoveAt(i--); filterNames.Add("Volllieferanten"); } else if (e.Length >= 5 && e.Length <= 14 && e[0] == '!' && "volllieferant".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.IsVollLieferant); filter.RemoveAt(i--); filterNames.Add("Nicht-Vollieferanten"); } else if (e.Length >= 5 && e.Length <= 11 && "buchführend".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.IsBuchführend); filter.RemoveAt(i--); filterNames.Add("buchführend"); } else if (e.Length >= 6 && e.Length <= 12 && e[0] == '!' && "buchführend".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.IsBuchführend); filter.RemoveAt(i--); filterNames.Add("pauschaliert"); } else if (e.Length >= 8 && e.Length <= 12 && "pauschaliert".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.IsBuchführend); filter.RemoveAt(i--); filterNames.Add("pauschaliert"); } else if (e.Length >= 9 && e.Length <= 13 && e[0] == '!' && "pauschaliert".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.IsBuchführend); filter.RemoveAt(i--); filterNames.Add("buchführend"); } else if (e.Equals("email", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.EmailAddresses.Count > 0); filter.RemoveAt(i--); filterNames.Add("mind. eine E-Mail-Adresse"); } else if (e.Equals("!email", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.EmailAddresses.Count == 0); filter.RemoveAt(i--); filterNames.Add("keine E-Mail-Adresse"); } else if (e.Equals("telnr", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.TelephoneNumbers.Count > 0); filter.RemoveAt(i--); filterNames.Add("mind. eine Tel.-Nr."); } else if (e.Equals("!telnr", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.TelephoneNumbers.Count == 0); filter.RemoveAt(i--); filterNames.Add("keine Tel.-Nr."); } else if (e.Equals("kontakt:email", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.ContactViaEmail); filter.RemoveAt(i--); filterNames.Add("Kontaktart E-Mail"); } else if (e.Equals("!kontakt:email", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.ContactViaEmail); filter.RemoveAt(i--); filterNames.Add("nicht Kontaktart E-Mail"); } else if (e.Equals("kontakt:post", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => m.ContactViaPost); filter.RemoveAt(i--); filterNames.Add("Kontaktart Post"); } else if (e.Equals("!kontakt:post", StringComparison.CurrentCultureIgnoreCase)) { memberQuery = memberQuery.Where(m => !m.ContactViaPost); filter.RemoveAt(i--); filterNames.Add("nicht Kontaktart Post"); } else if (e.All(char.IsAsciiDigit) && mgnr.ContainsKey(e)) { filterMgNr.Add(int.Parse(e)); filter.RemoveAt(i--); filterNames.Add($"MgNr. {e}"); } else if (kgs.TryGetValue(e, out var kg)) { filterKgNr.Add(kg.KgNr); filter.RemoveAt(i--); filterNames.Add($"Stammgemeinde {kg.Name}"); } else if (e.StartsWith("zwst:")) { try { var branch = branches.Where(b => b.Name.StartsWith(e[5..], StringComparison.CurrentCultureIgnoreCase)).Single(); filterZwst.Add(branch.ZwstId); filter.RemoveAt(i--); filterNames.Add($"Zweigstelle {branch.Name}"); } catch (InvalidOperationException) { } } else if (e.StartsWith('+') && e[1..].All(char.IsAsciiDigit)) { memberQuery = memberQuery.Where(m => m.TelephoneNumbers.Any(t => t.Number.Replace(" ", "").StartsWith(e))); filter.RemoveAt(i--); filterNames.Add($"Tel.-Nr. {e}"); } else if (areaComs.ContainsKey(e.ToUpper())) { filterAreaCom.Add(e.ToUpper()); filter.RemoveAt(i--); filterNames.Add($"Flächenbindung {e.ToUpper()}"); } else if (Validator.CheckLfbisNr(e)) { filterLfbisNr.Add(e); filter.RemoveAt(i--); filterNames.Add($"Betriebsnummer {e}"); } else if (Validator.CheckUstIdNr(e.ToUpper())) { filterUstIdNr.Add(e.ToUpper()); filter.RemoveAt(i--); filterNames.Add($"UID {e.ToUpper()}"); } else if (e.Length > 2 && e.StartsWith('"') && e.EndsWith('"')) { filter[i] = e[1..^1]; } else if (e.Length < 2) { filter.RemoveAt(i--); } } if (filterMgNr.Count > 0) memberQuery = memberQuery.Where(m => filterMgNr.Contains(m.MgNr)); if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr)); if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId)); if (filterAreaCom.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments()).Any(c => filterAreaCom.Contains(c.VtrgId))); if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr)); if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr)); } return (filterNames, memberQuery, filter); } public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) { Mouse.OverrideCursor = Cursors.AppStarting; try { using var ctx = new AppDbContext(); using var doc = new MemberDataSheet(m, ctx); await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt")); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) { Mouse.OverrideCursor = Cursors.AppStarting; try { var b = new Billing(year); await b.FinishSeason(); await b.CalculateBuckets(); App.HintContextChange(); using var ctx = new AppDbContext(); var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m); using var doc = new DeliveryConfirmation(ctx, year, m, data); await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}")); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) { Mouse.OverrideCursor = Cursors.AppStarting; try { using var ctx = new AppDbContext(); var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!; var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr); var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!; var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data); using var doc = new CreditNote(ctx, p, data[m.MgNr], b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers, await ctx.GetMemberUnderDelivery(year, m.MgNr)); await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {v.Name}", $"Im Anhang finden Sie die Traubengutschrift {v.Name}")); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } public static async Task GenerateMemberList(this MemberAdminViewModel vm, ExportSubject subject, ExportMode mode) { using var ctx = new AppDbContext(); IQueryable query; List filterNames = []; if (subject == ExportSubject.All) { query = ctx.Members; } else if (subject == ExportSubject.AllActive) { query = ctx.Members.Where(m => m.IsActive); filterNames.Add("aktive Mitglieder"); } else if (subject == ExportSubject.FromFilters) { var (f, q, _) = await vm.GetFilters(ctx); query = q; filterNames.AddRange(f); } else if (subject == ExportSubject.Selected) { var mgnr = vm.SelectedMember?.MgNr; if (mgnr == null) return; query = ctx.Members.Where(m => m.MgNr == mgnr); filterNames.Add($"{mgnr}"); } else { throw new ArgumentException("Invalid value for ExportSubject"); } if (vm.MemberListOrderByMgNr) { query = query .OrderBy(m => m.Branch!.Name) .ThenBy(m => m.MgNr); } else if (vm.MemberListOrderByName) { query = query .OrderBy(m => m.Branch!.Name) .ThenBy(m => m.Name) .ThenBy(m => m.GivenName) .ThenBy(m => m.MgNr); } else if (vm.MemberListOrderByOrt) { query = query .OrderBy(m => m.Branch!.Name) .ThenBy(m => m.DefaultWbKg!.AtKg.Name) .ThenBy(m => m.Name) .ThenBy(m => m.GivenName) .ThenBy(m => m.MgNr); } if (mode == ExportMode.SaveList) { var d = new SaveFileDialog() { FileName = $"{MemberList.Name}.ods", DefaultExt = "ods", Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", Title = $"{MemberList.Name} speichern unter - Elwig" }; if (d.ShowDialog() == true) { Mouse.OverrideCursor = Cursors.AppStarting; try { var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); using var ods = new OdsFile(d.FileName); await ods.AddTable(data); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } } else if (mode == ExportMode.Export) { var d = new SaveFileDialog() { FileName = subject == ExportSubject.Selected ? $"Mitglied_{vm.SelectedMember?.MgNr}.elwig.zip" : $"Mitglieder_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip", DefaultExt = ".elwig.zip", Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip", Title = $"{MemberList.Name} speichern unter - Elwig" }; if (d.ShowDialog() == true) { Mouse.OverrideCursor = Cursors.AppStarting; try { var members = await query .OrderBy(m => m.MgNr) .Include(m => m.BillingAddress) .Include(m => m.TelephoneNumbers) .Include(m => m.EmailAddresses) .AsSplitQuery() .ToListAsync(); var areaComs = await query .SelectMany(m => m.AreaCommitments) .Include(c => c.Rd) .ToListAsync(); await ElwigData.Export(d.FileName, members, areaComs, filterNames); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } } else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) { Mouse.OverrideCursor = Cursors.AppStarting; try { var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip"; var path = Path.Combine(App.TempPath, filename); var members = await query .OrderBy(m => m.MgNr) .Include(m => m.BillingAddress) .Include(m => m.TelephoneNumbers) .Include(m => m.EmailAddresses) .AsSplitQuery() .ToListAsync(); var areaComs = await query .SelectMany(m => m.AreaCommitments) .Include(c => c.Rd) .ToListAsync(); if (members.Count == 0) { MessageBox.Show("Es wurden keine Mitglieder zum Hochladen ausgewählt!", "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error); } else { await ElwigData.Export(path, members, areaComs, filterNames); await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); MessageBox.Show($"Hochladen von {members.Count} Mitgliedern erfolgreich!", "Mitglieder hochgeladen", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (HttpRequestException exc) { MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error); } catch (TaskCanceledException exc) { MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } else { Mouse.OverrideCursor = Cursors.AppStarting; try { var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); using var doc = new MemberList(string.Join(" / ", filterNames), data); await Utils.ExportDocument(doc, mode); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } } public static async Task UpdateMember(this MemberAdminViewModel vm, int? oldMgNr) { var newMgNr = (int)vm.MgNr!; using (var ctx = new AppDbContext()) { var m = new Member { MgNr = oldMgNr ?? newMgNr, PredecessorMgNr = vm.PredecessorMgNr, IsJuridicalPerson = vm.IsJuridicalPerson, Prefix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Prefix) ? null : vm.Prefix, GivenName = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.GivenName) ? null : vm.GivenName, Name = vm.Name!, Suffix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Suffix) ? null : vm.Suffix, ForTheAttentionOf = !vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.ForTheAttentionOf) ? null : vm.ForTheAttentionOf, Birthday = string.IsNullOrEmpty(vm.Birthday) ? null : string.Join("-", vm.Birthday!.Split(".").Reverse()), IsDeceased = vm.IsDeceased, CountryNum = 40, // Austria AT AUT PostalDestId = vm.Ort!.Id, Address = vm.Address!, Iban = string.IsNullOrEmpty(vm.Iban) ? null : vm.Iban?.Replace(" ", ""), Bic = string.IsNullOrEmpty(vm.Bic) ? null : vm.Bic, UstIdNr = string.IsNullOrEmpty(vm.UstIdNr) ? null : vm.UstIdNr, LfbisNr = string.IsNullOrEmpty(vm.LfbisNr) ? null : vm.LfbisNr, IsBuchführend = vm.IsBuchführend, IsOrganic = vm.IsOrganic, EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()), ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()), BusinessShares = (int)vm.BusinessShares!, AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr, IsActive = vm.IsActive, IsVollLieferant = vm.IsVollLieferant, IsFunktionär = vm.IsFunktionär, ZwstId = vm.Branch?.ZwstId, DefaultKgNr = vm.DefaultKg?.KgNr, Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment, ContactViaPost = vm.ContactViaPost, ContactViaEmail = vm.ContactViaEmail, }; if (oldMgNr != null) { ctx.Update(m); } else { ctx.Add(m); } ctx.RemoveRange(ctx.BillingAddresses.Where(a => a.MgNr == oldMgNr)); if (vm.BillingOrt != null && vm.BillingName != null) { var p = vm.BillingOrt; ctx.Add(new BillingAddr { MgNr = m.MgNr, FullName = vm.BillingName, Address = vm.BillingAddress ?? "", CountryNum = p.CountryNum, PostalDestId = p.Id, }); } ctx.RemoveRange(ctx.MemberTelephoneNrs.Where(t => t.MgNr == oldMgNr)); ctx.AddRange(vm.PhoneNrs .Where(input => input.Number != null && input.Number != "") .Select((input, i) => new MemberTelNr { MgNr = m.MgNr, Nr = i + 1, Type = input.Type == -1 ? (input.Number!.StartsWith("+43 ") && input.Number![4] == '6' ? "mobile" : "landline") : vm.PhoneNrTypes[input.Type].Key, Number = input.Number!, Comment = input.Comment, })); ctx.RemoveRange(ctx.MemberEmailAddrs.Where(e => e.MgNr == oldMgNr)); ctx.AddRange(vm.EmailAddresses .Where(input => input != null && input != "") .Select((input, i) => new MemberEmailAddr { MgNr = m.MgNr, Nr = i + 1, Address = input!, Comment = null, })); await ctx.SaveChangesAsync(); if (vm.TransferPredecessorAreaComs is int year && m.PredecessorMgNr is int predecessor) { var areaComs = await ctx.AreaCommitments .Where(c => c.MgNr == predecessor && (c.YearTo == null || c.YearTo >= year)) .ToListAsync(); var fbNr = await ctx.NextFbNr(); ctx.AddRange(areaComs.Select((c, i) => new AreaCom { FbNr = fbNr + i, MgNr = m.MgNr, VtrgId = c.VtrgId, CultId = c.CultId, Area = c.Area, KgNr = c.KgNr, GstNr = c.GstNr, RdNr = c.RdNr, YearFrom = vm.MaintainAreaComYearTo ? c.YearFrom : year, YearTo = c.YearTo, })); foreach (var ac in areaComs) ac.YearTo = year - 1; ctx.UpdateRange(areaComs); await ctx.SaveChangesAsync(); } vm.TransferPredecessorAreaComs = null; if (vm.CancelAreaComs is int yearTo) { var areaComs = await ctx.AreaCommitments .Where(c => c.MgNr == m.MgNr && (c.YearTo == null || c.YearTo > yearTo)) .ToListAsync(); foreach (var ac in areaComs) ac.YearTo = yearTo; ctx.UpdateRange(areaComs); await ctx.SaveChangesAsync(); } vm.CancelAreaComs = null; if (newMgNr != m.MgNr) { await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}"); } } App.HintContextChange(); return newMgNr; } } }