838 lines
41 KiB
C#
838 lines
41 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 async Task RefreshInputs(bool validate = false) {
|
|
ClearInputStates();
|
|
if (ViewModel.SelectedMember is Member m) {
|
|
EditMemberButton.IsEnabled = true;
|
|
DeleteMemberButton.IsEnabled = true;
|
|
await 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 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 };
|
|
i.SetBinding(IsEnabledProperty, new Binding() { Path = new("IsMemberSelected") });
|
|
var show = new MenuItem { Header = "...anzeigen (PDF)" };
|
|
show.Click += Menu_DeliveryConfirmation_Show_Click;
|
|
i.Items.Add(show);
|
|
var pdf = new MenuItem { Header = "...speichern... (PDF)" };
|
|
pdf.Click += Menu_DeliveryConfirmation_Email_Click;
|
|
i.Items.Add(pdf);
|
|
var print = new MenuItem { Header = "...drucken" };
|
|
print.Click += Menu_DeliveryConfirmation_Print_Click;
|
|
i.Items.Add(print);
|
|
var email = new MenuItem { Header = "...per E-Mail schicken" };
|
|
email.Click += Menu_DeliveryConfirmation_Email_Click;
|
|
email.SetBinding(IsEnabledProperty, new Binding() { Path = new("MemberCanSendEmail") });
|
|
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 };
|
|
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)" };
|
|
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.SetBinding(IsEnabledProperty, new Binding { Path = new("MemberCanSendEmail") });
|
|
email.Click += Menu_CreditNote_Email_Click;
|
|
i2.Items.Add(email);
|
|
i1.Items.Add(i2);
|
|
}
|
|
Menu_CreditNote.Items.Add(i1);
|
|
}
|
|
|
|
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 async void MemberList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
|
await 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 {
|
|
using (var ctx = new AppDbContext()) {
|
|
var l = (await ctx.Members.FindAsync(m.MgNr))!;
|
|
if (d.DeletePaymentData) {
|
|
ctx.RemoveRange(l.Credits);
|
|
}
|
|
if (d.DeleteDeliveries) {
|
|
ctx.RemoveRange(l.Deliveries);
|
|
}
|
|
if (d.DeleteAreaComs) {
|
|
ctx.RemoveRange(l.AreaCommitments);
|
|
}
|
|
ctx.Remove(l);
|
|
await ctx.SaveChangesAsync();
|
|
}
|
|
await App.HintContextChange();
|
|
} 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) {
|
|
int? mgnr = null;
|
|
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);
|
|
}
|
|
IsEditing = false;
|
|
IsCreating = false;
|
|
MemberList.IsEnabled = true;
|
|
HideSaveResetCancelButtons();
|
|
ShowNewEditDeleteButtons();
|
|
LockInputs();
|
|
UpdateContactInfoVisibility();
|
|
ViewModel.EnableSearchInputs = true;
|
|
FinishInputFilling();
|
|
await RefreshList();
|
|
await 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) {
|
|
await RefreshInputs();
|
|
} else if (IsCreating) {
|
|
ClearInputs();
|
|
await InitInputs();
|
|
}
|
|
UpdateButtons();
|
|
}
|
|
|
|
private async void CancelButton_Click(object sender, RoutedEventArgs evt) {
|
|
IsEditing = false;
|
|
IsCreating = false;
|
|
MemberList.IsEnabled = true;
|
|
ViewModel.TransferPredecessorAreaComs = null;
|
|
ViewModel.CancelAreaComs = null;
|
|
HideSaveResetCancelButtons();
|
|
ShowNewEditDeleteButtons();
|
|
await 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;
|
|
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;
|
|
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;
|
|
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 async Task FillInputs(Member m) {
|
|
ClearOriginalValues();
|
|
ClearDefaultValues();
|
|
await 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;
|
|
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) {
|
|
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();
|
|
}
|
|
}
|
|
}
|