1027 lines
52 KiB
C#
1027 lines
52 KiB
C#
using Elwig.Dialogs;
|
|
using Elwig.Documents;
|
|
using Elwig.Helpers;
|
|
using Elwig.Models.Entities;
|
|
using Elwig.Services;
|
|
using Elwig.ViewModels;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
|
|
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));
|
|
List<Control> exempt = [
|
|
SearchInput, ActiveMemberInput, MemberList,
|
|
];
|
|
if (App.Client.EnableMemberHistory) {
|
|
exempt.AddRange([BusinessShares1Input, BusinessShares2Input, BusinessShares3Input]);
|
|
BusinessShares1Input.IsReadOnly = true;
|
|
BusinessShares2Input.IsReadOnly = true;
|
|
BusinessShares3Input.IsReadOnly = true;
|
|
}
|
|
ExemptInputs = [.. exempt];
|
|
RequiredInputs = [
|
|
MgNrInput, GivenNameInput, NameInput,
|
|
AddressInput, PlzInput, OrtInput, BillingOrtInput,
|
|
BusinessShares1Input, BusinessShares2Input, BusinessShares3Input, 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),
|
|
];
|
|
|
|
ControlUtils.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;
|
|
ViewModel.ShowOnlyActiveMembers = true;
|
|
|
|
if (App.Client.HasRedWhite) {
|
|
BusinessSharesLabel.Content = "(rot/weiß/ruhend)";
|
|
//BusinessShares1Input.Background = Brushes.MistyRose;
|
|
BusinessShares1Input.Foreground = Brushes.DarkRed;
|
|
BusinessShares1Input.ToolTip = "Geschäftsanteile (rot)";
|
|
//BusinessShares2Input.Background = Brushes.MintCream;
|
|
BusinessShares2Input.Foreground = Brushes.DarkGreen;
|
|
BusinessShares2Input.ToolTip = "Geschäftsanteile (weiß)";
|
|
BusinessShares3Input.Background = Brushes.WhiteSmoke;
|
|
BusinessShares3Input.ToolTip = "Geschäftsanteile (ruhend)";
|
|
} else {
|
|
BusinessSharesLabel.Content = "(normal/ruhend)";
|
|
BusinessShares1Input.ToolTip = "Geschäftsanteile (normal)";
|
|
BusinessShares2Input.Background = Brushes.WhiteSmoke;
|
|
BusinessShares2Input.ToolTip = "Geschäftsanteile (ruhend)";
|
|
BusinessShares3Input.Visibility = Visibility.Hidden;
|
|
BusinessSharesButton.Margin = new(74, 100, 10, 0);
|
|
}
|
|
|
|
if (!App.Client.EnableMemberHistory) {
|
|
BusinessSharesButton.Visibility = Visibility.Hidden;
|
|
}
|
|
|
|
UpdateContactInfoVisibility();
|
|
}
|
|
|
|
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) {
|
|
var vm = ViewModel;
|
|
var cursor = Mouse.OverrideCursor != null;
|
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
|
var query = (vm.SearchQuery, vm.ShowOnlyActiveMembers);
|
|
var (members, stat) = await Task.Run(async () => {
|
|
using var ctx = new AppDbContext();
|
|
var (_, memberQuery, filter) = await vm.GetFilters(ctx);
|
|
var members = await memberQuery
|
|
.Include(m => m.EmailAddresses)
|
|
.Include(m => m.TelephoneNumbers)
|
|
.AsSplitQuery()
|
|
.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)];
|
|
} else {
|
|
members = [.. members
|
|
.OrderBy(m => m.Name)
|
|
.ThenBy(m => m.GivenName)
|
|
.ThenBy(m => m.MgNr)];
|
|
}
|
|
|
|
var stat = (await ctx.Members.GroupBy(m => 1).Select(g => new {
|
|
Count = g.Count(),
|
|
Shares = g.Sum(m => m.Shares),
|
|
SharesRed = g.Sum(m => m.SharesRed),
|
|
SharesWhite = g.Sum(m => m.SharesWhite),
|
|
SharesDormant = g.Sum(m => m.SharesDormant),
|
|
SharesTotal = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant),
|
|
SharesActive = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite),
|
|
}).ToListAsync()).Select(g => (g.Count, g.Shares, g.SharesRed, g.SharesWhite, g.SharesDormant, g.SharesTotal, g.SharesActive)).ToList();
|
|
|
|
return (members, stat[0]);
|
|
});
|
|
if (!cursor) Mouse.OverrideCursor = null;
|
|
if (query != (ViewModel.SearchQuery, ViewModel.ShowOnlyActiveMembers)) return;
|
|
|
|
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} ({stat.Count:N0})";
|
|
|
|
var sA = members.Sum(m => m.Shares);
|
|
var rA = members.Sum(m => m.SharesRed);
|
|
var wA = members.Sum(m => m.SharesWhite);
|
|
var dA = members.Sum(m => m.SharesDormant);
|
|
List<(int Count, Brush? Color)> a = [];
|
|
if (sA > 0) a.Add((sA, null));
|
|
if (rA > 0) a.Add((rA, Brushes.DarkRed));
|
|
if (wA > 0) a.Add((wA, Brushes.DarkGreen));
|
|
if (a.Count == 0) a.Add((0, null));
|
|
if (dA > 0) a.Add((dA, null));
|
|
|
|
List<(int Count, Brush? Color)> b = [];
|
|
if (stat.Shares > 0) b.Add((stat.Shares, null));
|
|
if (stat.SharesRed > 0) b.Add((stat.SharesRed, Brushes.DarkRed));
|
|
if (stat.SharesWhite > 0) b.Add((stat.SharesWhite, Brushes.DarkGreen));
|
|
if (a.Count == 0) b.Add((0, null));
|
|
if (stat.SharesDormant > 0) b.Add((stat.SharesDormant, null));
|
|
|
|
Run[] inlines = [
|
|
new("Geschäftsanteile: "),
|
|
.. a.Select(i => new Run($"{i.Count:N0}") { Foreground = i.Color ?? Brushes.Black }).Join(() => new("+")),
|
|
new(" ("),
|
|
.. b.Select(i => new Run($"{i.Count:N0}") { Foreground = i.Color ?? Brushes.Black }).Join(() => new("+")),
|
|
new(")")
|
|
];
|
|
if (ViewModel.StatusBusinessShares == null) {
|
|
ViewModel.StatusBusinessShares = new();
|
|
} else {
|
|
ViewModel.StatusBusinessShares.Inlines.Clear();
|
|
}
|
|
ViewModel.StatusBusinessShares.Inlines.AddRange(inlines);
|
|
}
|
|
|
|
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();
|
|
if (App.Client.EnableMemberHistory) {
|
|
BusinessShares1Input.Text = "0";
|
|
BusinessShares2Input.Text = "0";
|
|
BusinessShares3Input.Text = "0";
|
|
} else if (App.Client.HasRedWhite) {
|
|
BusinessShares3Input.Text = "0";
|
|
SetDefaultValue(BusinessShares3Input);
|
|
} else {
|
|
BusinessShares2Input.Text = "0";
|
|
SetDefaultValue(BusinessShares2Input);
|
|
}
|
|
SetDefaultValue(MgNrInput);
|
|
SetDefaultValue(EntryDateInput);
|
|
SetDefaultValue(ActiveInput);
|
|
ValidateRequiredInputs();
|
|
}
|
|
|
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
|
await base.OnRenewContext(ctx);
|
|
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
|
ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync());
|
|
|
|
var font = new FontFamily("Segoe MDL2 Assets");
|
|
MenuItem? temp = null;
|
|
var seasons = await ctx.Seasons.Include(s => s.PaymentVariants).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 stat = await ctx.Members.GroupBy(m => m.IsActive).Select(g => new {
|
|
IsActive = g.Key,
|
|
Count = g.Count(),
|
|
Shares = g.Sum(m => m.Shares),
|
|
SharesRed = g.Sum(m => m.SharesRed),
|
|
SharesWhite = g.Sum(m => m.SharesWhite),
|
|
SharesDormant = g.Sum(m => m.SharesDormant),
|
|
SharesTotal = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant),
|
|
SharesActive = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite),
|
|
}).ToDictionaryAsync(g => g.IsActive);
|
|
|
|
var (s1, s2) = ('\u2007', '\u202f');
|
|
var mA = $"{stat.GetValueOrDefault(true)?.Count ?? 0:N0}";
|
|
var mI = $"{stat.GetValueOrDefault(false)?.Count ?? 0:N0}";
|
|
var mT = $"{stat.Sum(g => g.Value.Count):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 grid = new Grid();
|
|
grid.ColumnDefinitions.Add(new() { Width = new(100) });
|
|
grid.AddToolTipCell("Geschäftsanteile:", 0, 0, bold: true);
|
|
grid.AddToolTipCell("Aktive Mitglieder", 1, 0);
|
|
grid.AddToolTipCell("Nicht aktive Mg.", 2, 0);
|
|
grid.AddToolTipCell("Alle Mitglieder", 3, 0, bold: true);
|
|
if (App.Client.HasRedWhite) {
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.AddToolTipCell("rot", 0, 1, alignRight: true);
|
|
grid.AddToolTipCell("weiß", 0, 2, alignRight: true);
|
|
grid.AddToolTipCell("ruhend", 0, 3, alignRight: true);
|
|
grid.AddToolTipCell("gesamt", 0, 4, alignRight: true);
|
|
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesRed ?? 0:N0}", 1, 1, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesWhite ?? 0:N0}", 1, 2, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesDormant ?? 0:N0}", 1, 3, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesTotal ?? 0:N0}", 1, 4, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesRed ?? 0:N0}", 2, 1, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesWhite ?? 0:N0}", 2, 2, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesDormant ?? 0:N0}", 2, 3, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesTotal ?? 0:N0}", 2, 4, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesRed):N0}", 3, 1, alignRight: true, bold: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesWhite):N0}", 3, 2, alignRight: true, bold: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesDormant):N0}", 3, 3, alignRight: true, bold: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesTotal):N0}", 3, 4, alignRight: true, bold: true);
|
|
} else {
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
grid.AddToolTipCell("normal", 0, 1, alignRight: true);
|
|
grid.AddToolTipCell("ruhend", 0, 2, alignRight: true);
|
|
grid.AddToolTipCell("gesamt", 0, 3, alignRight: true);
|
|
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.Shares ?? 0:N0}", 1, 1, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesDormant ?? 0:N0}", 1, 2, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(true)?.SharesTotal ?? 0:N0}", 1, 3, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.Shares ?? 0:N0}", 2, 1, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesDormant ?? 0:N0}", 2, 2, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.GetValueOrDefault(false)?.SharesTotal ?? 0:N0}", 2, 3, alignRight: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.Shares):N0}", 3, 1, alignRight: true, bold: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesDormant):N0}", 3, 2, alignRight: true, bold: true);
|
|
grid.AddToolTipCell($"{stat.Sum(g => g.Value.SharesTotal):N0}", 3, 3, alignRight: true, bold: true);
|
|
}
|
|
ViewModel.StatusBusinessShares?.ToolTip = grid;
|
|
}
|
|
|
|
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;
|
|
Menu_Contacts_Selected.IsEnabled = !IsEditing && !IsCreating;
|
|
} else {
|
|
Menu_Export_ExportSelected.IsEnabled = false;
|
|
Menu_Export_UploadSelected.IsEnabled = false;
|
|
Menu_Contacts_Selected.IsEnabled = false;
|
|
}
|
|
}
|
|
|
|
private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) {
|
|
if (!HasContextLoaded) return;
|
|
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()) {
|
|
areaComs = await ctx.AreaCommitments.Where(c => c.MgNr == m.MgNr).CountAsync();
|
|
deliveries = await ctx.Deliveries.Where(d => d.MgNr == m.MgNr).CountAsync();
|
|
credits = await ctx.Credits.Where(c => c.MgNr == m.MgNr).CountAsync();
|
|
}
|
|
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits);
|
|
if (d.ShowDialog() == true) {
|
|
Mouse.OverrideCursor = Cursors.Wait;
|
|
try {
|
|
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
|
|
App.HintContextChange();
|
|
} catch (Exception exc) {
|
|
InteractionService.ShowDbException("Mitglied löschen", exc);
|
|
}
|
|
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.Wait;
|
|
SaveButton.IsEnabled = false;
|
|
|
|
int mgnr;
|
|
try {
|
|
mgnr = await ViewModel.UpdateMember(ViewModel.SelectedMember?.MgNr);
|
|
App.HintContextChange();
|
|
} catch (Exception exc) {
|
|
InteractionService.ShowDbException("Mitglied aktualisieren", exc);
|
|
SaveButton.IsEnabled = true;
|
|
Mouse.OverrideCursor = null;
|
|
return;
|
|
}
|
|
|
|
IsEditing = false;
|
|
IsCreating = false;
|
|
MemberList.IsEnabled = true;
|
|
HideSaveResetCancelButtons();
|
|
ShowNewEditDeleteButtons();
|
|
LockInputs();
|
|
UpdateContactInfoVisibility();
|
|
ViewModel.EnableSearchInputs = true;
|
|
FinishInputFilling();
|
|
await EnsureContextRenewed();
|
|
ViewModel.SearchQuery = "";
|
|
Mouse.OverrideCursor = null;
|
|
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 BusinessSharesButton_Click(object sender, RoutedEventArgs evt) {
|
|
// TODO
|
|
// App.FocusBusinessSharesWindow(ViewModel.SelectedMember!.MgNr);
|
|
}
|
|
|
|
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) {
|
|
if (!HasContextLoaded) return;
|
|
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.Wait;
|
|
try {
|
|
await Task.Run(async () => {
|
|
using var doc = new Letterhead(m);
|
|
using (var ctx = new AppDbContext()) {
|
|
await doc.Generate(ctx);
|
|
}
|
|
if (!App.Config.Debug) {
|
|
await doc.Print();
|
|
} else {
|
|
doc.Show();
|
|
}
|
|
});
|
|
} catch (Exception exc) {
|
|
InteractionService.ShowException(exc);
|
|
}
|
|
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;
|
|
if (!InteractionService.AskQuestion("Stammdatenblatt verschicken", "Soll eine E-Mail verschickt werden?", true))
|
|
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;
|
|
if (!InteractionService.AskQuestion("Anlieferungsbestätigung verschicken", "Soll eine E-Mail verschickt werden?", true))
|
|
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;
|
|
if (!InteractionService.AskQuestion("Traubengutschrift verschicken", "Soll eine E-Mail verschickt werden?", true))
|
|
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_Contacts_All_Click(object sender, RoutedEventArgs evt) =>
|
|
await ViewModel.GenerateMemberList(MemberService.ExportSubject.All, ExportMode.Vcf);
|
|
private async void Menu_Contacts_Filters_Click(object sender, RoutedEventArgs evt) =>
|
|
await ViewModel.GenerateMemberList(MemberService.ExportSubject.FromFilters, ExportMode.Vcf);
|
|
private async void Menu_Contacts_Selected_Click(object sender, RoutedEventArgs evt) =>
|
|
await ViewModel.GenerateMemberList(MemberService.ExportSubject.Selected, ExportMode.Vcf);
|
|
|
|
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();
|
|
if (App.Client.EnableMemberHistory) {
|
|
BusinessShares1Input.Text = "";
|
|
BusinessShares2Input.Text = "";
|
|
BusinessShares3Input.Text = "";
|
|
ControlUtils.ClearInputState(BusinessShares1Input);
|
|
ControlUtils.ClearInputState(BusinessShares2Input);
|
|
ControlUtils.ClearInputState(BusinessShares3Input);
|
|
}
|
|
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.FetchMembers(mgnr).SingleAsync();
|
|
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 AreaComTransferDialog(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) {
|
|
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 AreaComTransferDialog(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();
|
|
}
|
|
}
|
|
}
|