From 4038ed87185316502c8155b6b2f19374baf495ac Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 4 Jul 2024 19:29:00 +0200 Subject: [PATCH] [#10] MemberAdminWindow: Add tooltip for delivieries --- Elwig/Services/MemberService.cs | 21 +++++++--- Elwig/ViewModels/MemberAdminViewModel.cs | 23 ++++++++--- Elwig/Windows/MemberAdminWindow.xaml | 20 +++++++--- Elwig/Windows/MemberAdminWindow.xaml.cs | 49 +++++++++++++++++------- 4 files changed, 84 insertions(+), 29 deletions(-) diff --git a/Elwig/Services/MemberService.cs b/Elwig/Services/MemberService.cs index 6ec2be1..b2e56df 100644 --- a/Elwig/Services/MemberService.cs +++ b/Elwig/Services/MemberService.cs @@ -43,7 +43,7 @@ namespace Elwig.Services { vm.Age = "-"; } - public static void FillInputs(this MemberAdminViewModel vm, Member m) { + public static async Task FillInputs(this MemberAdminViewModel vm, Member m) { vm.IsMemberSelected = true; vm.MgNrString = $"{m.MgNr}"; vm.PredecessorMgNrString = $"{m.PredecessorMgNr}"; @@ -129,11 +129,20 @@ namespace Elwig.Services { Dictionary deliveries; using (var ctx = new AppDbContext()) { - var d1 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason && d.MgNr == m.MgNr); - var d2 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason - 1 && d.MgNr == m.MgNr); - vm.StatusDeliveriesLastSeason = $"Lieferungen ({Utils.CurrentLastSeason - 1}): {d2.Count():N0} ({d2.Sum(d => d.Parts.Count):N0}), {d2.SelectMany(d => d.Parts).Sum(p => p.Weight):N0} kg"; - vm.StatusDeliveriesThisSeason = $"Lieferungen ({Utils.CurrentLastSeason}): {d1.Count():N0} ({d1.Sum(d => d.Parts.Count):N0}), {d1.SelectMany(d => d.Parts).Sum(p => p.Weight):N0} kg"; - vm.StatusAreaCommitment = $"Gebundene Fläche: {m.ActiveAreaCommitments(ctx).Select(c => c.Area).Sum():N0} m²"; + var d1 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason - 1 && d.MgNr == m.MgNr); + var (_, d1Grid, _, _) = await DeliveryService.GenerateToolTip(d1.SelectMany(d => d.Parts)); + vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}"; + vm.StatusDeliveriesLastSeason = $"{await d1.CountAsync():N0} ({await d1.SumAsync(d => d.Parts.Count):N0}), {await d1.SelectMany(d => d.Parts).SumAsync(p => p.Weight):N0} kg"; + vm.StatusDeliveriesLastSeasonToolTip = d1Grid; + + var d2 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason && d.MgNr == m.MgNr); + var (_, d2Grid, _, _) = await DeliveryService.GenerateToolTip(d2.SelectMany(d => d.Parts)); + vm.StatusDeliveriesThisSeasonInfo = $"{Utils.CurrentLastSeason}"; + vm.StatusDeliveriesThisSeason = $"{await d2.CountAsync():N0} ({await d2.SumAsync(d => d.Parts.Count):N0}), {await d2.SelectMany(d => d.Parts).SumAsync(p => p.Weight):N0} kg"; + vm.StatusDeliveriesThisSeasonToolTip = d2Grid; + + vm.StatusAreaCommitment = $"{m.ActiveAreaCommitments(ctx).Select(c => c.Area).Sum():N0} m²"; + deliveries = ctx.Deliveries .Where(d => d.MgNr == m.MgNr) .SelectMany(d => d.Parts) diff --git a/Elwig/ViewModels/MemberAdminViewModel.cs b/Elwig/ViewModels/MemberAdminViewModel.cs index e48936f..be58099 100644 --- a/Elwig/ViewModels/MemberAdminViewModel.cs +++ b/Elwig/ViewModels/MemberAdminViewModel.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; +using System.Windows.Controls; namespace Elwig.ViewModels { public partial class MemberAdminViewModel : ObservableObject { @@ -145,15 +146,27 @@ namespace Elwig.ViewModels { public ObservableCollection PhoneNrs { get; private set; } = [new(), new(), new(), new(), new(), new(), new(), new(), new()]; [ObservableProperty] - private string _statusMembers = "Mitglieder: -"; + private string _statusMembers = "-"; [ObservableProperty] - private string _statusBusinessShares = "Geschäftsanteile: -"; + private string? _statusMembersToolTip; [ObservableProperty] - private string _statusDeliveriesLastSeason = "Lieferungen (letzte Saison): -"; + private string _statusBusinessShares = "-"; [ObservableProperty] - private string _statusDeliveriesThisSeason = "Lieferungen (aktuelle Saison): -"; + private string? _statusBusinessSharesToolTip; [ObservableProperty] - private string _statusAreaCommitment = "Gebundene Fläche: -"; + private string _statusDeliveriesLastSeason = "-"; + [ObservableProperty] + private string _statusDeliveriesLastSeasonInfo = "letzte Saison"; + [ObservableProperty] + private Grid? _statusDeliveriesLastSeasonToolTip; + [ObservableProperty] + private string _statusDeliveriesThisSeason = "-"; + [ObservableProperty] + private string _statusDeliveriesThisSeasonInfo = "aktuelle Saison"; + [ObservableProperty] + private Grid? _statusDeliveriesThisSeasonToolTip; + [ObservableProperty] + private string _statusAreaCommitment = "-"; [ObservableProperty] private Visibility _controlButtonsVisibility = Visibility.Visible; diff --git a/Elwig/Windows/MemberAdminWindow.xaml b/Elwig/Windows/MemberAdminWindow.xaml index efce3df..4834fd3 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml +++ b/Elwig/Windows/MemberAdminWindow.xaml @@ -638,23 +638,33 @@ - + + Mitglieder: + - + + Geschäftsanteile: + - + + Gebundene Fläche: + - + + Lieferungen (): + - + + Lieferungen (): + diff --git a/Elwig/Windows/MemberAdminWindow.xaml.cs b/Elwig/Windows/MemberAdminWindow.xaml.cs index 16792d3..d901503 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml.cs +++ b/Elwig/Windows/MemberAdminWindow.xaml.cs @@ -147,12 +147,12 @@ namespace Elwig.Windows { MemberList.ScrollIntoView(MemberList.SelectedItem); } - private void RefreshInputs(bool validate = false) { + private async Task RefreshInputs(bool validate = false) { ClearInputStates(); if (ViewModel.SelectedMember is Member m) { EditMemberButton.IsEnabled = true; DeleteMemberButton.IsEnabled = true; - FillInputs(m); + await FillInputs(m); } else { EditMemberButton.IsEnabled = false; DeleteMemberButton.IsEnabled = false; @@ -224,8 +224,31 @@ namespace Elwig.Windows { } await RefreshList(); - ViewModel.StatusMembers = $"Mitglieder: {await ctx.Members.CountAsync(m => m.IsActive):N0} ({await ctx.Members.CountAsync():N0})"; - ViewModel.StatusBusinessShares = $"Geschäftsanteile: {await ctx.Members.Where(m => m.IsActive).SumAsync(m => m.BusinessShares):N0} ({await ctx.Members.SumAsync(m => m.BusinessShares):N0})"; + + 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.StatusMembers = $"{mA} ({mT})"; + 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.StatusBusinessShares = $"{bA} ({bT})"; + 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) { @@ -254,8 +277,8 @@ namespace Elwig.Windows { inputs.Address.Visibility = vis; } - private void MemberList_SelectionChanged(object sender, RoutedEventArgs evt) { - RefreshInputs(); + private async void MemberList_SelectionChanged(object sender, RoutedEventArgs evt) { + await RefreshInputs(); } private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) { @@ -373,7 +396,7 @@ namespace Elwig.Windows { ViewModel.EnableSearchInputs = true; FinishInputFilling(); await RefreshList(); - RefreshInputs(); + await RefreshInputs(); ViewModel.SearchQuery = ""; if (mgnr is int m) FocusMember(m); @@ -385,11 +408,11 @@ namespace Elwig.Windows { ResetButton_Click(null, null); } - private void ResetButton_Click(object? sender, RoutedEventArgs? evt) { + private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) { ViewModel.TransferPredecessorAreaComs = null; ViewModel.CancelAreaComs = null; if (IsEditing) { - RefreshInputs(); + await RefreshInputs(); } else if (IsCreating) { ClearInputs(); InitInputs(); @@ -397,7 +420,7 @@ namespace Elwig.Windows { UpdateButtons(); } - private void CancelButton_Click(object sender, RoutedEventArgs evt) { + private async void CancelButton_Click(object sender, RoutedEventArgs evt) { IsEditing = false; IsCreating = false; MemberList.IsEnabled = true; @@ -405,7 +428,7 @@ namespace Elwig.Windows { ViewModel.CancelAreaComs = null; HideSaveResetCancelButtons(); ShowNewEditDeleteButtons(); - RefreshInputs(); + await RefreshInputs(); LockInputs(); UpdateContactInfoVisibility(); ViewModel.EnableSearchInputs = true; @@ -616,10 +639,10 @@ namespace Elwig.Windows { } } - private void FillInputs(Member m) { + private async Task FillInputs(Member m) { ClearOriginalValues(); ClearDefaultValues(); - ViewModel.FillInputs(m); + await ViewModel.FillInputs(m); UpdateContactInfoVisibility(IsEditing || IsCreating); FinishInputFilling(); }