From 51ad8f99fd944b8fa1370e0e93bafc6bd0336695 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 19 Sep 2023 19:31:02 +0200 Subject: [PATCH] DeliveryAdminWindow: Add DeliveryJournal filter options --- Elwig/Windows/DeliveryAdminWindow.xaml | 19 +-- Elwig/Windows/DeliveryAdminWindow.xaml.cs | 152 ++++++++++++++++------ 2 files changed, 120 insertions(+), 51 deletions(-) diff --git a/Elwig/Windows/DeliveryAdminWindow.xaml b/Elwig/Windows/DeliveryAdminWindow.xaml index f3e2785..0a6cbc6 100644 --- a/Elwig/Windows/DeliveryAdminWindow.xaml +++ b/Elwig/Windows/DeliveryAdminWindow.xaml @@ -56,24 +56,25 @@ - - - - + + + + + + - - - diff --git a/Elwig/Windows/DeliveryAdminWindow.xaml.cs b/Elwig/Windows/DeliveryAdminWindow.xaml.cs index 17fbf5b..8c55557 100644 --- a/Elwig/Windows/DeliveryAdminWindow.xaml.cs +++ b/Elwig/Windows/DeliveryAdminWindow.xaml.cs @@ -111,8 +111,8 @@ namespace Elwig.Windows { Mouse.OverrideCursor = Cursors.Wait; using var doc = new DeliveryNote(d, Context); await doc.Generate(); - doc.Show(); Mouse.OverrideCursor = null; + doc.Show(); } private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) { @@ -141,7 +141,7 @@ namespace Elwig.Windows { } } - private async void Menu_Print_ShowDeliveryJournalToday_Click(object sender, RoutedEventArgs evt) { + private async void Menu_Print_DeliveryJournal_ShowToday_Click(object sender, RoutedEventArgs evt) { Mouse.OverrideCursor = Cursors.Wait; var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today)); await doc.Generate(); @@ -149,9 +149,27 @@ namespace Elwig.Windows { doc.Show(); } - private async void Menu_Print_ShowDeliveryJournalYesterday_Click(object sender, RoutedEventArgs evt) { + private async void Menu_Print_DeliveryJournal_PrintToday_Click(object sender, RoutedEventArgs evt) { Mouse.OverrideCursor = Cursors.Wait; - var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today.AddDays(-1))); + var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today)); + await doc.Generate(); + Mouse.OverrideCursor = null; + await doc.Print(); + } + + private async void Menu_Print_DeliveryJournal_ShowFilter_Click(object sender, RoutedEventArgs evt) { + Mouse.OverrideCursor = Cursors.Wait; + var (f, _, d, _) = await GetFilters(); + var doc = new DeliveryJournal(string.Join(" / ", f), d); + await doc.Generate(); + Mouse.OverrideCursor = null; + doc.Show(); + } + + private async void Menu_Print_DeliveryJournal_PrintFilter_Click(object sender, RoutedEventArgs evt) { + Mouse.OverrideCursor = Cursors.Wait; + var (f, _, d, _) = await GetFilters(); + var doc = new DeliveryJournal(string.Join(" / ", f), d); await doc.Generate(); Mouse.OverrideCursor = null; doc.Show(); @@ -227,19 +245,28 @@ namespace Elwig.Windows { await RefreshDeliveryListQuery(); } - private async Task RefreshDeliveryListQuery(bool updateSort = false) { + private async Task<(List, IQueryable, IQueryable, List)> GetFilters() { + List filterNames = new(); IQueryable deliveryQuery = Context.Deliveries; if (Member != null) { deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr); + filterNames.Add(Member.AdministrativeName); } if (TodayOnlyInput.IsChecked == true) { deliveryQuery = deliveryQuery - .Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) || + .Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) || (d.DateString == Utils.Today.AddDays(1).ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") <= 0)); + filterNames.Add(Utils.Today.ToString("dd.MM.yyyy")); } else if (AllSeasonsInput.IsChecked == false) { deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value); + filterNames.Add(SeasonInput.Value.ToString() ?? ""); } + deliveryQuery = deliveryQuery.OrderBy(d => d.DateString).ThenBy(d => d.TimeString); + IQueryable dpq = deliveryQuery.SelectMany(d => d.Parts); + // TODO add filter for: + // attributes + // branches var filterVar = new List(); var filterQual = new List(); var filterMgNr = new List(); @@ -256,21 +283,24 @@ namespace Elwig.Windows { var filter = TextFilter.ToList(); if (filter.Count > 0) { - var var = await Context.WineVarieties.Select(v => v.SortId).ToListAsync(); - var qual = await Context.WineQualityLevels.Select(q => q.QualId).ToListAsync(); - var mgnr = await Context.Members.Select(m => m.MgNr.ToString()).ToListAsync(); + var var = await Context.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v); + var qual = await Context.WineQualityLevels.ToDictionaryAsync(q => q.QualId, q => q); + var mgnr = await Context.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m); for (int i = 0; i < filter.Count; i++) { var e = filter[i]; - if (e.Length == 2 && var.Contains(e.ToUpper())) { + if (e.Length == 2 && var.ContainsKey(e.ToUpper())) { filterVar.Add(e.ToUpper()); filter.RemoveAt(i--); - } else if (e.Length == 3 && qual.Contains(e.ToUpper())) { + filterNames.Add(var[e.ToUpper()].Name); + } else if (e.Length == 3 && qual.ContainsKey(e.ToUpper())) { filterQual.Add(e.ToUpper()); filter.RemoveAt(i--); - } else if (e.All(char.IsAsciiDigit) && mgnr.Contains(e)) { + filterNames.Add(qual[e.ToUpper()].Name); + } else if (e.All(char.IsAsciiDigit) && mgnr.ContainsKey(e)) { filterMgNr.Add(int.Parse(e)); filter.RemoveAt(i--); + filterNames.Add(mgnr[e].AdministrativeName); } else if (e.StartsWith(">") || e.StartsWith("<")) { if (double.TryParse(e[1..], out var num)) { switch ((e[0], num)) { @@ -319,12 +349,23 @@ namespace Elwig.Windows { filterTimeLt = TimeOnly.TryParse(parts[1], out var to) ? $"{to:HH:mm}" : null; filter.RemoveAt(i--); } else if (DateOnly.TryParse(e, out var date)) { - filterDate.Add($"{date:yyyy-MM-dd}"); + // TODO allow date ranges + filterDate.Add(date.ToString("yyyy-MM-dd")); filter.RemoveAt(i--); + filterNames.Add(date.ToString("dd.MM.yyyy")); } else if (Utils.PartialDateRegex.IsMatch(e)) { + // TODO allow date ranges var parts = e.Split("."); - filterPartDate.Add($"-{int.Parse(parts[1]):00}-{int.Parse(parts[0]):00}"); + var p0 = int.Parse(parts[0]); + var p1 = int.Parse(parts[1]); + filterPartDate.Add($"-{p1:00}-{p0:00}"); filter.RemoveAt(i--); + if (filterNames.Contains(SeasonInput.Value.ToString())) { + filterNames.Remove(SeasonInput.Value.ToString()); + filterNames.Add($"{p0:00}.{p1:00}.{SeasonInput.Value:0000}"); + } else { + filterNames.Add($"{p0:00}.{p1:00}."); + } } else if (e.Length > 2 && e.StartsWith("\"") && e.EndsWith("\"")) { filter[i] = e[1..^1]; } else if (e.Length <= 2) { @@ -332,22 +373,58 @@ namespace Elwig.Windows { } } - if (filterMgNr.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterMgNr.Contains(d.MgNr)); - if (filterDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterDate.Contains(d.DateString)); - if (filterPartDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterPartDate.Contains(d.DateString.Substring(4))); - if (filterYearGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year >= filterYearGt); - if (filterYearLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year < filterYearLt); - if (filterTimeGt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeGt.CompareTo(d.TimeString) <= 0); - if (filterTimeLt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeLt.CompareTo(d.TimeString) > 0); - if (filterVar.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterVar.Contains(p.SortId))); - if (filterQual.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterQual.Contains(p.QualId))); - if (filterKmwGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw >= filterKmwGt)); - if (filterKmwLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw < filterKmwLt)); - if (filterOeGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt)); - if (filterOeLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt)); + if (filterMgNr.Count > 0) dpq = dpq.Where(p => filterMgNr.Contains(p.Delivery.MgNr)); + if (filterDate.Count > 0) dpq = dpq.Where(p => filterDate.Contains(p.Delivery.DateString)); + if (filterPartDate.Count > 0) dpq = dpq.Where(p => filterPartDate.Contains(p.Delivery.DateString.Substring(4))); + if (filterYearGt > 0) dpq = dpq.Where(p => p.Year >= filterYearGt); + if (filterYearLt > 0) dpq = dpq.Where(p => p.Year < filterYearLt); + if (filterTimeGt != null) dpq = dpq.Where(p => filterTimeGt.CompareTo(p.Delivery.TimeString) <= 0); + if (filterTimeLt != null) dpq = dpq.Where(p => filterTimeLt.CompareTo(p.Delivery.TimeString) > 0); + if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId)); + if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId)); + if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt); + if (filterKmwLt > 0) dpq = dpq.Where(p => p.Kmw < filterKmwLt); + if (filterOeGt > 0) dpq = dpq.Where(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 (filterYearGt > 0 && filterYearLt > 0) { + filterNames.Insert(0, $"{filterYearGt}–{filterYearLt - 1}"); + } else if (filterYearGt > 0) { + filterNames.Insert(0, $"ab {filterYearGt}"); + } else if (filterYearLt > 0) { + filterNames.Insert(0, $"bis {filterYearLt - 1}"); + } + if (filterKmwGt > 0 && filterKmwLt > 0) { + filterNames.Add($"{filterKmwGt:N1}–{filterKmwLt:N1} °KMW"); + } else if (filterKmwGt > 0) { + filterNames.Add($"ab {filterKmwGt:N1} °KMW"); + } else if (filterKmwLt > 0) { + filterNames.Add($"bis {filterKmwLt:N1} °KMW"); + } + if (filterOeGt > 0 && filterOeLt > 0) { + filterNames.Add($"{filterOeGt:N1}–{filterOeLt:N1} °Oe"); + } else if (filterOeGt > 0) { + filterNames.Add($"ab {filterOeGt:N1} °Oe"); + } else if (filterOeLt > 0) { + filterNames.Add($"bis {filterOeLt:N1} °Oe"); + } + if (filterTimeGt != null && filterTimeLt != null) { + filterNames.Add($"{filterTimeGt}–{filterTimeLt}"); + } else if (filterTimeGt != null) { + filterNames.Add($"ab {filterTimeGt}"); + } else if (filterTimeLt != null) { + filterNames.Add($"bis {filterTimeLt}"); + } } - List deliveries = await deliveryQuery.OrderByDescending(d => d.DateString).ThenByDescending(d => d.TimeString).ToListAsync(); + return (filterNames, dpq.Select(p => p.Delivery).Distinct(), dpq, filter); + } + + private async Task RefreshDeliveryListQuery(bool updateSort = false) { + var (_, deliveryQuery, deliveryPartsQuery, filter) = await GetFilters(); + var deliveries = await deliveryQuery.ToListAsync(); + deliveries.Reverse(); + if (filter.Count > 0 && deliveries.Count > 0) { var dict = deliveries.AsParallel() .ToDictionary(d => d, d => d.SearchScore(TextFilter)) @@ -368,15 +445,7 @@ namespace Elwig.Windows { StatusDeliveries.Text = $"Lieferungen: {deliveries.Count}"; if (filter.Count == 0) { - var partsQuery = deliveryQuery.SelectMany(d => d.Parts); - if (filterVar.Count > 0) partsQuery = partsQuery.Where(p => filterVar.Contains(p.SortId)); - if (filterQual.Count > 0) partsQuery = partsQuery.Where(p => filterQual.Contains(p.QualId)); - if (filterKmwGt > 0) partsQuery = partsQuery.Where(p => p.Kmw >= filterKmwGt); - if (filterKmwLt > 0) partsQuery = partsQuery.Where(p => p.Kmw < filterKmwLt); - if (filterOeGt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt); - if (filterOeLt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt); - var deliveryParts = partsQuery; - + var deliveryParts = deliveryPartsQuery; var n = await deliveryParts.CountAsync(); StatusDeliveries.Text = $"Lieferungen: {deliveries.Count} ({n})"; var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync(); @@ -394,9 +463,8 @@ namespace Elwig.Windows { StatusGradation.Text = "Gradation: -"; } - if (n > 0 && (n <= 200 || TodayOnlyInput.IsChecked == true)) { - var parts = (await deliveryParts.ToListAsync()); + var parts = await deliveryParts.ToListAsync(); var groups = parts .GroupBy(p => string.Join("/", p.Attributes.Select(a => a.Name))) .Select(g => (g.Key, g.Sum(p => p.Weight), g.Min(p => p.Kmw), Utils.AggregateDeliveryPartsKmw(g), g.Max(p => p.Kmw))) @@ -790,7 +858,7 @@ namespace Elwig.Windows { NewDeliveryPartButton.Cursor = Cursors.Wait; DeliveryPartList.IsEnabled = false; var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); - EmptyScale(); + EmptyScale(); await RefreshDeliveryList(); await RefreshDeliveryParts(); NewDeliveryPartButton.Cursor = null; @@ -806,8 +874,8 @@ namespace Elwig.Windows { FinishButton.Cursor = Cursors.Wait; DeliveryPartList.IsEnabled = false; var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); - EmptyScale(); - await RefreshDeliveryList(); + EmptyScale(); + await RefreshDeliveryList(); await RefreshDeliveryParts(); if (p?.Delivery != null) { Mouse.OverrideCursor = Cursors.Wait;