DeliveryAdminWindow: Add WineLocalityStatistics
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Test / Run tests (push) Successful in 2m10s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Test / Run tests (push) Successful in 2m10s
				
			This commit is contained in:
		| @@ -301,6 +301,7 @@ namespace Elwig.Helpers.Export { | ||||
|                 if (units != null && units.Length > 0) { | ||||
|                     int n = -1; | ||||
|                     switch (units[0]) { | ||||
|                         case "#": n = 0; data = $"{v:N0}"; break; | ||||
|                         case "%": n = 1; data = $"{v:N1}"; break; | ||||
|                         case "€": n = 2; data = $"{v:N2}"; break; | ||||
|                         case "€/kg": n = 4; data = $"{v:N4}"; break; | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
| using System.Linq; | ||||
|   | ||||
							
								
								
									
										60
									
								
								Elwig/Models/Dtos/WineLocalityStatisticsData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Elwig/Models/Dtos/WineLocalityStatisticsData.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| using Elwig.Helpers; | ||||
| using Elwig.Models.Entities; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using static Elwig.Models.Dtos.WineLocalityStatisticsData; | ||||
|  | ||||
| namespace Elwig.Models.Dtos { | ||||
|     class WineLocalityStatisticsData : DataTable<StatisticsRow> { | ||||
|  | ||||
|         private static readonly (string, string, string?, int?)[] FieldNames = [ | ||||
|             ("Branch", "Zwst.", null, 30), | ||||
|             ("KgNr", "KgNr.", null, 15), | ||||
|             ("Name", "Katastralgemeinde", null, 50), | ||||
|             ("Members", "Mitgl.", "#", 15), | ||||
|             ("Deliveries", "Lfrg.", "#", 15), | ||||
|             ("Parts", "Teill.", "#", 15), | ||||
|             ("Weight", "Gewicht", "kg", 20), | ||||
|             ("Gradation", "Gradation", "°Oe|°KMW", 30), | ||||
|         ]; | ||||
|  | ||||
|         public record struct StatisticsRow( | ||||
|             string Branch, | ||||
|             int? KgNr, | ||||
|             string? Name, | ||||
|             int Members, | ||||
|             int Deliveries, | ||||
|             int Parts, | ||||
|             int Weight, | ||||
|             (double Oe, double Kmw) Gradation | ||||
|         ); | ||||
|  | ||||
|         public WineLocalityStatisticsData(IEnumerable<StatisticsRow> rows, List<string> filterNames) : | ||||
|             base("Lieferstatistik pro Ort", "Lieferstatistik pro Ort", string.Join(" / ", filterNames), rows, FieldNames) { | ||||
|         } | ||||
|  | ||||
|         public static async Task<WineLocalityStatisticsData> FromQuery(IQueryable<DeliveryPart> query, List<string> filterNames) { | ||||
|             return new((await query | ||||
|                 .GroupBy(p => new { | ||||
|                     Branch = p.Delivery.Branch.Name, | ||||
|                     p.Kg!.KgNr, | ||||
|                     Kg = p.Kg!.AtKg.Name, | ||||
|                 }, (k, g) => new { | ||||
|                     k.Branch, | ||||
|                     KgNr = (int?)k.KgNr, | ||||
|                     Kg = (string?)k.Kg, | ||||
|                     Members = g.Select(p => p.Delivery.Member).Distinct().Count(), | ||||
|                     Deliveries = g.Select(p => p.Delivery).Distinct().Count(), | ||||
|                     Parts = g.Count(), | ||||
|                     Weight = g.Sum(p => p.Weight), | ||||
|                     Kmw = g.Sum(p => p.Kmw * p.Weight) / g.Sum(p => p.Weight), | ||||
|                 }) | ||||
|                 .OrderByDescending(g => g.Weight) | ||||
|                 .ThenBy(g => g.KgNr) | ||||
|                 .ToListAsync()).Select(g => new StatisticsRow(g.Branch, g.KgNr, g.Kg, g.Members, g.Deliveries, g.Parts, g.Weight, (Utils.KmwToOe(g.Kmw), Math.Round(g.Kmw, 1)))), filterNames); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -809,6 +809,38 @@ namespace Elwig.Services { | ||||
|             Mouse.OverrideCursor = null; | ||||
|         } | ||||
|  | ||||
|         public static async Task GenerateLocalityStatistics(this DeliveryAdminViewModel vm, ExportSubject subject) { | ||||
|             using var ctx = new AppDbContext(); | ||||
|             IQueryable<DeliveryPart> query; | ||||
|             List<string> filterNames = []; | ||||
|             if (subject == ExportSubject.FromFilters) { | ||||
|                 var (f, _, q, _, _) = await vm.GetFilters(ctx); | ||||
|                 query = q; | ||||
|                 filterNames.AddRange(f); | ||||
|  | ||||
|             } else { | ||||
|                 throw new ArgumentException("Invalid value for ExportSubject"); | ||||
|             } | ||||
|  | ||||
|             var d = new SaveFileDialog() { | ||||
|                 FileName = $"Lieferstatistik-{vm.FilterSeason ?? Utils.CurrentLastSeason}.ods", | ||||
|                 DefaultExt = "ods", | ||||
|                 Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", | ||||
|                 Title = $"Lieferstatistik pro Ort speichern unter - Elwig" | ||||
|             }; | ||||
|             if (d.ShowDialog() == true) { | ||||
|                 Mouse.OverrideCursor = Cursors.AppStarting; | ||||
|                 try { | ||||
|                     using var ods = new OdsFile(d.FileName); | ||||
|                     var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames); | ||||
|                     await ods.AddTable(tbl); | ||||
|                 } catch (Exception exc) { | ||||
|                     MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|                 } | ||||
|                 Mouse.OverrideCursor = null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static async Task GenerateDeliveryDepreciationList(this DeliveryAdminViewModel vm, ExportSubject subject, ExportMode mode) { | ||||
|             using var ctx = new AppDbContext(); | ||||
|             IQueryable<DeliveryPart> query; | ||||
|   | ||||
| @@ -110,32 +110,6 @@ | ||||
|                 <MenuItem x:Name="Menu_DeliveryJournal_PrintToday" Header="...von heute drucken" | ||||
|                           Click="Menu_DeliveryJournal_PrintToday_Click" InputGestureText="Strg+J"/> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Qualitätsstatistik" x:Name="Menu_WineQualityStatistics"> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ShowFilters" Header="...aus Filtern anzeigen (PDF)" | ||||
|                           Click="Menu_WineQualityStatistics_ShowFilters_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_SavePdfFilters" Header="...aus Filtern speichern... (PDF)" | ||||
|                           Click="Menu_WineQualityStatistics_SavePdfFilters_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_PrintFilters" Header="...aus Filtern drucken" | ||||
|                           Click="Menu_WineQualityStatistics_PrintFilters_Click"/> | ||||
|                 <Separator/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ShowToday" Header="...von heute anzeigen (PDF)" | ||||
|                           Click="Menu_WineQualityStatistics_ShowToday_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_SavePdfToday" Header="...von heute speichern... (PDF)" | ||||
|                           Click="Menu_WineQualityStatistics_SavePdfToday_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_PrintToday" Header="...von heute drucken" | ||||
|                           Click="Menu_WineQualityStatistics_PrintToday_Click" InputGestureText="Strg+Q"/> | ||||
|                 <Separator/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ModeOe" Header="...nach °Oe aufschlüsseln" IsCheckable="True" IsChecked="True" | ||||
|                           Click="Menu_WineQualityStatistics_Mode_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ModeKmw10" Header="...nach °KMW aufschlüsseln (⅒)" IsCheckable="True" | ||||
|                           Click="Menu_WineQualityStatistics_Mode_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ModeKmw5" Header="...nach °KMW aufschlüsseln (⅕)" IsCheckable="True" | ||||
|                           Click="Menu_WineQualityStatistics_Mode_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ModeKmw2" Header="...nach °KMW aufschlüsseln (½)" IsCheckable="True" | ||||
|                           Click="Menu_WineQualityStatistics_Mode_Click"/> | ||||
|                 <MenuItem x:Name="Menu_WineQualityStatistics_ModeKmw1" Header="...nach °KMW aufschlüsseln (ganze)" IsCheckable="True" | ||||
|                           Click="Menu_WineQualityStatistics_Mode_Click"/> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Abwertungsliste" x:Name="Menu_DeliveryDepreciationList"> | ||||
|                 <MenuItem x:Name="Menu_DeliveryDepreciationList_SaveFilters" Header="...aus Filtern speichern... (Excel)" | ||||
|                           Click="Menu_DeliveryDepreciationList_SaveFilters_Click"/> | ||||
| @@ -155,6 +129,38 @@ | ||||
|                 <MenuItem x:Name="Menu_DeliveryDepreciationList_PrintSeason" Header="...von Saison drucken" | ||||
|                           Click="Menu_DeliveryDepreciationList_PrintSeason_Click"/> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Statistik" x:Name="Menu_Statistics"> | ||||
|                 <MenuItem Header="Qualitätsstatistik..." x:Name="Menu_Statistics_WineQuality"> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ShowFilters" Header="...aus Filtern anzeigen (PDF)" | ||||
|                               Click="Menu_Statistics_WineQuality_ShowFilters_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_SavePdfFilters" Header="...aus Filtern speichern... (PDF)" | ||||
|                               Click="Menu_Statistics_WineQuality_SavePdfFilters_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_PrintFilters" Header="...aus Filtern drucken" | ||||
|                               Click="Menu_Statistics_WineQuality_PrintFilters_Click"/> | ||||
|                     <Separator/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ShowToday" Header="...von heute anzeigen (PDF)" | ||||
|                               Click="Menu_Statistics_WineQuality_ShowToday_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_SavePdfToday" Header="...von heute speichern... (PDF)" | ||||
|                               Click="Menu_Statistics_WineQuality_SavePdfToday_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_PrintToday" Header="...von heute drucken" | ||||
|                               Click="Menu_Statistics_WineQuality_PrintToday_Click" InputGestureText="Strg+Q"/> | ||||
|                     <Separator/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ModeOe" Header="...nach °Oe aufschlüsseln" IsCheckable="True" IsChecked="True" | ||||
|                               Click="Menu_Statistics_WineQuality_Mode_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ModeKmw10" Header="...nach °KMW aufschlüsseln (⅒)" IsCheckable="True" | ||||
|                               Click="Menu_Statistics_WineQuality_Mode_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ModeKmw5" Header="...nach °KMW aufschlüsseln (⅕)" IsCheckable="True" | ||||
|                               Click="Menu_Statistics_WineQuality_Mode_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ModeKmw2" Header="...nach °KMW aufschlüsseln (½)" IsCheckable="True" | ||||
|                               Click="Menu_Statistics_WineQuality_Mode_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Statistics_WineQuality_ModeKmw1" Header="...nach °KMW aufschlüsseln (ganze)" IsCheckable="True" | ||||
|                               Click="Menu_Statistics_WineQuality_Mode_Click"/> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_Statistics_Locality" Header="Lieferstatistik pro Ort..."> | ||||
|                     <MenuItem x:Name="Menu_Statistic_Locality_SaveFilters" Header="...aus Filtern speichern... (Excel)" | ||||
|                               Click="Menu_Statistic_Locality_SaveFilters_Click"/> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="BKI"> | ||||
|                 <MenuItem x:Name="Menu_Bki_SaveList" Header="Traubentransportscheinliste speichern..."/> | ||||
|             </MenuItem> | ||||
|   | ||||
| @@ -41,7 +41,7 @@ namespace Elwig.Windows { | ||||
|             CommandBindings.Add(new CommandBinding(CtrlP, Menu_DeliveryNote_Show_Click)); | ||||
|             CommandBindings.Add(new CommandBinding(CtrlO, Menu_DeliveryJournal_ShowFilters_Click)); | ||||
|             CommandBindings.Add(new CommandBinding(CtrlJ, Menu_DeliveryJournal_PrintToday_Click)); | ||||
|             CommandBindings.Add(new CommandBinding(CtrlQ, Menu_WineQualityStatistics_PrintToday_Click)); | ||||
|             CommandBindings.Add(new CommandBinding(CtrlQ, Menu_Statistics_WineQuality_PrintToday_Click)); | ||||
|             CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_DeliveryNote_Print_Click)); | ||||
|             CommandBindings.Add(new CommandBinding(CtrlShiftO, Menu_DeliveryJournal_PrintFilters_Click)); | ||||
|             RequiredInputs = [ | ||||
| @@ -97,17 +97,17 @@ namespace Elwig.Windows { | ||||
|                 WeighingDButton.Visibility = Visibility.Hidden; | ||||
|             } | ||||
|  | ||||
|             Menu_WineQualityStatistics_ModeOe.IsChecked = false; | ||||
|             Menu_WineQualityStatistics_ModeKmw1.IsChecked = false; | ||||
|             Menu_WineQualityStatistics_ModeKmw2.IsChecked = false; | ||||
|             Menu_WineQualityStatistics_ModeKmw5.IsChecked = false; | ||||
|             Menu_WineQualityStatistics_ModeKmw10.IsChecked = false; | ||||
|             Menu_Statistics_WineQuality_ModeOe.IsChecked = false; | ||||
|             Menu_Statistics_WineQuality_ModeKmw1.IsChecked = false; | ||||
|             Menu_Statistics_WineQuality_ModeKmw2.IsChecked = false; | ||||
|             Menu_Statistics_WineQuality_ModeKmw5.IsChecked = false; | ||||
|             Menu_Statistics_WineQuality_ModeKmw10.IsChecked = false; | ||||
|             switch (App.Client.OrderingMemberList) { | ||||
|                 case 0: Menu_WineQualityStatistics_ModeOe.IsChecked = true; break; | ||||
|                 case 1: Menu_WineQualityStatistics_ModeKmw1.IsChecked = true; break; | ||||
|                 case 2: Menu_WineQualityStatistics_ModeKmw2.IsChecked = true; break; | ||||
|                 case 3: Menu_WineQualityStatistics_ModeKmw5.IsChecked = true; break; | ||||
|                 case 4: Menu_WineQualityStatistics_ModeKmw10.IsChecked = true; break; | ||||
|                 case 0: Menu_Statistics_WineQuality_ModeOe.IsChecked = true; break; | ||||
|                 case 1: Menu_Statistics_WineQuality_ModeKmw1.IsChecked = true; break; | ||||
|                 case 2: Menu_Statistics_WineQuality_ModeKmw2.IsChecked = true; break; | ||||
|                 case 3: Menu_Statistics_WineQuality_ModeKmw5.IsChecked = true; break; | ||||
|                 case 4: Menu_Statistics_WineQuality_ModeKmw10.IsChecked = true; break; | ||||
|             } | ||||
|  | ||||
|             Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null; | ||||
| @@ -218,40 +218,44 @@ namespace Elwig.Windows { | ||||
|             await ViewModel.GenerateDeliveryJournal(DeliveryService.ExportSubject.FromSeasonAndBranch, ExportMode.Upload); | ||||
|         } | ||||
|  | ||||
|         private async void Menu_WineQualityStatistics_ShowToday_Click(object sender, RoutedEventArgs evt) => | ||||
|         private async void Menu_Statistics_WineQuality_ShowToday_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateWineQualityStatistics(DeliveryService.ExportSubject.FromToday, ExportMode.Show); | ||||
|         private async void Menu_WineQualityStatistics_SavePdfToday_Click(object sender, RoutedEventArgs evt) => | ||||
|         private async void Menu_Statistics_WineQuality_SavePdfToday_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateWineQualityStatistics(DeliveryService.ExportSubject.FromToday, ExportMode.SavePdf); | ||||
|         private async void Menu_WineQualityStatistics_PrintToday_Click(object sender, RoutedEventArgs evt) => | ||||
|         private async void Menu_Statistics_WineQuality_PrintToday_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateWineQualityStatistics(DeliveryService.ExportSubject.FromToday, ExportMode.Print); | ||||
|         private async void Menu_WineQualityStatistics_ShowFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|         private async void Menu_Statistics_WineQuality_ShowFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateWineQualityStatistics(DeliveryService.ExportSubject.FromFilters, ExportMode.Show); | ||||
|         private async void Menu_WineQualityStatistics_SavePdfFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|         private async void Menu_Statistics_WineQuality_SavePdfFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateWineQualityStatistics(DeliveryService.ExportSubject.FromFilters, ExportMode.SavePdf); | ||||
|         private async void Menu_WineQualityStatistics_PrintFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|         private async void Menu_Statistics_WineQuality_PrintFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateWineQualityStatistics(DeliveryService.ExportSubject.FromFilters, ExportMode.Print); | ||||
|  | ||||
|         private async void Menu_WineQualityStatistics_Mode_Click(object sender, RoutedEventArgs evt) { | ||||
|             Menu_WineQualityStatistics.IsSubmenuOpen = true; | ||||
|             if (sender == Menu_WineQualityStatistics_ModeOe) { | ||||
|         private async void Menu_Statistics_WineQuality_Mode_Click(object sender, RoutedEventArgs evt) { | ||||
|             Menu_Statistics.IsSubmenuOpen = true; | ||||
|             Menu_Statistics_WineQuality.IsSubmenuOpen = true; | ||||
|             if (sender == Menu_Statistics_WineQuality_ModeOe) { | ||||
|                 App.Client.OrderingMemberList = 0; | ||||
|             } else if (sender == Menu_WineQualityStatistics_ModeKmw1) { | ||||
|             } else if (sender == Menu_Statistics_WineQuality_ModeKmw1) { | ||||
|                 App.Client.OrderingMemberList = 1; | ||||
|             } else if (sender == Menu_WineQualityStatistics_ModeKmw2) { | ||||
|             } else if (sender == Menu_Statistics_WineQuality_ModeKmw2) { | ||||
|                 App.Client.OrderingMemberList = 2; | ||||
|             } else if (sender == Menu_WineQualityStatistics_ModeKmw5) { | ||||
|             } else if (sender == Menu_Statistics_WineQuality_ModeKmw5) { | ||||
|                 App.Client.OrderingMemberList = 3; | ||||
|             } else if (sender == Menu_WineQualityStatistics_ModeKmw10) { | ||||
|             } else if (sender == Menu_Statistics_WineQuality_ModeKmw10) { | ||||
|                 App.Client.OrderingMemberList = 4; | ||||
|             } | ||||
|             Menu_WineQualityStatistics_ModeOe.IsChecked = App.Client.OrderingMemberList == 0; | ||||
|             Menu_WineQualityStatistics_ModeKmw1.IsChecked = App.Client.OrderingMemberList == 1; | ||||
|             Menu_WineQualityStatistics_ModeKmw2.IsChecked = App.Client.OrderingMemberList == 2; | ||||
|             Menu_WineQualityStatistics_ModeKmw5.IsChecked = App.Client.OrderingMemberList == 3; | ||||
|             Menu_WineQualityStatistics_ModeKmw10.IsChecked = App.Client.OrderingMemberList == 4; | ||||
|             Menu_Statistics_WineQuality_ModeOe.IsChecked = App.Client.OrderingMemberList == 0; | ||||
|             Menu_Statistics_WineQuality_ModeKmw1.IsChecked = App.Client.OrderingMemberList == 1; | ||||
|             Menu_Statistics_WineQuality_ModeKmw2.IsChecked = App.Client.OrderingMemberList == 2; | ||||
|             Menu_Statistics_WineQuality_ModeKmw5.IsChecked = App.Client.OrderingMemberList == 3; | ||||
|             Menu_Statistics_WineQuality_ModeKmw10.IsChecked = App.Client.OrderingMemberList == 4; | ||||
|             await App.Client.UpdateValues(); | ||||
|         } | ||||
|  | ||||
|         private async void Menu_Statistic_Locality_SaveFilters_Click(object sender, RoutedEventArgs evt)=> | ||||
|             await ViewModel.GenerateLocalityStatistics(DeliveryService.ExportSubject.FromFilters); | ||||
|  | ||||
|         private async void Menu_DeliveryDepreciationList_SaveFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|             await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList); | ||||
|         private async void Menu_DeliveryDepreciationList_ShowFilters_Click(object sender, RoutedEventArgs evt) => | ||||
|   | ||||
		Reference in New Issue
	
	Block a user