From 4229fbbef60b138788fe3de8ae98b95158bc76d8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 5 Jul 2024 21:27:32 +0200 Subject: [PATCH] [#26] AreaComService: Add GenerateToolTip() --- Elwig/Models/Entities/Member.cs | 4 +- Elwig/Services/AreaComService.cs | 102 +++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/Elwig/Models/Entities/Member.cs b/Elwig/Models/Entities/Member.cs index a5612fd..af70440 100644 --- a/Elwig/Models/Entities/Member.cs +++ b/Elwig/Models/Entities/Member.cs @@ -156,8 +156,8 @@ namespace Elwig.Models.Entities { [InverseProperty(nameof(AreaCom.Member))] public virtual ICollection AreaCommitments { get; private set; } = null!; - public IQueryable ActiveAreaCommitments(AppDbContext ctx) { - return ctx.AreaCommitments.Where(c => c.MgNr == MgNr).Where(Utils.ActiveAreaCommitments()); + public IQueryable ActiveAreaCommitments(AppDbContext ctx, int? year = null) { + return ctx.AreaCommitments.Where(c => c.MgNr == MgNr).Where(Utils.ActiveAreaCommitments(year ?? Utils.CurrentYear)); } [InverseProperty(nameof(BillingAddr.Member))] diff --git a/Elwig/Services/AreaComService.cs b/Elwig/Services/AreaComService.cs index 7ff4915..c9141b0 100644 --- a/Elwig/Services/AreaComService.cs +++ b/Elwig/Services/AreaComService.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows; namespace Elwig.Services { public static class AreaComService { @@ -123,5 +125,105 @@ namespace Elwig.Services { return newFbNr; } + + private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) { + var tb = new TextBlock() { + Text = text, + TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left, + Margin = new(0, 12 * row, 0, 0), + FontWeight = bold ? FontWeights.Bold : FontWeights.Normal, + }; + tb.SetValue(Grid.ColumnProperty, col); + tb.SetValue(Grid.ColumnSpanProperty, colSpan); + grid.Children.Add(tb); + } + + private static void AddToolTipRow(Grid grid, int row, string? h1, string? h2, int area, int? min, int? max) { + var bold = h2 == null; + if (h1 != null) AddToolTipCell(grid, h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold); + if (h2 != null) AddToolTipCell(grid, h2 + ":", row, 1, 1, bold); + AddToolTipCell(grid, $"{area:N0} m²", row, 2, 1, bold, true); + AddToolTipCell(grid, min == null ? "" : $"{min:N0} kg", row, 3, 1, bold, true); + AddToolTipCell(grid, max == null ? "" : $"{max:N0} kg", row, 4, 1, bold, true); + } + + public static async Task<(string, Grid)> GenerateToolTip(IQueryable areaComs, int maxKgPerHa) { + var grid = new Grid(); + grid.ColumnDefinitions.Add(new() { Width = new(10) }); + grid.ColumnDefinitions.Add(new() { Width = new(60) }); + grid.ColumnDefinitions.Add(new() { Width = new(80) }); + grid.ColumnDefinitions.Add(new() { Width = new(80) }); + grid.ColumnDefinitions.Add(new() { Width = new(80) }); + AddToolTipCell(grid, "Lieferpflicht", 0, 3, 1, false, false, true); + AddToolTipCell(grid, "Lieferrecht", 0, 4, 1, false, false, true); + var text = "-"; + + var area = await areaComs.SumAsync(p => p.Area); + text = $"{area:N0} m²"; + AddToolTipRow(grid, 1, "Geb. Fläche", null, area, null, null); + + if (await areaComs.AnyAsync()) { + var attrGroups = await areaComs + .Where(c => c.AreaComType.WineAttr != null) + .GroupBy(c => c.AreaComType.WineAttr!.Name) + .Select(g => new { + Attr = g.Key, + Area = g.Sum(c => c.Area), + Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000), + Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000), + }) + .OrderByDescending(g => g.Area) + .ThenBy(g => g.Attr) + .ToListAsync(); + var groups = await areaComs + .Where(c => c.AreaComType.WineAttr != null) + .GroupBy(c => new { + Attr = c.AreaComType.WineAttr!.Name, + c.AreaComType.SortId, + }) + .Select(g => new { + g.Key.Attr, + g.Key.SortId, + Area = g.Sum(c => c.Area), + Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000), + Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000), + }) + .OrderByDescending(g => g.Area) + .ThenBy(g => g.Attr) + .ThenBy(g => g.SortId) + .ToListAsync(); + + var noAttr = await areaComs + .Where(c => c.AreaComType.WineAttr == null || !c.AreaComType.WineAttr.IsStrict) + .GroupBy(c => c.AreaComType.SortId) + .Select(g => new { + SortId = g.Key, + Area = g.Sum(c => c.Area), + Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000), + Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000), + }) + .OrderByDescending(g => g.Area) + .ThenBy(g => g.SortId) + .ToListAsync(); + + int rowNum = 2; + if (noAttr.Count > 0) { + rowNum++; + AddToolTipRow(grid, rowNum++, null, null, noAttr.Sum(g => g.Area), noAttr.Sum(g => g.Min), noAttr.Sum(g => g.Max)); + foreach (var g in noAttr) { + AddToolTipRow(grid, rowNum++, null, g.SortId, g.Area, g.Min, g.Max); + } + } + foreach (var attrG in attrGroups) { + rowNum++; + AddToolTipRow(grid, rowNum++, attrG.Attr, null, attrG.Area, attrG.Min, attrG.Max); + foreach (var g in groups.Where(g => g.Attr == attrG.Attr).OrderByDescending(g => g.Area).ThenBy(g => g.SortId)) { + AddToolTipRow(grid, rowNum++, null, g.SortId, g.Area, g.Min, g.Max); + } + } + } + + return (text, grid); + } } }