diff --git a/Elwig/Windows/MemberAdminWindow.xaml b/Elwig/Windows/MemberAdminWindow.xaml index 1911024..9bca74a 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml +++ b/Elwig/Windows/MemberAdminWindow.xaml @@ -71,6 +71,16 @@ + + + + + + diff --git a/Elwig/Windows/MemberAdminWindow.xaml.cs b/Elwig/Windows/MemberAdminWindow.xaml.cs index 082c65f..c5328a0 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml.cs +++ b/Elwig/Windows/MemberAdminWindow.xaml.cs @@ -319,9 +319,10 @@ namespace Elwig.Windows { ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync()); ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync()); + var seasons = await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync(); Menu_DeliveryConfirmation.Items.Clear(); - foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) { - var i = new MenuItem { Header = $"Saison {s.Year}...", IsEnabled = MemberList.SelectedItem != null }; + foreach (var s in seasons) { + var i = new MenuItem { Header = $"Saison {s.Year}...", Tag = s.Year, IsEnabled = MemberList.SelectedItem != null }; var show = new MenuItem { Header = "...anzeigen (PDF)" }; show.Click += Menu_DeliveryConfirmation_Show_Click; i.Items.Add(show); @@ -331,10 +332,31 @@ namespace Elwig.Windows { var print = new MenuItem { Header = "...drucken" }; print.Click += Menu_DeliveryConfirmation_Print_Click; i.Items.Add(print); - Menu_DeliveryConfirmation.Items.Add(i); var email = new MenuItem { Header = "...per E-Mail schicken" }; email.Click += Menu_DeliveryConfirmation_Email_Click; i.Items.Add(email); + Menu_DeliveryConfirmation.Items.Add(i); + } + Menu_CreditNote.Items.Clear(); + foreach (var s in seasons) { + var i1 = new MenuItem { Header = $"Saison {s.Year}...", Tag = s.Year, IsEnabled = MemberList.SelectedItem != null }; + foreach (var v in s.PaymentVariants.OrderByDescending(v => v.AvNr)) { + var i2 = new MenuItem { Header = $"...{v.Name}...", Tag = v.AvNr }; + var show = new MenuItem { Header = "...anzeigen (PDF)" }; + show.Click += Menu_CreditNote_Show_Click; + i2.Items.Add(show); + var pdf = new MenuItem { Header = "...speichern... (PDF)" }; + pdf.Click += Menu_CreditNote_Email_Click; + i2.Items.Add(pdf); + var print = new MenuItem { Header = "...drucken" }; + print.Click += Menu_CreditNote_Print_Click; + i2.Items.Add(print); + var email = new MenuItem { Header = "...per E-Mail schicken" }; + email.Click += Menu_CreditNote_Email_Click; + i2.Items.Add(email); + i1.Items.Add(i2); + } + Menu_CreditNote.Items.Add(i1); } await RefreshMemberList(); @@ -627,31 +649,31 @@ namespace Elwig.Windows { } private async void Menu_DeliveryConfirmation_Show_Click(object sender, RoutedEventArgs evt) { - var season = ((sender as MenuItem)?.Parent as MenuItem)?.Header?.ToString()?.Split(' ')[^1].Split('.')[0]; - if (MemberList.SelectedItem is not Member m || season == null || !int.TryParse(season, out var s)) + var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null) return; - await GenerateDeliveryConfirmation(m, s, ExportMode.Show); + await GenerateDeliveryConfirmation(m, (int)year, ExportMode.Show); } private async void Menu_DeliveryConfirmation_SavePdf_Click(object sender, RoutedEventArgs evt) { - var season = ((sender as MenuItem)?.Parent as MenuItem)?.Header?.ToString()?.Split(' ')[^1].Split('.')[0]; - if (MemberList.SelectedItem is not Member m || season == null || !int.TryParse(season, out var s)) + var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null) return; - await GenerateDeliveryConfirmation(m, s, ExportMode.SavePdf); + await GenerateDeliveryConfirmation(m, (int)year, ExportMode.SavePdf); } private async void Menu_DeliveryConfirmation_Print_Click(object sender, RoutedEventArgs evt) { - var season = ((sender as MenuItem)?.Parent as MenuItem)?.Header?.ToString()?.Split(' ')[^1].Split('.')[0]; - if (MemberList.SelectedItem is not Member m || season == null || !int.TryParse(season, out var s)) + var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null) return; - await GenerateDeliveryConfirmation(m, s, ExportMode.Print); + await GenerateDeliveryConfirmation(m, (int)year, ExportMode.Print); } private async void Menu_DeliveryConfirmation_Email_Click(object sender, RoutedEventArgs evt) { - var season = ((sender as MenuItem)?.Parent as MenuItem)?.Header?.ToString()?.Split(' ')[^1].Split('.')[0]; - if (MemberList.SelectedItem is not Member m || season == null || !int.TryParse(season, out var s)) + var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null) return; - await GenerateDeliveryConfirmation(m, s, ExportMode.Email); + await GenerateDeliveryConfirmation(m, (int)year, ExportMode.Email); } private static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) { @@ -672,6 +694,57 @@ namespace Elwig.Windows { Mouse.OverrideCursor = null; } + private async void Menu_CreditNote_Show_Click(object sender, RoutedEventArgs evt) { + var year = (int?)(((sender as MenuItem)?.Parent as MenuItem)?.Parent as MenuItem)?.Tag; + var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null || avnr == null) + return; + await GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Show); + } + + private async void Menu_CreditNote_SavePdf_Click(object sender, RoutedEventArgs evt) { + var year = (int?)(((sender as MenuItem)?.Parent as MenuItem)?.Parent as MenuItem)?.Tag; + var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null || avnr == null) + return; + await GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.SavePdf); + } + + private async void Menu_CreditNote_Print_Click(object sender, RoutedEventArgs evt) { + var year = (int?)(((sender as MenuItem)?.Parent as MenuItem)?.Parent as MenuItem)?.Tag; + var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null || avnr == null) + return; + await GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Print); + } + + private async void Menu_CreditNote_Email_Click(object sender, RoutedEventArgs evt) { + var year = (int?)(((sender as MenuItem)?.Parent as MenuItem)?.Parent as MenuItem)?.Tag; + var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; + if (MemberList.SelectedItem is not Member m || year == null || avnr == null) + return; + await GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Email); + } + + private 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; + } + private async void Menu_List_SaveActive_Click(object sender, RoutedEventArgs evt) { await GenerateMemberList(0, ExportMode.SaveList); } private async void Menu_List_ShowActive_Click(object sender, RoutedEventArgs evt) { await GenerateMemberList(0, ExportMode.Show); } private async void Menu_List_SavePdfActive_Click(object sender, RoutedEventArgs evt) { await GenerateMemberList(0, ExportMode.SavePdf); } @@ -1063,12 +1136,18 @@ namespace Elwig.Windows { ContactPostalInput.IsChecked = m.ContactViaPost; ContactEmailInput.IsChecked = m.ContactViaEmail; + Dictionary delivieries; using (var ctx = new AppDbContext()) { var d1 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason && d.MgNr == m.MgNr); var d2 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason - 1 && d.MgNr == m.MgNr); StatusDeliveriesLastSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason - 1}): {d2.Count():N0} ({d2.Sum(d => d.Parts.Count):N0}), {d2.SelectMany(d => d.Parts).Sum(p => p.Weight):N0} kg"; StatusDeliveriesThisSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason}): {d1.Count():N0} ({d1.Sum(d => d.Parts.Count):N0}), {d1.SelectMany(d => d.Parts).Sum(p => p.Weight):N0} kg"; StatusAreaCommitment.Text = $"Gebundene Fläche: {m.ActiveAreaCommitments(ctx).Select(c => c.Area).Sum():N0} m²"; + delivieries = ctx.Deliveries + .Where(d => d.MgNr == m.MgNr) + .SelectMany(d => d.Parts) + .GroupBy(d => d.Year) + .ToDictionary(g => g.Key, g => g.Sum(d => d.Weight)); } Menu_Contact_Email.IsEnabled = m.EmailAddresses.Count > 0; @@ -1081,6 +1160,13 @@ namespace Elwig.Windows { i.IsEnabled = true; (i.Items[^1] as MenuItem)!.IsEnabled = App.Config.Smtp != null && m.EmailAddresses.Count > 0; } + foreach (var i in Menu_CreditNote.Items.Cast()) { + var year = (int)i.Tag; + i.IsEnabled = delivieries.GetValueOrDefault(year, 0) > 0; + foreach (var v in i.Items.Cast()) { + (v.Items[^1] as MenuItem)!.IsEnabled = App.Config.Smtp != null && m.EmailAddresses.Count > 0; + } + } FinishInputFilling(); } @@ -1095,6 +1181,9 @@ namespace Elwig.Windows { foreach (var i in Menu_DeliveryConfirmation.Items.Cast()) { i.IsEnabled = false; } + foreach (var i in Menu_CreditNote.Items.Cast()) { + i.IsEnabled = false; + } MemberReferenceButton.IsEnabled = false; StatusDeliveriesLastSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason - 1}): -"; StatusDeliveriesThisSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason}): -";