From c5453c2fe639c5c2d7e8faacdf5087879f536083 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 9 Nov 2024 16:13:28 +0100 Subject: [PATCH] =?UTF-8?q?MainWindow:=20Add=20'Fl=C3=A4chenbindungen'=20a?= =?UTF-8?q?nd=20'Liefermenge/Ertrag'=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Elwig/Helpers/AppDbContext.cs | 1 + Elwig/Models/Dtos/MemberAreaComsData.cs | 105 ++++++++++++++++++ ...ata.cs => MemberDeliveryPerVarietyData.cs} | 9 +- Elwig/Windows/MainWindow.xaml | 58 ++++++++-- Elwig/Windows/MainWindow.xaml.cs | 78 +++++++++++-- 5 files changed, 225 insertions(+), 26 deletions(-) create mode 100644 Elwig/Models/Dtos/MemberAreaComsData.cs rename Elwig/Models/Dtos/{MemberDeliveryPerVariantData.cs => MemberDeliveryPerVarietyData.cs} (95%) diff --git a/Elwig/Helpers/AppDbContext.cs b/Elwig/Helpers/AppDbContext.cs index 3325259..adcfa44 100644 --- a/Elwig/Helpers/AppDbContext.cs +++ b/Elwig/Helpers/AppDbContext.cs @@ -68,6 +68,7 @@ namespace Elwig.Helpers { public DbSet OverUnderDeliveryRows { get; private set; } public DbSet AreaComUnderDeliveryRows { get; private set; } public DbSet MemberDeliveryPerVariantRows { get; private set; } + public DbSet MemberAreaComsRows { get; private set; } public DbSet CreditNoteDeliveryRows { get; private set; } public DbSet CreditNoteRows { get; private set; } public DbSet WeightBreakDownRows { get; private set; } diff --git a/Elwig/Models/Dtos/MemberAreaComsData.cs b/Elwig/Models/Dtos/MemberAreaComsData.cs new file mode 100644 index 0000000..3ed7782 --- /dev/null +++ b/Elwig/Models/Dtos/MemberAreaComsData.cs @@ -0,0 +1,105 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Threading.Tasks; + +namespace Elwig.Models.Dtos { + class MemberAreaComsData : DataTable { + + private static readonly (string, string, string?, int)[] FieldNames = [ + ("MgNr", "MgNr.", null, 12), + ("Name1", "Name", null, 40), + ("Name2", "Vorname", null, 40), + ("Address", "Adresse", null, 60), + ("Plz", "PLZ", null, 10), + ("Locality", "Ort", null, 60), + ("SortIds", "Sorte", null, 12), + ("AttrIds", "Attribut", null, 16), + ("Areas", "Fläche", "m²", 22), + ("DeliveryObligations", "Lieferpflicht", "kg", 22), + ("DeliveryRights", "Lieferrecht", "kg", 22), + ]; + + public MemberAreaComsData(IEnumerable rows, int year) : + base($"Flächenbindungen", $"Flächenbindungen pro Mitglied {year}", rows, FieldNames) { + } + + public static async Task ForSeason(DbSet table, int year) { + return new MemberAreaComsData( + (await FromDbSet(table, year)).GroupBy( + r => r.MgNr, + (k, g) => new MemberAreaComsRow(g) + ), year); + } + + private static async Task> FromDbSet(DbSet table, int year) { + return await table.FromSql($""" + SELECT m.mgnr, m.name AS name_1, + COALESCE(m.prefix || ' ', '') || m.given_name || + COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, + p.plz, o.name AS ort, m.address, + c.bucket, c.area, c.min_kg, c.max_kg + FROM v_area_commitment_bucket_strict c + LEFT JOIN member m ON m.mgnr = c.mgnr + LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest + LEFT JOIN AT_ort o ON o.okz = p.okz + WHERE c.year = {year} + ORDER BY m.mgnr, c.bucket + """).ToListAsync(); + } + } + + public class MemberAreaComsRow { + public int MgNr; + public string Name1; + public string? Name2; + public string Address; + public int Plz; + public string Locality; + public string[] SortIds; + public string[] AttrIds; + public int[] Areas; + public int[] DeliveryObligations; + public int[] DeliveryRights; + + public MemberAreaComsRow(IEnumerable rows) { + var f = rows.First(); + MgNr = f.MgNr; + Name1 = f.Name1; + Name2 = f.Name2; + Address = f.Address; + Plz = f.Plz; + Locality = f.Locality.Split(",")[0]; + SortIds = rows.Select(r => r.VtrgId[..2]).ToArray(); + AttrIds = rows.Select(r => r.VtrgId[2..]).ToArray(); + Areas = rows.Select(r => r.Area).ToArray(); + DeliveryObligations = rows.Select(r => r.MinKg).ToArray(); + DeliveryRights = rows.Select(r => r.MaxKg).ToArray(); + } + } + + [Keyless] + public class MemberAreaComsRowSingle { + [Column("mgnr")] + public int MgNr { get; set; } + [Column("name_1")] + public required string Name1 { get; set; } + [Column("name_2")] + public string? Name2 { get; set; } + [Column("address")] + public required string Address { get; set; } + [Column("plz")] + public int Plz { get; set; } + [Column("ort")] + public required string Locality { get; set; } + [Column("bucket")] + public required string VtrgId { get; set; } + [Column("area")] + public int Area { get; set; } + [Column("min_kg")] + public int MinKg { get; set; } + [Column("max_kg")] + public int MaxKg { get; set; } + } +} diff --git a/Elwig/Models/Dtos/MemberDeliveryPerVariantData.cs b/Elwig/Models/Dtos/MemberDeliveryPerVarietyData.cs similarity index 95% rename from Elwig/Models/Dtos/MemberDeliveryPerVariantData.cs rename to Elwig/Models/Dtos/MemberDeliveryPerVarietyData.cs index b8bd3da..5575f66 100644 --- a/Elwig/Models/Dtos/MemberDeliveryPerVariantData.cs +++ b/Elwig/Models/Dtos/MemberDeliveryPerVarietyData.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Threading.Tasks; namespace Elwig.Models.Dtos { - public class MemberDeliveryPerVariantData : DataTable { + public class MemberDeliveryPerVarietyData : DataTable { private static readonly (string, string, string?, int)[] FieldNames = [ ("MgNr", "MgNr.", null, 12), @@ -22,13 +22,12 @@ namespace Elwig.Models.Dtos { ("Yields", "Ertrag", "kg/ha", 22), ]; - - public MemberDeliveryPerVariantData(IEnumerable rows, int year) : + public MemberDeliveryPerVarietyData(IEnumerable rows, int year) : base($"Liefermengen", $"Liefermengen pro Mitglied, Sorte und Attribut {year}", rows, FieldNames) { } - public static async Task ForSeason(DbSet table, int year) { - return new MemberDeliveryPerVariantData( + public static async Task ForSeason(DbSet table, int year) { + return new MemberDeliveryPerVarietyData( (await FromDbSet(table, year)).GroupBy( r => r.MgNr, (k, g) => new MemberDeliveryPerVariantRow(g) diff --git a/Elwig/Windows/MainWindow.xaml b/Elwig/Windows/MainWindow.xaml index 279c9a2..438c1eb 100644 --- a/Elwig/Windows/MainWindow.xaml +++ b/Elwig/Windows/MainWindow.xaml @@ -90,23 +90,59 @@ Margin="0,13,0,0" VerticalAlignment="Top" HorizontalAlignment="Center" TextChanged="SeasonInput_TextChanged"/> - + + + + + + + + diff --git a/Elwig/Windows/MainWindow.xaml.cs b/Elwig/Windows/MainWindow.xaml.cs index c333871..f97c691 100644 --- a/Elwig/Windows/MainWindow.xaml.cs +++ b/Elwig/Windows/MainWindow.xaml.cs @@ -251,7 +251,7 @@ namespace Elwig.Windows { } private void SeasonFinish_Expanded(object sender, RoutedEventArgs evt) { - Height = 610; + Height = 660; } private void SeasonFinish_Collapsed(object sender, RoutedEventArgs evt) { @@ -264,9 +264,11 @@ namespace Elwig.Windows { var s0 = await ctx.Seasons.FindAsync(year); var valid = (s0 != null); DeliveryConfirmationButton.IsEnabled = valid; - OverUnderDeliveryButton.IsEnabled = valid; PaymentButton.IsEnabled = valid; + OverUnderDeliveryButton.IsEnabled = valid; BreakdownButton.IsEnabled = valid; + AreaCommitmentsButton.IsEnabled = valid; + BreakdownMemberVarietyButton.IsEnabled = valid; if (valid) { var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value); @@ -295,6 +297,12 @@ namespace Elwig.Windows { w.AddDeliveryConfirmation(); } + private void PaymentButton_Click(object sender, RoutedEventArgs evt) { + if (SeasonInput.Value is not int year) + return; + App.FocusPaymentVariants(year); + } + private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) { if (SeasonInput.Value is not int year) return; @@ -317,23 +325,15 @@ namespace Elwig.Windows { using var ctx = new AppDbContext(); var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year); var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year); - var tbl3 = await MemberDeliveryPerVariantData.ForSeason(ctx.MemberDeliveryPerVariantRows, year); using var ods = new OdsFile(d.FileName); await ods.AddTable(tbl1); await ods.AddTable(tbl2); - await ods.AddTable(tbl3); } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } - private void PaymentButton_Click(object sender, RoutedEventArgs evt) { - if (SeasonInput.Value is not int year) - return; - App.FocusPaymentVariants(year); - } - private async void BreakdownButton_Click(object sender, RoutedEventArgs evt) { if (SeasonInput.Value is not int year) return; @@ -366,5 +366,63 @@ namespace Elwig.Windows { } Mouse.OverrideCursor = null; } + + private async void AreaCommitmentsButton_Click(object sender, RoutedEventArgs evt) { + if (SeasonInput.Value is not int year) + return; + var d = new SaveFileDialog() { + FileName = $"Flächenbindungen-{year}.ods", + DefaultExt = "ods", + Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", + Title = $"Flächenbindungen {year} speichern unter - Elwig" + }; + if (d.ShowDialog() == false) + return; + + Mouse.OverrideCursor = Cursors.AppStarting; + try { + var b = new Billing(year); + await b.FinishSeason(); + await b.CalculateBuckets(); + App.HintContextChange(); + + using var ctx = new AppDbContext(); + var tbl = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year); + using var ods = new OdsFile(d.FileName); + await ods.AddTable(tbl); + } catch (Exception exc) { + MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); + } + Mouse.OverrideCursor = null; + } + + private async void BreakdownMemberVarietyButton_Click(object sender, RoutedEventArgs evt) { + if (SeasonInput.Value is not int year) + return; + var d = new SaveFileDialog() { + FileName = $"Liefermengen-Ertrag-{year}.ods", + DefaultExt = "ods", + Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", + Title = $"Liefermengen/Ertrag {year} speichern unter - Elwig" + }; + if (d.ShowDialog() == false) + return; + + Mouse.OverrideCursor = Cursors.AppStarting; + try { + var b = new Billing(year); + await b.FinishSeason(); + await b.CalculateBuckets(); + App.HintContextChange(); + + using var ctx = new AppDbContext(); + var tbl = await MemberDeliveryPerVarietyData.ForSeason(ctx.MemberDeliveryPerVariantRows, year); + using var ods = new OdsFile(d.FileName); + await ods.AddTable(tbl); + } catch (Exception exc) { + MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); + } + Mouse.OverrideCursor = null; + } } }