Files
elwig/Elwig/Windows/MemberAdminWindow.xaml.cs
Lorenz Stechauner f4fa549130
All checks were successful
Test / Run tests (push) Successful in 2m15s
Windows: Add icons on Buttons and MenuItems
2024-11-10 10:58:44 +01:00

877 lines
43 KiB
C#

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Elwig.Helpers;
using Elwig.Models.Entities;
using System.Threading.Tasks;
using Elwig.Documents;
using System.Diagnostics;
using Elwig.Dialogs;
using Elwig.Services;
using Elwig.ViewModels;
using System.Windows.Data;
namespace Elwig.Windows {
public partial class MemberAdminWindow : AdministrationWindow {
public MemberAdminViewModel ViewModel => (MemberAdminViewModel)DataContext;
private readonly (ComboBox Type, TextBox Number, TextBox Comment)[] PhoneNrInputs;
private readonly (Label Label, TextBox Address)[] EmailAddressInputs;
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(MemberAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
private readonly RoutedCommand CtrlL = new("CtrlL", typeof(MemberAdminWindow), [new KeyGesture(Key.L, ModifierKeys.Control)]);
private readonly RoutedCommand CtrlP = new("CtrlP", typeof(MemberAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control)]);
private readonly RoutedCommand CtrlO = new("CtrlO", typeof(MemberAdminWindow), [new KeyGesture(Key.O, ModifierKeys.Control)]);
private readonly RoutedCommand CtrlShiftP = new("CtrlShiftP", typeof(MemberAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control | ModifierKeys.Shift)]);
private readonly RoutedCommand CtrlShiftO = new("CtrlShiftO", typeof(MemberAdminWindow), [new KeyGesture(Key.O, ModifierKeys.Control | ModifierKeys.Shift)]);
public MemberAdminWindow() {
InitializeComponent();
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
CommandBindings.Add(new CommandBinding(CtrlL, Menu_List_SaveActive_Click));
CommandBindings.Add(new CommandBinding(CtrlP, Menu_MemberDataSheet_Show_Click));
CommandBindings.Add(new CommandBinding(CtrlO, Menu_List_ShowActive_Click));
CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_MemberDataSheet_Print_Click));
CommandBindings.Add(new CommandBinding(CtrlShiftO, Menu_List_PrintActive_Click));
ExemptInputs = [
SearchInput, ActiveMemberInput, MemberList,
];
RequiredInputs = [
MgNrInput, GivenNameInput, NameInput,
AddressInput, PlzInput, OrtInput, BillingOrtInput,
BusinessSharesInput, BranchInput, DefaultKgInput
];
EmailAddressInputs = [
(EmailAddress1Label, EmailAddress1Input),
(EmailAddress2Label, EmailAddress2Input),
(EmailAddress3Label, EmailAddress3Input),
(EmailAddress4Label, EmailAddress4Input),
(EmailAddress5Label, EmailAddress5Input),
(EmailAddress6Label, EmailAddress6Input),
(EmailAddress7Label, EmailAddress7Input),
(EmailAddress8Label, EmailAddress8Input),
(EmailAddress9Label, EmailAddress9Input),
];
PhoneNrInputs = [
(PhoneNr1TypeInput, PhoneNr1Input, PhoneNr1CommentInput),
(PhoneNr2TypeInput, PhoneNr2Input, PhoneNr2CommentInput),
(PhoneNr3TypeInput, PhoneNr3Input, PhoneNr3CommentInput),
(PhoneNr4TypeInput, PhoneNr4Input, PhoneNr4CommentInput),
(PhoneNr5TypeInput, PhoneNr5Input, PhoneNr5CommentInput),
(PhoneNr6TypeInput, PhoneNr6Input, PhoneNr6CommentInput),
(PhoneNr7TypeInput, PhoneNr7Input, PhoneNr7CommentInput),
(PhoneNr8TypeInput, PhoneNr8Input, PhoneNr8CommentInput),
(PhoneNr9TypeInput, PhoneNr9Input, PhoneNr9CommentInput),
];
InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
SearchInput.TextChanged -= SearchInput_TextChanged;
ViewModel.MemberListOrderByMgNr = false;
ViewModel.MemberListOrderByName = false;
ViewModel.MemberListOrderByOrt = false;
switch (App.Client.OrderingMemberList) {
case 0: ViewModel.MemberListOrderByMgNr = true; break;
case 1: ViewModel.MemberListOrderByName = true; break;
case 2: ViewModel.MemberListOrderByOrt = true; break;
}
Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null;
Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null;
}
private void Window_Loaded(object sender, RoutedEventArgs evt) {
ViewModel.ShowOnlyActiveMembers = true;
UpdateContactInfoVisibility();
LockInputs();
}
public void FocusMember(int mgnr) {
if (IsEditing || IsCreating) return;
var item = ViewModel.Members.FirstOrDefault(m => m.MgNr == mgnr);
if (item == null) {
using var ctx = new AppDbContext();
var m = ctx.Members.Find(mgnr);
if (m == null) return;
if (ViewModel.SearchQuery?.Length > 0) {
ViewModel.SearchQuery = "";
}
if (!m.IsActive) {
ViewModel.ShowOnlyActiveMembers = false;
}
App.MainDispatcher.BeginInvoke(async () => {
await Task.Delay(500);
FocusMember(mgnr);
});
} else {
ControlUtils.SelectItem(MemberList, item);
}
}
private async Task RefreshList(bool updateSort = false) {
using var ctx = new AppDbContext();
var (_, memberQuery, filter) = await ViewModel.GetFilters(ctx);
var members = await memberQuery
.Include(m => m.Branch)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Country)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
.ToListAsync();
if (filter.Count > 0 && members.Count > 0) {
var dict = members.AsParallel()
.ToDictionary(m => m, m => m.SearchScore(filter))
.OrderByDescending(a => a.Value)
.ThenBy(a => a.Key.Name)
.ThenBy(a => a.Key.GivenName)
.ThenBy(a => a.Key.MgNr);
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
members = dict
.Where(a => a.Value > threshold)
.Select(a => a.Key)
.ToList();
} else {
members = members
.OrderBy(m => m.Name)
.ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr)
.ToList();
}
ControlUtils.RenewItemsSource(MemberList, members,
MemberList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
if (updateSort && MemberList.SelectedItem != null)
MemberList.ScrollIntoView(MemberList.SelectedItem);
ViewModel.StatusMembers = $"{members.Count:N0} ({await ctx.Members.CountAsync():N0})";
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.BusinessShares):N0} ({await ctx.Members.SumAsync(m => m.BusinessShares):N0})";
}
private void RefreshInputs(bool validate = false) {
ClearInputStates();
if (ViewModel.SelectedMember is Member m) {
EditMemberButton.IsEnabled = true;
DeleteMemberButton.IsEnabled = true;
FillInputs(m);
} else {
EditMemberButton.IsEnabled = false;
DeleteMemberButton.IsEnabled = false;
ClearOriginalValues();
ClearDefaultValues();
ClearInputs(validate);
ClearInputStates();
}
GC.Collect();
}
private async Task InitInputs() {
ClearOriginalValues();
ClearDefaultValues();
await ViewModel.InitInputs();
SetDefaultValue(MgNrInput);
SetDefaultValue(EntryDateInput);
SetDefaultValue(ActiveInput);
ValidateRequiredInputs();
}
protected override async Task OnRenewContext(AppDbContext ctx) {
await base.OnRenewContext(ctx);
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 font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets");
MenuItem? temp = null;
var seasons = await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync();
Menu_DeliveryConfirmation.Items.Clear();
foreach (var s in seasons) {
var i = new MenuItem {
Header = $"Saison {s.Year}...",
Tag = s.Year,
Icon = s.Year == seasons[0].Year ? new TextBlock { FontSize = 16, Text = "\uE734", FontFamily = font } : null,
};
i.SetBinding(IsEnabledProperty, new Binding() { Path = new("IsMemberSelected") });
var show = new MenuItem { Header = "...anzeigen (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uE8FF", FontFamily = font } };
show.Click += Menu_DeliveryConfirmation_Show_Click;
i.Items.Add(show);
var pdf = new MenuItem { Header = "...speichern... (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uEA90", FontFamily = font } };
pdf.Click += Menu_DeliveryConfirmation_SavePdf_Click;
i.Items.Add(pdf);
var print = new MenuItem { Header = "...drucken", Icon = new TextBlock { FontSize = 16, Text = "\uE749", FontFamily = font } };
print.Click += Menu_DeliveryConfirmation_Print_Click;
i.Items.Add(print);
var email = new MenuItem { Header = "...per E-Mail schicken", Icon = new TextBlock { FontSize = 16, Text = "\uE89C", FontFamily = font } };
email.Click += Menu_DeliveryConfirmation_Email_Click;
email.SetBinding(IsEnabledProperty, new Binding() { Path = new("MemberCanSendEmail") });
i.Items.Add(email);
var decade = s.Year / 10;
if (seasons[0].Year / 10 != decade) {
if (temp == null || !temp.Header.ToString()!.Contains($"{decade}0er")) {
temp = new MenuItem { Header = $"Saisons {decade}0er..." };
Menu_DeliveryConfirmation.Items.Add(temp);
}
temp?.Items.Add(i);
} else {
Menu_DeliveryConfirmation.Items.Add(i);
}
}
temp = null;
Menu_CreditNote.Items.Clear();
foreach (var s in seasons) {
var i1 = new MenuItem {
Header = $"Saison {s.Year}...",
Tag = s.Year,
IsEnabled = MemberList.SelectedItem != null,
Icon = s.Year == seasons[0].Year ? new TextBlock { FontSize = 16, Text = "\uE734", FontFamily = font } : null,
};
i1.SetBinding(IsEnabledProperty, new Binding() { Path = new($"MemberHasDeliveries[{s.Year}]") });
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)", Icon = new TextBlock { FontSize = 16, Text = "\uE8FF", FontFamily = font } };
show.Click += Menu_CreditNote_Show_Click;
i2.Items.Add(show);
var pdf = new MenuItem { Header = "...speichern... (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uEA90", FontFamily = font } };
pdf.Click += Menu_CreditNote_SavePdf_Click;
i2.Items.Add(pdf);
var print = new MenuItem { Header = "...drucken", Icon = new TextBlock { FontSize = 16, Text = "\uE749", FontFamily = font } };
print.Click += Menu_CreditNote_Print_Click;
i2.Items.Add(print);
var email = new MenuItem { Header = "...per E-Mail schicken", Icon = new TextBlock { FontSize = 16, Text = "\uE89C", FontFamily = font } };
email.SetBinding(IsEnabledProperty, new Binding { Path = new("MemberCanSendEmail") });
email.Click += Menu_CreditNote_Email_Click;
i2.Items.Add(email);
i1.Items.Add(i2);
}
var decade = s.Year / 10;
if (seasons[0].Year / 10 != decade) {
if (temp == null || !temp.Header.ToString()!.Contains($"{decade}0er")) {
temp = new MenuItem { Header = $"Saisons {decade}0er..." };
Menu_CreditNote.Items.Add(temp);
}
temp?.Items.Add(i1);
} else {
Menu_CreditNote.Items.Add(i1);
}
}
temp = null;
await RefreshList();
var (s1, s2) = ('\u2007', '\u202f');
var mA = $"{await ctx.Members.CountAsync(m => m.IsActive):N0}";
var mI = $"{await ctx.Members.CountAsync(m => !m.IsActive):N0}";
var mT = $"{await ctx.Members.CountAsync():N0}";
var mM = Math.Max(mA.Length, Math.Max(mI.Length, mT.Length));
var mS = mM > 3;
if (mS) mM--;
ViewModel.StatusMembersToolTip =
$"{new string(s1, Math.Max(0, mM - mA.Length))}{(mS && mA.Length < 4 ? s2 : "")}{mA} aktive Mitglieder\n" +
$"{new string(s1, Math.Max(0, mM - mI.Length))}{(mS && mI.Length < 4 ? s2 : "")}{mI} nicht aktive Mitglieder\n" +
$"{new string(s1, Math.Max(0, mM - mT.Length))}{(mS && mT.Length < 4 ? s2 : "")}{mT} Mitglieder gesamt";
var bA = $"{await ctx.Members.Where(m => m.IsActive).SumAsync(m => m.BusinessShares):N0}";
var bI = $"{await ctx.Members.Where(m => !m.IsActive).SumAsync(m => m.BusinessShares):N0}";
var bT = $"{await ctx.Members.SumAsync(m => m.BusinessShares):N0}";
var bM = Math.Max(bA.Length, Math.Max(bI.Length, bT.Length));
var bS = bM > 3;
if (bS) bM--;
ViewModel.StatusBusinessSharesToolTip =
$"{new string(s1, Math.Max(0, bM - bA.Length))}{(bS && bA.Length < 4 ? s2 : "")}{bA} Geschäftsanteile von aktiven Mitgliedern\n" +
$"{new string(s1, Math.Max(0, bM - bI.Length))}{(bS && bI.Length < 4 ? s2 : "")}{bI} Geschäftsanteile von nicht aktiven Mitgliedern\n" +
$"{new string(s1, Math.Max(0, bM - bT.Length))}{(bS && bT.Length < 4 ? s2 : "")}{bT} Geschäftsanteile gesamt";
}
private void SetPhoneNrInputVisible(int nr, bool visible, int? position = null) {
var inputs = PhoneNrInputs[nr];
if (position is int p) {
var mt = 10 + p * 30;
inputs.Type.Margin = new(6, mt, 5, 0);
inputs.Number.Margin = new(0, mt, 5, 0);
inputs.Comment.Margin = new(0, mt, 10, 0);
}
var vis = visible ? Visibility.Visible : Visibility.Hidden;
inputs.Type.Visibility = vis;
inputs.Number.Visibility = vis;
inputs.Comment.Visibility = vis;
}
private void SetEmailAddressInputVisible(int nr, bool visible, int? position = null) {
var inputs = EmailAddressInputs[nr];
if (position is int p) {
var mt = 10 + p * 30;
inputs.Label.Margin = new(10, mt, 0, 0);
inputs.Address.Margin = new(0, mt, 10, 0);
}
var vis = visible ? Visibility.Visible : Visibility.Hidden;
inputs.Label.Visibility = vis;
inputs.Address.Visibility = vis;
}
private void MemberList_SelectionChanged(object sender, RoutedEventArgs evt) {
RefreshInputs();
if (MemberList.SelectedItem is Member m) {
Menu_Export_ExportSelected.IsEnabled = !IsEditing && !IsCreating;
Menu_Export_UploadSelected.IsEnabled = !IsEditing && !IsCreating && App.Config.SyncUrl != null;
} else {
Menu_Export_ExportSelected.IsEnabled = false;
Menu_Export_UploadSelected.IsEnabled = false;
}
}
private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) {
await RefreshList();
}
protected override void ShortcutNew() {
if (!NewMemberButton.IsEnabled || NewMemberButton.Visibility != Visibility.Visible)
return;
NewMemberButton_Click(null, null);
}
private async void NewMemberButton_Click(object? sender, RoutedEventArgs? evt) {
IsCreating = true;
MemberList.IsEnabled = false;
ViewModel.SelectedMember = null;
ViewModel.TransferPredecessorAreaComs = null;
ViewModel.CancelAreaComs = null;
HideNewEditDeleteButtons();
ShowSaveResetCancelButtons();
UnlockInputs();
UpdateContactInfoVisibility(true);
await InitInputs();
ViewModel.EnableSearchInputs = false;
}
protected override void ShortcutEdit() {
if (!EditMemberButton.IsEnabled || EditMemberButton.Visibility != Visibility.Visible)
return;
EditMemberButton_Click(null, null);
}
private void EditMemberButton_Click(object? sender, RoutedEventArgs? evt) {
if (ViewModel.SelectedMember == null) return;
IsEditing = true;
MemberList.IsEnabled = false;
ViewModel.TransferPredecessorAreaComs = null;
ViewModel.CancelAreaComs = null;
HideNewEditDeleteButtons();
ShowSaveResetCancelButtons();
UnlockInputs();
UpdateContactInfoVisibility(true);
ViewModel.EnableSearchInputs = false;
}
protected override void ShortcutDelete() {
if (!DeleteMemberButton.IsEnabled || DeleteMemberButton.Visibility != Visibility.Visible)
return;
DeleteMemberButton_Click(null, null);
}
private async void DeleteMemberButton_Click(object? sender, RoutedEventArgs? evt) {
if (ViewModel.SelectedMember is not Member m)
return;
int areaComs = 0, deliveries = 0, credits = 0;
using (var ctx = new AppDbContext()) {
var l = (await ctx.Members.FindAsync(m.MgNr))!;
areaComs = l.AreaCommitments.Count;
deliveries = l.Deliveries.Count;
credits = l.Credits.Count;
}
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits);
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
} catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Mitglied löschen", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
}
}
protected override void ShortcutSave() {
if (!SaveButton.IsEnabled || SaveButton.Visibility != Visibility.Visible)
return;
SaveButton_Click(null, null);
}
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
Mouse.OverrideCursor = Cursors.AppStarting;
SaveButton.IsEnabled = false;
int mgnr;
try {
mgnr = await ViewModel.UpdateMember(ViewModel.SelectedMember?.MgNr);
} catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Mitglied aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null;
}
IsEditing = false;
IsCreating = false;
MemberList.IsEnabled = true;
HideSaveResetCancelButtons();
ShowNewEditDeleteButtons();
LockInputs();
UpdateContactInfoVisibility();
ViewModel.EnableSearchInputs = true;
FinishInputFilling();
await RefreshList();
RefreshInputs();
ViewModel.SearchQuery = "";
if (mgnr is int m)
FocusMember(m);
}
protected override void ShortcutReset() {
if (!ResetButton.IsEnabled || ResetButton.Visibility != Visibility.Visible)
return;
ResetButton_Click(null, null);
}
private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) {
ViewModel.TransferPredecessorAreaComs = null;
ViewModel.CancelAreaComs = null;
if (IsEditing) {
RefreshInputs();
} else if (IsCreating) {
ClearInputs();
await InitInputs();
}
UpdateButtons();
}
private void CancelButton_Click(object sender, RoutedEventArgs evt) {
IsEditing = false;
IsCreating = false;
MemberList.IsEnabled = true;
ViewModel.TransferPredecessorAreaComs = null;
ViewModel.CancelAreaComs = null;
HideSaveResetCancelButtons();
ShowNewEditDeleteButtons();
RefreshInputs();
LockInputs();
UpdateContactInfoVisibility();
ViewModel.EnableSearchInputs = true;
}
private void AreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
App.FocusMemberAreaComs(ViewModel.SelectedMember!.MgNr);
}
private void DeliveryButton_Click(object sender, RoutedEventArgs evt) {
App.FocusMemberDeliveries(ViewModel.SelectedMember!.MgNr);
}
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
await RefreshList(true);
}
private void Menu_Contact_Email_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
Utils.MailTo(m.EmailAddresses.Select(a => a.Address));
}
private async void Menu_Contact_Letterhead_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var doc = new Letterhead(m);
await doc.Generate();
if (!App.Config.Debug) {
await doc.Print();
} else {
doc.Show();
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
}
private async void Menu_MemberDataSheet_Show_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
await MemberService.GenerateMemberDataSheet(m, ExportMode.Show);
}
private async void Menu_MemberDataSheet_SavePdf_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
await MemberService.GenerateMemberDataSheet(m, ExportMode.SavePdf);
}
private async void Menu_MemberDataSheet_Print_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
await MemberService.GenerateMemberDataSheet(m, ExportMode.Print);
}
private async void Menu_MemberDataSheet_Email_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Stammdatenblatt verschicken",
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return;
await MemberService.GenerateMemberDataSheet(m, ExportMode.Email);
}
private async void Menu_DeliveryConfirmation_Show_Click(object sender, RoutedEventArgs evt) {
var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
if (ViewModel.SelectedMember is not Member m || year == null)
return;
await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.Show);
}
private async void Menu_DeliveryConfirmation_SavePdf_Click(object sender, RoutedEventArgs evt) {
var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
if (ViewModel.SelectedMember is not Member m || year == null)
return;
await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.SavePdf);
}
private async void Menu_DeliveryConfirmation_Print_Click(object sender, RoutedEventArgs evt) {
var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
if (ViewModel.SelectedMember is not Member m || year == null)
return;
await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.Print);
}
private async void Menu_DeliveryConfirmation_Email_Click(object sender, RoutedEventArgs evt) {
var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
if (ViewModel.SelectedMember is not Member m || year == null)
return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Anlieferungsbestätigung verschicken",
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return;
await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.Email);
}
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 (ViewModel.SelectedMember is not Member m || year == null || avnr == null)
return;
await MemberService.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 (ViewModel.SelectedMember is not Member m || year == null || avnr == null)
return;
await MemberService.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 (ViewModel.SelectedMember is not Member m || year == null || avnr == null)
return;
await MemberService.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 (ViewModel.SelectedMember is not Member m || year == null || avnr == null)
return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Traubengutschrift verschicken",
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return;
await MemberService.GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Email);
}
private async void Menu_List_SaveActive_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.AllActive, ExportMode.SaveList);
private async void Menu_List_ShowActive_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.AllActive, ExportMode.Show);
private async void Menu_List_SavePdfActive_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.AllActive, ExportMode.SavePdf);
private async void Menu_List_PrintActive_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.AllActive, ExportMode.Print);
private async void Menu_List_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.SaveList);
private async void Menu_List_ShowFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.Show);
private async void Menu_List_SavePdfFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.SavePdf);
private async void Menu_List_PrintFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.Print);
private async void Menu_List_SaveAll_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.SaveList);
private async void Menu_List_ShowAll_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.Show);
private async void Menu_List_SavePdfAll_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.SavePdf);
private async void Menu_List_PrintAll_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.Print);
private async void Menu_Export_ExportAll_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.Export);
private async void Menu_Export_ExportFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.Export);
private async void Menu_Export_ExportSelected_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateMemberList(MemberService.ExportSubject.Selected, ExportMode.Export);
private async void Menu_Export_UploadAll_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) return;
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.Upload);
}
private async void Menu_Export_UploadFilters_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) return;
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.Upload);
}
private async void Menu_Export_UploadSelected_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) return;
await ViewModel.GenerateMemberList(MemberService.ExportSubject.Selected, ExportMode.Upload);
}
private async void Menu_List_Order_Click(object sender, RoutedEventArgs evt) {
Menu_List.IsSubmenuOpen = true;
if (sender == Menu_List_OrderMgNr) {
App.Client.OrderingMemberList = 0;
ViewModel.MemberListOrderByMgNr = true;
ViewModel.MemberListOrderByName = false;
ViewModel.MemberListOrderByOrt = false;
} else if (sender == Menu_List_OrderName) {
App.Client.OrderingMemberList = 1;
ViewModel.MemberListOrderByMgNr = false;
ViewModel.MemberListOrderByName = true;
ViewModel.MemberListOrderByOrt = false;
} else if (sender == Menu_List_OrderOrt) {
App.Client.OrderingMemberList = 2;
ViewModel.MemberListOrderByMgNr = false;
ViewModel.MemberListOrderByName = false;
ViewModel.MemberListOrderByOrt = true;
}
await App.Client.UpdateValues();
}
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
if (!IsEditing && !IsCreating) {
SearchInput.Focus();
SearchInput.SelectAll();
}
}
private void ShowSaveResetCancelButtons() {
SaveButton.IsEnabled = false;
ResetButton.IsEnabled = false;
CancelButton.IsEnabled = true;
ViewModel.EditingButtonsVisibility = Visibility.Visible;
}
private void HideSaveResetCancelButtons() {
SaveButton.IsEnabled = false;
ResetButton.IsEnabled = false;
CancelButton.IsEnabled = false;
ViewModel.EditingButtonsVisibility = Visibility.Hidden;
}
private void ShowNewEditDeleteButtons() {
NewMemberButton.IsEnabled = true;
EditMemberButton.IsEnabled = ViewModel.SelectedMember != null;
DeleteMemberButton.IsEnabled = ViewModel.SelectedMember != null;
ViewModel.ControlButtonsVisibility = Visibility.Visible;
}
private void HideNewEditDeleteButtons() {
NewMemberButton.IsEnabled = false;
EditMemberButton.IsEnabled = false;
DeleteMemberButton.IsEnabled = false;
ViewModel.ControlButtonsVisibility = Visibility.Hidden;
}
private void UpdateContactInfoVisibility(bool extra = false) {
var m = ViewModel.SelectedMember;
bool lastVisible;
int num = 0;
lastVisible = true;
for (int i = 0; i < EmailAddressInputs.Length; i++) {
var input = EmailAddressInputs[i];
var vis = !string.IsNullOrEmpty(input.Address.Text) || (m?.EmailAddresses.Any(a => a.Nr - 1 == i) ?? false);
var cVis = vis || (extra && lastVisible);
SetEmailAddressInputVisible(i, cVis, cVis ? num++ : null);
lastVisible = vis;
}
lastVisible = true;
for (int i = 0; i < PhoneNrInputs.Length; i++) {
var input = PhoneNrInputs[i];
var vis = !string.IsNullOrEmpty(input.Number.Text) || (m?.TelephoneNumbers.Any(n => n.Nr - 1 == i) ?? false);
var cVis = vis || (extra && lastVisible);
SetPhoneNrInputVisible(i, cVis, cVis ? num++ : null);
lastVisible = vis;
}
}
private void FillInputs(Member m) {
ClearOriginalValues();
ClearDefaultValues();
ViewModel.FillInputs(m);
UpdateContactInfoVisibility(IsEditing || IsCreating);
FinishInputFilling();
}
new protected void ClearInputs(bool validate = false) {
ViewModel.ClearInputs();
base.ClearInputs(validate);
}
override protected void UpdateButtons() {
if (!IsEditing && !IsCreating) return;
bool ch = HasChanged, v = IsValid;
ResetButton.IsEnabled = ch;
SaveButton.IsEnabled = v && ch;
}
protected void InputTextChanged(TextBox input, Func<TextBox, bool, Member?, ValidationResult> checker) {
InputTextChanged(input, checker(input, SenderIsRequired(input), ViewModel.SelectedMember));
}
protected void InputLostFocus(TextBox input, Func<TextBox, bool, Member?, ValidationResult> checker, string? msg = null) {
InputLostFocus(input, checker(input, SenderIsRequired(input), ViewModel.SelectedMember), msg);
}
private void MgNrInput_TextChanged(object sender, RoutedEventArgs evt) {
InputTextChanged((TextBox)sender, Validator.CheckNewMgNr);
}
private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
InputLostFocus((TextBox)sender, Validator.CheckNewMgNr);
}
private void PredecessorMgNrInput_TextChanged(object sender, RoutedEventArgs evt) {
InputTextChanged((TextBox)sender, Validator.CheckPredecessorMgNr);
}
private async void PredecessorMgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
var valid = InputLostFocus((TextBox)sender, Validator.CheckPredecessorMgNr);
if (valid && ViewModel.PredecessorMgNr is int mgnr && (IsEditing || IsCreating)) {
if (ViewModel.MgNr == mgnr)
return;
using var ctx = new AppDbContext();
var areaComs = await ctx.AreaCommitments
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
.ToListAsync();
if (areaComs.Count == 0)
return;
var oldMember = (await ctx.Members.FindAsync(mgnr))!;
var newName = $"{ViewModel.Name?.Replace('ß', 'ẞ').ToUpper()} " +
$"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" +
$"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" +
$"{ViewModel.Suffix}{(!string.IsNullOrEmpty(ViewModel.Suffix) ? " " : "")}";
var d = new AreaComDialog(oldMember.AdministrativeName, newName, areaComs.Count, areaComs.Sum(c => c.Area));
if (d.ShowDialog() != true)
return;
ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason;
ViewModel.MaintainAreaComYearTo = d.MaintainYearTo;
if (IsEditing)
SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save
UpdateButtons();
}
}
private new void EmailAddressInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (sender == EmailAddress1Input && ViewModel.ContactViaEmail) {
InputTextChanged((TextBox)sender, Validator.CheckEmailAddress((TextBox)sender, true));
} else {
base.EmailAddressInput_TextChanged(sender, evt);
}
UpdateContactInfoVisibility(IsEditing || IsCreating);
}
private new void PhoneNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
base.PhoneNrInput_TextChanged(sender, evt);
UpdateContactInfoVisibility(IsEditing || IsCreating);
}
private void ContactEmailInput_Changed(object sender, RoutedEventArgs evt) {
CheckBox_Changed(sender, evt);
EmailAddressInput_TextChanged(EmailAddress1Input, new TextChangedEventArgs(evt.RoutedEvent, UndoAction.None));
}
private void KgDetailsButton_Click(object sender, RoutedEventArgs evt) {
if (DefaultKgInput.SelectedItem is AT_Kg kg) {
App.FocusOriginHierarchyKg(kg.KgNr);
} else {
App.FocusOriginHierarchy();
}
}
private void OrganicButton_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
var url = "https://www.easy-cert.com/htm/suchergebnis.htm?" +
//$"CustomerNumber={m.LfbisNr}&" +
$"Name={(m.BillingAddress?.FullName ?? m.FullName).Replace(' ', '+')}&" +
$"PostalCode={(m.BillingAddress?.PostalDest ?? m.PostalDest).AtPlz?.Plz}";
Process.Start(new ProcessStartInfo(url) {
UseShellExecute = true,
});
}
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m || m.PredecessorMgNr == null) return;
FocusMember((int)m.PredecessorMgNr);
}
private async void ActiveInput_Changed(object sender, RoutedEventArgs evt) {
if (MemberList.SelectedItem is not Member m)
return;
if ((IsEditing || IsCreating) && ViewModel.IsActive == false && ViewModel.MgNr is int mgnr) {
using var ctx = new AppDbContext();
var areaComs = await ctx.AreaCommitments
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
.ToListAsync();
if (areaComs.Count > 0) {
var d = new AreaComDialog(m.AdministrativeName, areaComs.Count, areaComs.Sum(c => c.Area));
if (d.ShowDialog() == true) {
ViewModel.CancelAreaComs = d.CancelSeason;
}
}
}
CheckBox_Changed(sender, evt);
}
private void JuridicalPersonInput_Changed(object sender, RoutedEventArgs evt) {
CheckBox_Changed(sender, evt);
if (ViewModel.IsJuridicalPerson) {
ViewModel.PersonalNameVisibility = Visibility.Hidden;
ViewModel.JuridicalNameVisibility = Visibility.Visible;
NameInput.Margin = new(0, 40, 10, 0);
NameInput.SetValue(Grid.ColumnSpanProperty, 3);
BirthdayLabel.Content = "Gründung:";
DeceasedInput.Content = "Aufgelöst";
} else {
ViewModel.JuridicalNameVisibility = Visibility.Hidden;
ViewModel.PersonalNameVisibility = Visibility.Visible;
NameInput.Margin = new(0, 70, 0, 0);
NameInput.SetValue(Grid.ColumnSpanProperty, 1);
BirthdayLabel.Content = "Geburtstag:";
DeceasedInput.Content = "Verstorben";
}
ValidateRequiredInputs();
UpdateButtons();
}
}
}