[#29] DeliveryAdminWindow: Only show sums of filtered parts when filtering

This commit is contained in:
2024-01-19 13:35:53 +01:00
parent 42bf01656e
commit 626724fe87
3 changed files with 53 additions and 33 deletions

View File

@ -68,19 +68,32 @@ namespace Elwig.Models.Entities {
[InverseProperty("Delivery")] [InverseProperty("Delivery")]
public virtual ISet<DeliveryPart> Parts { get; private set; } public virtual ISet<DeliveryPart> Parts { get; private set; }
[NotMapped]
public IEnumerable<DeliveryPart> FilteredParts => PartFilter == null ? Parts : Parts.Where(p => PartFilter(p));
[NotMapped]
public Predicate<DeliveryPart>? PartFilter { get; set; }
public int Weight => Parts.Select(p => p.Weight).Sum(); public int Weight => Parts.Select(p => p.Weight).Sum();
public int FilteredWeight => FilteredParts.Select(p => p.Weight).Sum();
public IEnumerable<string> SortIds => Parts public IEnumerable<string> SortIds => Parts
.GroupBy(p => p.SortId) .GroupBy(p => p.SortId)
.OrderByDescending(g => g.Select(p => p.Weight).Sum()) .OrderByDescending(g => g.Select(p => p.Weight).Sum())
.Select(g => g.Select(p => p.SortId).First()); .Select(g => g.Key);
public IEnumerable<string> FilteredSortIds => FilteredParts
.GroupBy(p => p.SortId)
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
.Select(g => g.Key);
public string SortIdString => string.Join(", ", SortIds); public string SortIdString => string.Join(", ", SortIds);
public string FilteredSortIdString => string.Join(", ", FilteredSortIds);
public double Kmw => Utils.AggregateDeliveryPartsKmw(Parts); public double Kmw => Utils.AggregateDeliveryPartsKmw(Parts);
public double FilteredKmw => Utils.AggregateDeliveryPartsKmw(FilteredParts);
public double Oe => Utils.KmwToOe(Kmw); public double Oe => Utils.KmwToOe(Kmw);
public double FilteredOe => Utils.KmwToOe(FilteredKmw);
public int SearchScore(IEnumerable<string> keywords) { public int SearchScore(IEnumerable<string> keywords) {
var list = new string?[] { var list = new string?[] {

View File

@ -148,21 +148,21 @@
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Sorte" Binding="{Binding SortIdString}" Width="50"> <DataGridTextColumn Header="Sorte" Binding="{Binding FilteredSortIdString}" Width="50">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Center"/> <Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg '}" Width="75"> <DataGridTextColumn Header="Gewicht" Binding="{Binding FilteredWeight, StringFormat='{}{0:N0} kg '}" Width="75">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Gradation" Binding="{Binding Kmw, StringFormat='{}{0:N1}° '}" Width="50"> <DataGridTextColumn Header="Gradation" Binding="{Binding FilteredKmw, StringFormat='{}{0:N1}° '}" Width="50">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>

View File

@ -10,6 +10,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -168,7 +169,7 @@ namespace Elwig.Windows {
private async void Menu_Print_DeliveryJournal_ShowFilter_Click(object sender, RoutedEventArgs evt) { private async void Menu_Print_DeliveryJournal_ShowFilter_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.AppStarting;
var (f, _, d, _) = await GetFilters(); var (f, _, d, _, _) = await GetFilters();
var doc = new DeliveryJournal(string.Join(" / ", f), d); var doc = new DeliveryJournal(string.Join(" / ", f), d);
await doc.Generate(); await doc.Generate();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@ -177,7 +178,7 @@ namespace Elwig.Windows {
private async void Menu_Print_DeliveryJournal_PrintFilter_Click(object sender, RoutedEventArgs evt) { private async void Menu_Print_DeliveryJournal_PrintFilter_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.AppStarting;
var (f, _, d, _) = await GetFilters(); var (f, _, d, _, _) = await GetFilters();
var doc = new DeliveryJournal(string.Join(" / ", f), d); var doc = new DeliveryJournal(string.Join(" / ", f), d);
await doc.Generate(); await doc.Generate();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@ -296,7 +297,7 @@ namespace Elwig.Windows {
await RefreshDeliveryListQuery(); await RefreshDeliveryListQuery();
} }
private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, List<string>)> GetFilters() { private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, Predicate<DeliveryPart>, List<string>)> GetFilters() {
List<string> filterNames = []; List<string> filterNames = [];
IQueryable<Delivery> deliveryQuery = Context.Deliveries; IQueryable<Delivery> deliveryQuery = Context.Deliveries;
if (IsReceipt && App.BranchNum > 1) { if (IsReceipt && App.BranchNum > 1) {
@ -316,12 +317,8 @@ namespace Elwig.Windows {
deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value); deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value);
filterNames.Add(SeasonInput.Value.ToString() ?? ""); filterNames.Add(SeasonInput.Value.ToString() ?? "");
} }
IQueryable<DeliveryPart> dpq = deliveryQuery
.SelectMany(d => d.Parts) Expression<Func<DeliveryPart, bool>> prd = p => true;
.OrderBy(p => p.Delivery.DateString)
.ThenBy(p => p.Delivery.TimeString)
.ThenBy(p => p.Delivery.LsNr)
.ThenBy(p => p.DPNr);
var filterVar = new List<string>(); var filterVar = new List<string>();
var filterNotVar = new List<string>(); var filterNotVar = new List<string>();
@ -487,32 +484,32 @@ namespace Elwig.Windows {
} }
} }
if (filterYearGt > 0) dpq = dpq.Where(p => p.Year >= filterYearGt); if (filterYearGt > 0) prd = prd.And(p => p.Year >= filterYearGt);
if (filterYearLt > 0) dpq = dpq.Where(p => p.Year < filterYearLt); if (filterYearLt > 0) prd = prd.And(p => p.Year < filterYearLt);
if (filterMgNr.Count > 0) dpq = dpq.Where(p => filterMgNr.Contains(p.Delivery.MgNr)); if (filterMgNr.Count > 0) prd = prd.And(p => filterMgNr.Contains(p.Delivery.MgNr));
if (filterDate.Count > 0) { if (filterDate.Count > 0) {
var pr = PredicateBuilder.New<DeliveryPart>(false); var pr = PredicateBuilder.New<DeliveryPart>(false);
foreach (var (d1, d2) in filterDate) foreach (var (d1, d2) in filterDate)
pr.Or(p => (d1 == null || d1.CompareTo(p.Delivery.DateString.Substring(10 - d1.Length)) <= 0) && (d2 == null || d2.CompareTo(p.Delivery.DateString.Substring(10 - d2.Length)) >= 0)); pr.Or(p => (d1 == null || d1.CompareTo(p.Delivery.DateString.Substring(10 - d1.Length)) <= 0) && (d2 == null || d2.CompareTo(p.Delivery.DateString.Substring(10 - d2.Length)) >= 0));
dpq = dpq.Where(pr); prd = prd.And(pr);
} }
if (filterTime.Count > 0) { if (filterTime.Count > 0) {
var pr = PredicateBuilder.New<DeliveryPart>(false); var pr = PredicateBuilder.New<DeliveryPart>(false);
foreach (var (t1, t2) in filterTime) foreach (var (t1, t2) in filterTime)
pr.Or(p => (t1 == null || t1.CompareTo(p.Delivery.TimeString) <= 0) && (t2 == null || t2.CompareTo(p.Delivery.TimeString) > 0)); pr.Or(p => (t1 == null || t1.CompareTo(p.Delivery.TimeString) <= 0) && (t2 == null || t2.CompareTo(p.Delivery.TimeString) > 0));
dpq = dpq.Where(p => p.Delivery.TimeString != null).Where(pr); prd = prd.And(p => p.Delivery.TimeString != null).And(pr);
} }
if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId)); if (filterVar.Count > 0) prd = prd.And(p => filterVar.Contains(p.SortId));
if (filterNotVar.Count > 0) dpq = dpq.Where(p => !filterNotVar.Contains(p.SortId)); if (filterNotVar.Count > 0) prd = prd.And(p => !filterNotVar.Contains(p.SortId));
if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId)); if (filterQual.Count > 0) prd = prd.And(p => filterQual.Contains(p.QualId));
if (filterNotQual.Count > 0) dpq = dpq.Where(p => !filterNotQual.Contains(p.QualId)); if (filterNotQual.Count > 0) prd = prd.And(p => !filterNotQual.Contains(p.QualId));
if (filterZwst.Count > 0) dpq = dpq.Where(p => filterZwst.Contains(p.Delivery.ZwstId)); if (filterZwst.Count > 0) prd = prd.And(p => filterZwst.Contains(p.Delivery.ZwstId));
if (filterAttr.Count > 0) dpq = dpq.Where(p => p.AttrId != null && filterAttr.Contains(p.AttrId)); if (filterAttr.Count > 0) prd = prd.And(p => p.AttrId != null && filterAttr.Contains(p.AttrId));
if (filterNotAttr.Count > 0) dpq = dpq.Where(p => p.AttrId == null || !filterNotAttr.Contains(p.AttrId)); if (filterNotAttr.Count > 0) prd = prd.And(p => p.AttrId == null || !filterNotAttr.Contains(p.AttrId));
if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt); if (filterKmwGt > 0) prd = prd.And(p => p.Kmw >= filterKmwGt);
if (filterKmwLt > 0) dpq = dpq.Where(p => p.Kmw < filterKmwLt); if (filterKmwLt > 0) prd = prd.And(p => p.Kmw < filterKmwLt);
if (filterOeGt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt); if (filterOeGt > 0) prd = prd.And(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt);
if (filterOeLt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt); if (filterOeLt > 0) prd = prd.And(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt);
if (filterYearGt > 0 && filterYearLt > 0) { if (filterYearGt > 0 && filterYearLt > 0) {
filterNames.Insert(0, $"{filterYearGt}{filterYearLt - 1}"); filterNames.Insert(0, $"{filterYearGt}{filterYearLt - 1}");
@ -537,7 +534,15 @@ namespace Elwig.Windows {
} }
} }
return (filterNames, dpq.Select(p => p.Delivery).Distinct().OrderBy(d => d.DateString).ThenBy(d => d.TimeString), dpq, filter); IQueryable<DeliveryPart> dpq = deliveryQuery
.SelectMany(d => d.Parts)
.Where(prd)
.OrderBy(p => p.Delivery.DateString)
.ThenBy(p => p.Delivery.TimeString)
.ThenBy(p => p.Delivery.LsNr)
.ThenBy(p => p.DPNr);
return (filterNames, dpq.Select(p => p.Delivery).Distinct().OrderBy(d => d.DateString).ThenBy(d => d.TimeString), dpq, prd.Invoke, filter);
} }
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) { private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
@ -573,7 +578,7 @@ namespace Elwig.Windows {
} }
private async Task RefreshDeliveryListQuery(bool updateSort = false) { private async Task RefreshDeliveryListQuery(bool updateSort = false) {
var (_, deliveryQuery, deliveryPartsQuery, filter) = await GetFilters(); var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await GetFilters();
var deliveries = await deliveryQuery.ToListAsync(); var deliveries = await deliveryQuery.ToListAsync();
deliveries.Reverse(); deliveries.Reverse();
@ -589,8 +594,10 @@ namespace Elwig.Windows {
.ToList(); .ToList();
} }
deliveries.ForEach(d => { d.PartFilter = predicate; });
ControlUtils.RenewItemsSource(DeliveryList, deliveries, d => ((d as Delivery)?.Year, (d as Delivery)?.DId), ControlUtils.RenewItemsSource(DeliveryList, deliveries, d => ((d as Delivery)?.Year, (d as Delivery)?.DId),
DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort); DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
await RefreshDeliveryParts();
var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList(); var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList();
StatusMembers.Text = $"Mitglieder: {members.Count}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : ""); StatusMembers.Text = $"Mitglieder: {members.Count}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
@ -760,7 +767,7 @@ namespace Elwig.Windows {
private async Task RefreshDeliveryParts() { private async Task RefreshDeliveryParts() {
if (DeliveryList.SelectedItem is Delivery d) { if (DeliveryList.SelectedItem is Delivery d) {
ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == d.Year).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId); ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == d.Year).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId);
ControlUtils.RenewItemsSource(DeliveryPartList, d.Parts.OrderBy(p => p.DPNr).ToList(), i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId, (i as DeliveryPart)?.DPNr), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First); ControlUtils.RenewItemsSource(DeliveryPartList, d.FilteredParts.OrderBy(p => p.DPNr).ToList(), i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId, (i as DeliveryPart)?.DPNr), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
} else { } else {
ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == Utils.CurrentLastSeason).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId); ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == Utils.CurrentLastSeason).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId);
DeliveryPartList.ItemsSource = null; DeliveryPartList.ItemsSource = null;
@ -1134,7 +1141,7 @@ namespace Elwig.Windows {
} else { } else {
// switch to last delivery part // switch to last delivery part
DeliveryPartList.IsEnabled = true; DeliveryPartList.IsEnabled = true;
DeliveryPartList.SelectedItem = d.Parts.Last(); DeliveryPartList.SelectedItem = d.FilteredParts.Last();
} }
} }