[#34] Second step of not using Bio as Attribute

This commit is contained in:
2024-02-20 16:36:12 +01:00
parent 049927f90c
commit c82e8de724
9 changed files with 140 additions and 77 deletions

View File

@ -150,38 +150,33 @@ namespace Elwig.Helpers.Billing {
return dict; return dict;
} }
protected static Dictionary<string, JsonValue> GetSelection(JsonNode value, IEnumerable<string> vaributes) { protected static Dictionary<RawVaribute, JsonValue> GetSelection(JsonNode value, IEnumerable<RawVaribute> vaributes) {
if (value is JsonValue flatRate) { if (value is JsonValue flatRate) {
return vaributes.ToDictionary(e => e, _ => flatRate); return vaributes.ToDictionary(e => e, _ => flatRate);
} if (value is not JsonObject data) { } if (value is not JsonObject data) {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
Dictionary<string, JsonValue> dict; Dictionary<RawVaribute, JsonValue> dict;
if (data["default"] is JsonValue def) { if (data["default"] is JsonValue def) {
dict = vaributes.ToDictionary(e => e, _ => def); dict = vaributes.ToDictionary(e => e, _ => def);
} else { } else {
dict = []; dict = [];
} }
var varieties = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length == 2); var conv = data
var attributes = data.Where(p => p.Key.StartsWith('/')); .Where(p => p.Key != "default")
var others = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length > 2 && p.Key != "default"); .Select(p => (new RawVaribute(p.Key), p.Value))
foreach (var (idx, v) in varieties) { .OrderBy(p => (p.Item1.SortId != null ? 10 : 0) + (p.Item1.AttrId != null ? 12 : 0) + (p.Item1.CultId != null ? 11 : 0))
.ToList();
foreach (var (idx, v) in conv) {
var curve = v?.AsValue() ?? throw new InvalidOperationException(); var curve = v?.AsValue() ?? throw new InvalidOperationException();
foreach (var i in vaributes.Where(e => e.StartsWith(idx[..^1]))) { foreach (var i in vaributes.Where(e =>
(idx.SortId == null || idx.SortId == e.SortId) &&
(idx.AttrId == null || idx.AttrId == e.AttrId) &&
(idx.CultId == null || idx.CultId == e.CultId))) {
dict[i] = curve; dict[i] = curve;
} }
} }
foreach (var (idx, v) in attributes) {
var curve = v?.AsValue() ?? throw new InvalidOperationException();
foreach (var i in vaributes.Where(e => e[2..] == idx[1..])) {
dict[i] = curve;
}
}
foreach (var (idx, v) in others) {
var curve = v?.AsValue() ?? throw new InvalidOperationException();
dict[idx.Replace("/", "")] = curve;
}
return dict; return dict;
} }
@ -257,7 +252,7 @@ namespace Elwig.Helpers.Billing {
return curve; return curve;
} }
protected static void CollapsePaymentData(JsonObject data, IEnumerable<string> vaributes, bool useDefault = true) { protected static void CollapsePaymentData(JsonObject data, IEnumerable<RawVaribute> vaributes, bool useDefault = true) {
Dictionary<string, List<string>> rev1 = []; Dictionary<string, List<string>> rev1 = [];
Dictionary<decimal, List<string>> rev2 = []; Dictionary<decimal, List<string>> rev2 = [];
foreach (var (k, v) in data) { foreach (var (k, v) in data) {
@ -292,23 +287,23 @@ namespace Elwig.Helpers.Billing {
var attributes = data var attributes = data
.Select(e => e.Key) .Select(e => e.Key)
.Where(k => k.Length > 3 && k.Contains('/')) .Where(k => k.Length > 3 && k.Contains('/'))
.Select(k => "/" + k.Split('/')[1]) .Select(k => k.Split('/')[1])
.Distinct() .Distinct()
.ToList(); .ToList();
foreach (var idx in attributes) { foreach (var idx in attributes) {
var len = vaributes.Count(e => e.EndsWith(idx)); var len = vaributes.Count(e => e.AttrId == idx);
foreach (var (v, ks) in rev1) { foreach (var (v, ks) in rev1) {
var myKs = ks.Where(k => k.EndsWith(idx)).ToList(); var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
if (myKs.Count > 1 && ((myKs.Count >= len * 0.5 && useDefault) || myKs.Count == len)) { if (myKs.Count > 1 && ((myKs.Count >= len * 0.5 && useDefault) || myKs.Count == len)) {
foreach (var k in myKs) data.Remove(k); foreach (var k in myKs) data.Remove(k);
data[idx] = v; data[$"/{idx}"] = v;
} }
} }
foreach (var (v, ks) in rev2) { foreach (var (v, ks) in rev2) {
var myKs = ks.Where(k => k.EndsWith(idx)).ToList(); var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
if (myKs.Count > 1 && ((myKs.Count >= len * 0.5 && useDefault) || myKs.Count == len)) { if (myKs.Count > 1 && ((myKs.Count >= len * 0.5 && useDefault) || myKs.Count == len)) {
foreach (var k in myKs) data.Remove(k); foreach (var k in myKs) data.Remove(k);
data[idx] = v; data[$"/{idx}"] = v;
} }
} }
} }
@ -317,7 +312,7 @@ namespace Elwig.Helpers.Billing {
public static JsonObject FromGraphEntries( public static JsonObject FromGraphEntries(
IEnumerable<GraphEntry> graphEntries, IEnumerable<GraphEntry> graphEntries,
BillingData? origData = null, BillingData? origData = null,
IEnumerable<string>? vaributes = null, IEnumerable<RawVaribute>? vaributes = null,
bool useDefaultPayment = true, bool useDefaultPayment = true,
bool useDefaultQuality = true bool useDefaultQuality = true
) { ) {
@ -338,16 +333,16 @@ namespace Elwig.Helpers.Billing {
continue; continue;
} }
foreach (var c in entry.Vaributes) { foreach (var c in entry.Vaributes) {
if (entry.Abgewertet) { if (entry.Abgewertet) {;
qualityWei[$"{c.Variety?.SortId}/{c.Attribute?.AttrId}"] = node.DeepClone(); qualityWei[c.ToString()] = node.DeepClone();
} else { } else {
payment[$"{c.Variety?.SortId}/{c.Attribute?.AttrId}"] = node.DeepClone(); payment[c.ToString()] = node.DeepClone();
} }
} }
} }
CollapsePaymentData(payment, vaributes ?? payment.Select(e => e.Key).ToList(), useDefaultPayment); CollapsePaymentData(payment, vaributes ?? payment.Select(e => new RawVaribute(e.Key)).ToList(), useDefaultPayment);
CollapsePaymentData(qualityWei, vaributes ?? qualityWei.Select(e => e.Key).ToList(), useDefaultQuality); CollapsePaymentData(qualityWei, vaributes ?? qualityWei.Select(e => new RawVaribute(e.Key)).ToList(), useDefaultQuality);
var data = new JsonObject { var data = new JsonObject {
["mode"] = "elwig", ["mode"] = "elwig",

View File

@ -7,18 +7,18 @@ using System.Text.Json.Nodes;
namespace Elwig.Helpers.Billing { namespace Elwig.Helpers.Billing {
public class EditBillingData : BillingData { public class EditBillingData : BillingData {
protected readonly IEnumerable<string> Vaributes; protected readonly IEnumerable<RawVaribute> Vaributes;
public EditBillingData(JsonObject data, IEnumerable<string> vaributes) : public EditBillingData(JsonObject data, IEnumerable<RawVaribute> vaributes) :
base(data) { base(data) {
Vaributes = vaributes; Vaributes = vaributes;
} }
public static EditBillingData FromJson(string json, IEnumerable<string> vaributes) { public static EditBillingData FromJson(string json, IEnumerable<RawVaribute> vaributes) {
return new(ParseJson(json), vaributes); return new(ParseJson(json), vaributes);
} }
private (Dictionary<int, Curve>, Dictionary<int, List<string>>) GetGraphEntries(JsonNode root) { private (Dictionary<int, Curve>, Dictionary<int, List<RawVaribute>>) GetGraphEntries(JsonNode root) {
Dictionary<int, List<string>> dict1 = []; Dictionary<int, List<string>> dict1 = [];
Dictionary<decimal, List<string>> dict2 = []; Dictionary<decimal, List<string>> dict2 = [];
if (root is JsonObject paymentObj) { if (root is JsonObject paymentObj) {
@ -55,7 +55,7 @@ namespace Elwig.Helpers.Billing {
curves[i + virtOffset] = new Curve(CurveMode.Oe, new() { { 73, idx } }, null); curves[i + virtOffset] = new Curve(CurveMode.Oe, new() { { 73, idx } }, null);
} }
Dictionary<int, List<string>> dict3 = curves.ToDictionary(c => c.Key, _ => new List<string>()); Dictionary<int, List<RawVaribute>> dict3 = curves.ToDictionary(c => c.Key, _ => new List<RawVaribute>());
foreach (var (selector, value) in GetSelection(root, Vaributes)) { foreach (var (selector, value) in GetSelection(root, Vaributes)) {
int? idx = null; int? idx = null;
if (value.TryGetValue<decimal>(out var val)) { if (value.TryGetValue<decimal>(out var val)) {
@ -73,13 +73,14 @@ namespace Elwig.Helpers.Billing {
private static List<GraphEntry> CreateGraphEntries( private static List<GraphEntry> CreateGraphEntries(
AppDbContext ctx, int precision, AppDbContext ctx, int precision,
Dictionary<int, Curve> curves, Dictionary<int, Curve> curves,
Dictionary<int, List<string>> entries Dictionary<int, List<RawVaribute>> entries
) { ) {
var vars = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v); var vars = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
var attrs = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a); var attrs = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
var cults = ctx.WineCultivations.ToDictionary(c => c.CultId, c => c);
return entries return entries
.Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value .Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value
.Select(s => new Varibute(vars[s[..2]], s.Length > 2 ? attrs[s[2..]] : null)) .Select(s => new Varibute(s, vars, attrs, cults))
.ToList())) .ToList()))
.ToList(); .ToList();
} }

View File

@ -7,40 +7,38 @@ namespace Elwig.Helpers.Billing {
public class PaymentBillingData : BillingData { public class PaymentBillingData : BillingData {
protected readonly Dictionary<int, Curve> Curves; protected readonly Dictionary<int, Curve> Curves;
protected readonly Dictionary<string, Curve> PaymentData; protected readonly Dictionary<RawVaribute, Curve> PaymentData;
protected readonly Dictionary<string, Curve> QualityData; protected readonly Dictionary<RawQualVaribute, Curve> QualityData;
protected readonly IEnumerable<string> Vaributes; protected readonly IEnumerable<RawVaribute> Vaributes;
public PaymentBillingData(JsonObject data, IEnumerable<string> vaributes) : public PaymentBillingData(JsonObject data, IEnumerable<RawVaribute> vaributes) :
base(data) { base(data) {
if (vaributes.Any(e => e.Any(c => c < 'A' || c > 'Z')))
throw new ArgumentException("Invalid vaributes");
Vaributes = vaributes; Vaributes = vaributes;
Curves = GetCurves(); Curves = GetCurves();
PaymentData = GetPaymentData(); PaymentData = GetPaymentData();
QualityData = GetQualityData(); QualityData = GetQualityData();
} }
public static PaymentBillingData FromJson(string json, IEnumerable<string> vaributes) { public static PaymentBillingData FromJson(string json, IEnumerable<RawVaribute> vaributes) {
return new(ParseJson(json), vaributes); return new(ParseJson(json), vaributes);
} }
private Dictionary<string, Curve> GetData(JsonNode data) { private Dictionary<RawVaribute, Curve> GetData(JsonNode data) {
return GetSelection(data, Vaributes).ToDictionary(e => e.Key, e => LookupCurve(e.Value)); return GetSelection(data, Vaributes).ToDictionary(e => e.Key, e => LookupCurve(e.Value));
} }
protected Dictionary<string, Curve> GetPaymentData() { protected Dictionary<RawVaribute, Curve> GetPaymentData() {
return GetData(GetPaymentEntry()); return GetData(GetPaymentEntry());
} }
protected Dictionary<string, Curve> GetQualityData() { protected Dictionary<RawQualVaribute, Curve> GetQualityData() {
Dictionary<string, Curve> dict = []; Dictionary<RawQualVaribute, Curve> dict = [];
var q = GetQualityEntry(); var q = GetQualityEntry();
if (q == null) return dict; if (q == null) return dict;
foreach (var (qualid, data) in q) { foreach (var (qualid, data) in q) {
foreach (var (idx, d) in GetData(data ?? throw new InvalidOperationException())) { foreach (var (idx, d) in GetData(data ?? throw new InvalidOperationException())) {
dict[$"{qualid}/{idx}"] = d; dict[new(qualid, idx.SortId, idx.AttrId, idx.CultId)] = d;
} }
} }
@ -63,11 +61,11 @@ namespace Elwig.Helpers.Billing {
} }
protected Curve GetCurve(string sortid, string? attrid) { protected Curve GetCurve(string sortid, string? attrid) {
return PaymentData[$"{sortid}{attrid}"]; return PaymentData[new(sortid, attrid ?? "", null)];
} }
protected Curve? GetQualityCurve(string qualid, string sortid, string? attrid) { protected Curve? GetQualityCurve(string qualid, string sortid, string? attrid) {
return QualityData.TryGetValue($"{qualid}/{sortid}{attrid}", out var curve) ? curve : null; return QualityData.TryGetValue(new(qualid, sortid, attrid ?? "", null), out var curve) ? curve : null;
} }
} }
} }

View File

@ -1,20 +1,81 @@
using Elwig.Models.Entities; using Elwig.Models.Entities;
using System; using System;
using System.Collections.Generic;
namespace Elwig.Helpers.Billing { namespace Elwig.Helpers.Billing {
public record struct RawQualVaribute {
public string QualId;
public string? SortId;
public string? AttrId;
public string? CultId;
public RawQualVaribute(string qualid, string? sortid, string? attrid, string? cultid) {
QualId = qualid;
SortId = sortid;
AttrId = attrid;
CultId = cultid;
}
}
public record struct RawVaribute : IComparable<RawVaribute> {
public string? SortId;
public string? AttrId;
public string? CultId;
public RawVaribute(string? sortid, string? attrid, string? cultid) {
SortId = sortid;
AttrId = attrid;
CultId = cultid;
}
public RawVaribute(string id) {
var p1 = id.Split('/')[0].Split('-')[0];
SortId = p1 == "" ? null : p1;
AttrId = id.Contains('/') ? id.Split('/')[1].Split('-')[0] : null;
CultId = id.Contains('-') ? id.Split('-')[1] : null;
}
public readonly override string ToString() {
return $"{SortId}" + (AttrId != null ? $"/{AttrId}" : "") + (CultId != null ? $"-{CultId}" : "");
}
public readonly int CompareTo(RawVaribute other) {
return $"{SortId}/{AttrId}-{CultId}".CompareTo($"{other.SortId}/{other.AttrId}-{other.CultId}");
}
}
public class Varibute : IComparable<Varibute> { public class Varibute : IComparable<Varibute> {
public WineVar? Variety { get; } public WineVar? Variety { get; }
public WineAttr? Attribute { get; } public WineAttr? Attribute { get; }
public WineCult? Cultivation { get; }
public int? AssignedGraphId { get; set; } public int? AssignedGraphId { get; set; }
public int? AssignedAbgewGraphId { get; set; } public int? AssignedAbgewGraphId { get; set; }
public string Listing => $"{Variety?.SortId}{Attribute?.AttrId}"; public string Listing => $"{Variety?.SortId}" +
public string FullName => $"{Variety?.Name}" + (Variety != null && Attribute != null ? " " : "") + $"{Attribute?.Name}"; (Attribute != null ? $"/{Attribute.AttrId}" : "") +
(Cultivation != null ? $"-{Cultivation.CultId}" : "");
public string FullName => $"{Variety?.Name}" +
(Variety != null && Attribute != null ? " " : "") + $"{Attribute?.Name}" +
((Variety != null || Attribute != null) && Cultivation != null ? " " : "") + $"{Cultivation?.Name}";
public Varibute(WineVar? var, WineAttr? attr) { public Varibute(RawVaribute raw) :
this(raw.SortId != null ? new WineVar(raw.SortId, raw.SortId) : null,
raw.AttrId != null ? new WineAttr(raw.AttrId, raw.AttrId) : null,
raw.CultId != null ? new WineCult(raw.CultId, raw.CultId) : null) {
}
public Varibute(RawVaribute raw, Dictionary<string, WineVar> vars, Dictionary<string, WineAttr> attrs, Dictionary<string, WineCult> cults) :
this(raw.SortId != null && raw.SortId != "" ? vars[raw.SortId] : null,
raw.AttrId != null && raw.AttrId != "" ? attrs[raw.AttrId] : null,
raw.CultId != null && raw.CultId != "" ? cults[raw.CultId] : null) {
}
public Varibute(WineVar? var, WineAttr? attr, WineCult? cult) {
Variety = var; Variety = var;
Attribute = attr; Attribute = attr;
Cultivation = cult;
} }
public override string ToString() { public override string ToString() {
@ -23,6 +84,6 @@ namespace Elwig.Helpers.Billing {
public int CompareTo(Varibute? other) { public int CompareTo(Varibute? other) {
return Listing.CompareTo(other?.Listing); return Listing.CompareTo(other?.Listing);
} }
} }
} }

View File

@ -362,11 +362,11 @@ namespace Elwig.Helpers {
return output.OrderByDescending(l => l.Count()); return output.OrderByDescending(l => l.Count());
} }
public static List<string> GetVaributes(AppDbContext ctx, int year, bool withSlash = false, bool onlyDelivered = true) { public static List<RawVaribute> GetVaributes(AppDbContext ctx, int year, bool onlyDelivered = true) {
var varieties = ctx.WineVarieties.Select(v => v.SortId).ToList(); var varieties = ctx.WineVarieties.Select(v => new RawVaribute(v.SortId, "", null)).ToList();
var delivered = ctx.DeliveryParts var delivered = ctx.DeliveryParts
.Where(d => d.Year == year) .Where(d => d.Year == year)
.Select(d => $"{d.SortId}{(withSlash ? "/" : "")}{d.AttrId}") .Select(d => new RawVaribute(d.SortId, d.AttrId ?? "", d.CultId))
.Distinct() .Distinct()
.ToList(); .ToList();
return [.. (onlyDelivered ? delivered : delivered.Union(varieties)).Order()]; return [.. (onlyDelivered ? delivered : delivered.Union(varieties)).Order()];
@ -375,8 +375,9 @@ namespace Elwig.Helpers {
public static List<Varibute> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) { public static List<Varibute> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) {
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v); var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a); var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
return GetVaributes(ctx, year, false, onlyDelivered) var cultivations = ctx.WineCultivations.ToDictionary(c => c.CultId, c => c);
.Select(s => new Varibute(varieties[s[..2]], s.Length > 2 ? attributes[s[2..]] : null)) return GetVaributes(ctx, year, onlyDelivered)
.Select(s => new Varibute(s, varieties, attributes, cultivations))
.ToList(); .ToList();
} }
} }

View File

@ -13,5 +13,16 @@ namespace Elwig.Models.Entities {
[Column("description")] [Column("description")]
public string? Description { get; set; } public string? Description { get; set; }
public WineCult() { }
public WineCult(string cultId, string name) {
CultId = cultId;
Name = name;
}
public override string ToString() {
return Name;
}
} }
} }

View File

@ -69,7 +69,8 @@
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Variety.Name}" Width="150"/> <TextBlock Text="{Binding Variety.Name}" Width="150"/>
<TextBlock Text="{Binding Variety.Type}" Width="30"/> <TextBlock Text="{Binding Variety.Type}" Width="30"/>
<TextBlock Text="{Binding Attribute.Name}" Width="120"/> <TextBlock Text="{Binding Attribute.Name}" Width="80"/>
<TextBlock Text="{Binding Cultivation.Name}" Width="80"/>
<TextBlock Text="{Binding AssignedGraphId}" Width="30"/> <TextBlock Text="{Binding AssignedGraphId}" Width="30"/>
<TextBlock Text="{Binding AssignedAbgewGraphId}" Width="30"/> <TextBlock Text="{Binding AssignedAbgewGraphId}" Width="30"/>
</StackPanel> </StackPanel>
@ -78,7 +79,7 @@
</xctk:CheckComboBox> </xctk:CheckComboBox>
<CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False" Checked="AbgewertetInput_Changed" Unchecked="AbgewertetInput_Changed" <CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False" Checked="AbgewertetInput_Changed" Unchecked="AbgewertetInput_Changed"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0" Grid.Column="1"/> VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0" Grid.Column="1"/>
</Grid> </Grid>
<ListBox x:Name="GraphList" Margin="10,10,35,42" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" SelectionChanged="GraphList_SelectionChanged"> <ListBox x:Name="GraphList" Margin="10,10,35,42" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" SelectionChanged="GraphList_SelectionChanged">

View File

@ -644,7 +644,7 @@ namespace Elwig.Windows {
private async void SaveButton_Click(object sender, RoutedEventArgs e) { private async void SaveButton_Click(object sender, RoutedEventArgs e) {
var origData = BillingData.FromJson(PaymentVar.Data); var origData = BillingData.FromJson(PaymentVar.Data);
var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(Context, Year, withSlash: true), var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(Context, Year),
AllVaributesAssigned, AllVaributesAssignedAbgew); AllVaributesAssigned, AllVaributesAssignedAbgew);
EntityEntry<PaymentVar>? tr = null; EntityEntry<PaymentVar>? tr = null;

View File

@ -8,7 +8,9 @@ namespace Tests.HelperTests {
public class BillingDataTest { public class BillingDataTest {
private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true }; private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true };
private static readonly string[] Vaributes = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"]; private static readonly RawVaribute[] Vaributes = [
new("GV/"), new("GV/D"), new("GV/K"), new("GV/S"), new("GV/Z"),
new("WR/"), new("WR/S"), new("ZW/"), new("ZW/S"), new("ZW/Z")];
private static (string, string?) GetSortIdAttrId(string bucket) { private static (string, string?) GetSortIdAttrId(string bucket) {
return (bucket[..2], bucket.Length > 2 ? bucket[2..] : null); return (bucket[..2], bucket.Length > 2 ? bucket[2..] : null);
@ -345,14 +347,7 @@ namespace Tests.HelperTests {
} }
private static List<Varibute> GetSelection(IEnumerable<string> attVars) { private static List<Varibute> GetSelection(IEnumerable<string> attVars) {
return attVars.Select(s => { return attVars.Select(s => new Varibute(new RawVaribute(s))).ToList();
var sortid = s[..2];
var attrid = s.Length > 2 ? s[2..] : null;
return new Varibute(
new WineVar(sortid, sortid),
attrid == null ? null : new WineAttr(attrid, attrid)
);
}).ToList();
} }
[Test] [Test]
@ -378,7 +373,7 @@ namespace Tests.HelperTests {
List<GraphEntry> entries = [ List<GraphEntry> entries = [
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.5m [73] = 0.5m
}, null), GetSelection(["GV"])) }, null), GetSelection(["GV/"]))
]; ];
var data = BillingData.FromGraphEntries(entries); var data = BillingData.FromGraphEntries(entries);
Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo("""
@ -397,7 +392,7 @@ namespace Tests.HelperTests {
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.5m, [73] = 0.5m,
[83] = 1.0m [83] = 1.0m
}, null), GetSelection(["GV"])) }, null), GetSelection(["GV/"]))
]; ];
var data = BillingData.FromGraphEntries(entries); var data = BillingData.FromGraphEntries(entries);
Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo("""
@ -425,10 +420,10 @@ namespace Tests.HelperTests {
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.5m, [73] = 0.5m,
[84] = 1.0m [84] = 1.0m
}, null), GetSelection(["GV", "ZW"])), }, null), GetSelection(["GV/", "ZW/"])),
new GraphEntry(10, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(10, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.75m, [73] = 0.75m,
}, null), GetSelection(["WR"])) }, null), GetSelection(["WR/"]))
]; ];
var data = BillingData.FromGraphEntries(entries); var data = BillingData.FromGraphEntries(entries);
Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo("""
@ -459,14 +454,14 @@ namespace Tests.HelperTests {
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.5m, [73] = 0.5m,
[84] = 1.0m [84] = 1.0m
}, null), GetSelection(["GVB", "ZWB"])), }, null), GetSelection(["GV/B", "ZW/B"])),
new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.75m, [73] = 0.75m,
}, null), GetSelection(["WR", "BL", "RR", "FV"])), }, null), GetSelection(["WR/", "BL/", "RR/", "FV/"])),
new GraphEntry(4, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { new GraphEntry(4, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = 0.65m, [73] = 0.65m,
[84] = 1.2m [84] = 1.2m
}, null), GetSelection(["BP", "SA"])) }, null), GetSelection(["BP/", "SA/"]))
]; ];
var data = BillingData.FromGraphEntries(entries); var data = BillingData.FromGraphEntries(entries);
Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo("""