[#30] WineQualityStatistics: Add number of deliveries
This commit is contained in:
@ -27,14 +27,16 @@
|
|||||||
<td class="container">
|
<td class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="units">[°Oe]</span>
|
<span class="units">[°Oe]</span>
|
||||||
|
<span class="units">[#]</span>
|
||||||
<span class="units">[kg]</span>
|
<span class="units">[kg]</span>
|
||||||
</div>
|
</div>
|
||||||
@foreach (var qualId in qualIds) {
|
@foreach (var qualId in qualIds) {
|
||||||
<h4>@(Model.QualityLevels.GetValueOrDefault(qualId, qualId))</h4>
|
<h4>@(Model.QualityLevels.GetValueOrDefault(qualId, qualId))</h4>
|
||||||
@foreach (var (oe, weight) in sec.Data.GetValueOrDefault(qualId, Array.Empty<(int, int)>())) {
|
@foreach (var (oe, num, weight) in sec.Data.GetValueOrDefault(qualId, Array.Empty<(int, int, int)>())) {
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="oe">@oe</span>
|
<span class="oe">@oe</span>
|
||||||
<span class="weight">@($"{weight:N0}")</span>
|
<span class="number">@($"{num:N0}")</span>
|
||||||
|
<span class="number">@($"{weight:N0}")</span>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,13 +45,15 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@foreach (var qualIds in Model.QualIds) {
|
@foreach (var qualIds in Model.QualIds) {
|
||||||
var quals = qualIds.Select(q => sec.Data.GetValueOrDefault(q, Array.Empty<(int, int)>()));
|
var quals = qualIds.Select(q => sec.Data.GetValueOrDefault(q, Array.Empty<(int Oe, int Num, int Weight)>()));
|
||||||
var weight = quals.Sum(q => q.Sum(kv => kv.Item2));
|
var weight = quals.Sum(q => q.Sum(kv => kv.Weight));
|
||||||
var oe = quals.Sum(q => q.Sum(kv => (double)kv.Item1 * kv.Item2)) / weight;
|
var num = quals.Sum(q => q.Sum(kv => kv.Num));
|
||||||
|
var oe = quals.Sum(q => q.Sum(kv => (double)kv.Oe * kv.Weight)) / weight;
|
||||||
<td class="container bold">
|
<td class="container bold">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="oe">@(weight == 0 ? "" : $"{oe:N0}")</span>
|
<span class="oe">@(weight == 0 ? "-" : $"{oe:N0}")</span>
|
||||||
<span class="weight">@($"{weight:N0}")</span>
|
<span class="number">@($"{num:N0}")</span>
|
||||||
|
<span class="number">@($"{weight:N0}")</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
@ -59,12 +63,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
@{
|
@{
|
||||||
var totalWeight = sec.Data.Values.Sum(q => q.Sum(kv => kv.Weight));
|
var totalWeight = sec.Data.Values.Sum(q => q.Sum(kv => kv.Weight));
|
||||||
|
var totalNum = sec.Data.Values.Sum(q => q.Sum(kv => kv.Num));
|
||||||
var totalOe = sec.Data.Values.Sum(q => q.Sum(kv => (double)kv.Oe * kv.Weight)) / totalWeight;
|
var totalOe = sec.Data.Values.Sum(q => q.Sum(kv => (double)kv.Oe * kv.Weight)) / totalWeight;
|
||||||
}
|
}
|
||||||
<td colspan="4" class="container bold footer @(sec.Type == "R" ? "red" : sec.Type == "W" ? "green" : "")">
|
<td colspan="4" class="container bold footer @(sec.Type == "R" ? "red" : sec.Type == "W" ? "green" : "")">
|
||||||
<div class="row" style="width: 24%; margin-left: 76%;">
|
<div class="row" style="width: 24%; margin-left: 76%;">
|
||||||
<span class="oe">@(totalWeight == 0 ? "" : $"{totalOe:N0}")</span>
|
<span class="oe">@(totalWeight == 0 ? "-" : $"{totalOe:N0}")</span>
|
||||||
<span class="weight">@($"{totalWeight:N0}")</span>
|
<span class="number">@($"{totalNum:N0}")</span>
|
||||||
|
<span class="number">@($"{totalWeight:N0}")</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -88,6 +88,9 @@ table .footer.green {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.weight {
|
.number {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row span:first-child { flex-basis: 7.5mm; }
|
||||||
|
.row span:last-child { flex-basis: 15mm; }
|
||||||
|
@ -10,8 +10,8 @@ using System.Windows;
|
|||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class WineQualityStatisticsData {
|
public class WineQualityStatisticsData {
|
||||||
|
|
||||||
public record struct QualityRow(string? Variety, string? Attribute, string? Cultivation, string? Type, string QualId, int Oe, int Weight);
|
public record struct QualityRow(string? Variety, string? Attribute, string? Cultivation, string? Type, string QualId, int Oe, int Num, int Weight);
|
||||||
public record struct QualitySection(string Name, string? Type, Dictionary<string, (int Oe, int Weight)[]> Data);
|
public record struct QualitySection(string Name, string? Type, Dictionary<string, (int Oe, int Num, int Weight)[]> Data);
|
||||||
|
|
||||||
public QualitySection[] Sections;
|
public QualitySection[] Sections;
|
||||||
|
|
||||||
@ -21,8 +21,8 @@ namespace Elwig.Models.Dtos {
|
|||||||
|
|
||||||
private static QualitySection[] GetQualitySections(IEnumerable<QualityRow> rows) {
|
private static QualitySection[] GetQualitySections(IEnumerable<QualityRow> rows) {
|
||||||
var data = new List<QualitySection>();
|
var data = new List<QualitySection>();
|
||||||
var currentQual = new Dictionary<int, int>();
|
var currentQual = new Dictionary<int, (int Num, int Weight)>();
|
||||||
var current = new Dictionary<string, (int, int)[]>();
|
var current = new Dictionary<string, (int, int, int)[]>();
|
||||||
string? lastSection = null;
|
string? lastSection = null;
|
||||||
string? lastType = null;
|
string? lastType = null;
|
||||||
string? lastQual = null;
|
string? lastQual = null;
|
||||||
@ -31,25 +31,25 @@ namespace Elwig.Models.Dtos {
|
|||||||
$"{(row.Attribute != null ? " / " : "")}{row.Attribute}" +
|
$"{(row.Attribute != null ? " / " : "")}{row.Attribute}" +
|
||||||
$"{(row.Cultivation != null ? " / " : "")}{row.Cultivation}";
|
$"{(row.Cultivation != null ? " / " : "")}{row.Cultivation}";
|
||||||
if (lastQual != null && lastQual != row.QualId) {
|
if (lastQual != null && lastQual != row.QualId) {
|
||||||
current[lastQual] = currentQual.Select(kv => (kv.Key, kv.Value)).ToArray();
|
current[lastQual] = currentQual.Select(kv => (kv.Key, kv.Value.Num, kv.Value.Weight)).ToArray();
|
||||||
currentQual.Clear();
|
currentQual.Clear();
|
||||||
}
|
}
|
||||||
if (lastSection != null && lastSection != sec) {
|
if (lastSection != null && lastSection != sec) {
|
||||||
if (!current.ContainsKey(lastQual!)) {
|
if (!current.ContainsKey(lastQual!)) {
|
||||||
current[lastQual!] = currentQual.Select(kv => (kv.Key, kv.Value)).ToArray();
|
current[lastQual!] = currentQual.Select(kv => (kv.Key, kv.Value.Num, kv.Value.Weight)).ToArray();
|
||||||
currentQual.Clear();
|
currentQual.Clear();
|
||||||
}
|
}
|
||||||
data.Add(new(lastSection, lastType, current));
|
data.Add(new(lastSection, lastType, current));
|
||||||
current = [];
|
current = [];
|
||||||
currentQual.Clear();
|
currentQual.Clear();
|
||||||
}
|
}
|
||||||
currentQual[row.Oe] = row.Weight;
|
currentQual[row.Oe] = (row.Num, row.Weight);
|
||||||
lastSection = sec;
|
lastSection = sec;
|
||||||
lastType = row.Type;
|
lastType = row.Type;
|
||||||
lastQual = row.QualId;
|
lastQual = row.QualId;
|
||||||
}
|
}
|
||||||
if (lastQual != null) {
|
if (lastQual != null) {
|
||||||
current[lastQual] = currentQual.Select(kv => (kv.Key, kv.Value)).ToArray();
|
current[lastQual] = currentQual.Select(kv => (kv.Key, kv.Value.Num, kv.Value.Weight)).ToArray();
|
||||||
currentQual.Clear();
|
currentQual.Clear();
|
||||||
}
|
}
|
||||||
if (lastSection != null) {
|
if (lastSection != null) {
|
||||||
@ -69,14 +69,14 @@ namespace Elwig.Models.Dtos {
|
|||||||
Cultivation = p.Cultivation!.Name,
|
Cultivation = p.Cultivation!.Name,
|
||||||
p.QualId,
|
p.QualId,
|
||||||
Oe = (int)Math.Round(p.Kmw * (4.54 + 0.022 * p.Kmw), 0),
|
Oe = (int)Math.Round(p.Kmw * (4.54 + 0.022 * p.Kmw), 0),
|
||||||
}, (k, g) => new { Key = k, Weight = g.Sum(p => p.Weight) })
|
}, (k, g) => new { Key = k, Num = g.Count(), Weight = g.Sum(p => p.Weight) })
|
||||||
.OrderBy(g => g.Key.Variety)
|
.OrderBy(g => g.Key.Variety)
|
||||||
.ThenBy(g => g.Key.Attribute)
|
.ThenBy(g => g.Key.Attribute)
|
||||||
.ThenBy(g => g.Key.Cultivation)
|
.ThenBy(g => g.Key.Cultivation)
|
||||||
.ThenBy(g => g.Key.QualId)
|
.ThenBy(g => g.Key.QualId)
|
||||||
.ThenBy(g => g.Key.Oe)
|
.ThenBy(g => g.Key.Oe)
|
||||||
.ToListAsync())
|
.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))
|
.Select(r => new QualityRow(r.Key.Variety, r.Key.Attribute, r.Key.Cultivation, r.Key.Type, r.Key.QualId, r.Key.Oe, r.Num, r.Weight))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var data = GetQualitySections(rows);
|
var data = GetQualitySections(rows);
|
||||||
@ -84,7 +84,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
return new(data);
|
return new(data);
|
||||||
|
|
||||||
var typeRows = rows
|
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)))
|
.GroupBy(s => new { s.Type, s.QualId, s.Oe }, (k, g) => new QualityRow(null, null, null, k.Type, k.QualId, k.Oe, g.Sum(g => g.Num), g.Sum(p => p.Weight)))
|
||||||
.OrderBy(g => g.Type)
|
.OrderBy(g => g.Type)
|
||||||
.ThenBy(g => g.QualId)
|
.ThenBy(g => g.QualId)
|
||||||
.ThenBy(g => g.Oe)
|
.ThenBy(g => g.Oe)
|
||||||
@ -94,7 +94,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
return new([.. typeData, .. data]);
|
return new([.. typeData, .. data]);
|
||||||
|
|
||||||
var totalRows = rows
|
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)))
|
.GroupBy(s => new { s.QualId, s.Oe }, (k, g) => new QualityRow(null, null, null, null, k.QualId, k.Oe, g.Sum(p => p.Num), g.Sum(p => p.Weight)))
|
||||||
.OrderBy(g => g.QualId)
|
.OrderBy(g => g.QualId)
|
||||||
.ThenBy(g => g.Oe)
|
.ThenBy(g => g.Oe)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
Reference in New Issue
Block a user