[#30] Documents: Add WineQualityStatistics
This commit is contained in:
105
Elwig/Models/Dtos/WineQualityStatisticsData.cs
Normal file
105
Elwig/Models/Dtos/WineQualityStatisticsData.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using Elwig.Models.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Elwig.Models.Dtos {
|
||||
public class WineQualityStatisticsData {
|
||||
|
||||
public record struct QualityRow(string? Variety, string? Attribute, string? Cultivation, string? Type, string QualId, int Oe, int Weight);
|
||||
public record struct QualitySection(string Name, string? Type, Dictionary<string, (int Oe, int Weight)[]> Data);
|
||||
|
||||
public QualitySection[] Sections;
|
||||
|
||||
public WineQualityStatisticsData(QualitySection[] sections) {
|
||||
Sections = sections;
|
||||
}
|
||||
|
||||
private static QualitySection[] GetQualitySections(IEnumerable<QualityRow> rows) {
|
||||
var data = new List<QualitySection>();
|
||||
var currentQual = new Dictionary<int, int>();
|
||||
var current = new Dictionary<string, (int, int)[]>();
|
||||
string? lastSection = null;
|
||||
string? lastType = null;
|
||||
string? lastQual = null;
|
||||
foreach (var row in rows) {
|
||||
var sec = $"{row.Variety ?? (row.Type == "R" ? "Rotweinsorten" : row.Type == "W" ? "Weißweinsorten" : "Gesamt")}" +
|
||||
$"{(row.Attribute != null ? " / " : "")}{row.Attribute}" +
|
||||
$"{(row.Cultivation != null ? " / " : "")}{row.Cultivation}";
|
||||
if (lastQual != null && lastQual != row.QualId) {
|
||||
current[lastQual] = currentQual.Select(kv => (kv.Key, kv.Value)).ToArray();
|
||||
currentQual.Clear();
|
||||
}
|
||||
if (lastSection != null && lastSection != sec) {
|
||||
if (!current.ContainsKey(lastQual!)) {
|
||||
current[lastQual!] = currentQual.Select(kv => (kv.Key, kv.Value)).ToArray();
|
||||
currentQual.Clear();
|
||||
}
|
||||
data.Add(new(lastSection, lastType, current));
|
||||
current = [];
|
||||
currentQual.Clear();
|
||||
}
|
||||
currentQual[row.Oe] = row.Weight;
|
||||
lastSection = sec;
|
||||
lastType = row.Type;
|
||||
lastQual = row.QualId;
|
||||
}
|
||||
if (lastQual != null) {
|
||||
current[lastQual] = currentQual.Select(kv => (kv.Key, kv.Value)).ToArray();
|
||||
currentQual.Clear();
|
||||
}
|
||||
if (lastSection != null) {
|
||||
data.Add(new(lastSection, lastType, current));
|
||||
current = [];
|
||||
currentQual.Clear();
|
||||
}
|
||||
return [.. data];
|
||||
}
|
||||
|
||||
public static async Task<WineQualityStatisticsData> FromQuery(IQueryable<DeliveryPart> query) {
|
||||
var rows = (await query
|
||||
.GroupBy(p => new {
|
||||
p.Variety.Type,
|
||||
Variety = p.Variety.Name,
|
||||
Attribute = p.Attribute!.Name,
|
||||
Cultivation = p.Cultivation!.Name,
|
||||
p.QualId,
|
||||
Oe = (int)Math.Round(p.Kmw * (4.54 + 0.022 * p.Kmw), 0),
|
||||
}, (k, g) => new { Key = k, Weight = g.Sum(p => p.Weight) })
|
||||
.OrderBy(g => g.Key.Variety)
|
||||
.ThenBy(g => g.Key.Attribute)
|
||||
.ThenBy(g => g.Key.Cultivation)
|
||||
.ThenBy(g => g.Key.QualId)
|
||||
.ThenBy(g => g.Key.Oe)
|
||||
.ToListAsync())
|
||||
.Select(r => new QualityRow(r.Key.Variety, r.Key.Attribute, r.Key.Cultivation, r.Key.Type, r.Key.QualId, r.Key.Oe, r.Weight))
|
||||
.ToList();
|
||||
|
||||
var data = GetQualitySections(rows);
|
||||
if (data.Length <= 1)
|
||||
return new(data);
|
||||
|
||||
var typeRows = rows
|
||||
.GroupBy(s => new { s.Type, s.QualId, s.Oe }, (k, g) => new QualityRow(null, null, null, k.Type, k.QualId, k.Oe, g.Sum(p => p.Weight)))
|
||||
.OrderBy(g => g.Type)
|
||||
.ThenBy(g => g.QualId)
|
||||
.ThenBy(g => g.Oe)
|
||||
.ToList();
|
||||
var typeData = GetQualitySections(typeRows);
|
||||
if (typeData.Length <= 1)
|
||||
return new([.. typeData, .. data]);
|
||||
|
||||
var totalRows = rows
|
||||
.GroupBy(s => new { s.QualId, s.Oe }, (k, g) => new QualityRow(null, null, null, null, k.QualId, k.Oe, g.Sum(p => p.Weight)))
|
||||
.OrderBy(g => g.QualId)
|
||||
.ThenBy(g => g.Oe)
|
||||
.ToList();
|
||||
var totalData = GetQualitySections(totalRows);
|
||||
return new([.. totalData, .. typeData, .. data]);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user