From 20e3e2a76b78e7537e5df2460e3d84b9a5bf2697 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 14 Jan 2025 22:03:18 +0100 Subject: [PATCH] BillingData: Fix collapsing with cultivations/defaults --- Elwig/Helpers/Billing/BillingData.cs | 46 +++-- Tests/HelperTests/BillingDataTest.cs | 297 +++++++++++++++++++++++++-- 2 files changed, 310 insertions(+), 33 deletions(-) diff --git a/Elwig/Helpers/Billing/BillingData.cs b/Elwig/Helpers/Billing/BillingData.cs index c757d57..8f63888 100644 --- a/Elwig/Helpers/Billing/BillingData.cs +++ b/Elwig/Helpers/Billing/BillingData.cs @@ -299,22 +299,28 @@ namespace Elwig.Helpers.Billing { return (rev1, rev2); } - protected static void CollapsePaymentData(JsonObject data, IEnumerable vaributes, bool useDefault = true) { + protected static void CollapsePaymentData(JsonObject data, JsonObject originalData, IEnumerable vaributes, bool useDefault = true) { var (rev1, rev2) = GetReverseKeys(data); if (!data.ContainsKey("default")) { foreach (var (v, ks) in rev1) { - if ((ks.Count >= vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) { - foreach (var k in ks) data.Remove(k); + if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) { + foreach (var k in ks) { + if (!(originalData[$"{k[..2]}/"]?.AsValue().TryGetValue(out var o) ?? false) || o == v) + data.Remove(k); + } data["default"] = v; - CollapsePaymentData(data, vaributes, useDefault); + CollapsePaymentData(data, originalData, vaributes, useDefault); return; } } foreach (var (v, ks) in rev2) { - if ((ks.Count >= vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) { - foreach (var k in ks) data.Remove(k); + if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) { + foreach (var k in ks) { + if (!(originalData[$"{k[..2]}/"]?.AsValue().TryGetValue(out var o) ?? false) || o == v) + data.Remove(k); + } data["default"] = v; - CollapsePaymentData(data, vaributes, useDefault); + CollapsePaymentData(data, originalData, vaributes, useDefault); return; } } @@ -330,16 +336,26 @@ namespace Elwig.Helpers.Billing { var len = vaributes.Count(e => $"{e.AttrId}{(e.CultId != null && e.CultId != "" ? "-" : "")}{e.CultId}" == idx); foreach (var (v, ks) in rev1) { 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); - data[(idx.StartsWith('-') && !useDefault ? "" : "/") + idx] = v; + var discr = (idx.StartsWith('-') && !useDefault ? "" : "/") + idx; + data[discr] = v; + foreach (var (k, o) in originalData) { + if (o!.AsValue().TryGetValue(out var o2) && o2 != v && k.Contains(discr)) + data[k] = o2; + } } } foreach (var (v, ks) in rev2) { 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); - data[(idx.StartsWith('-') && !useDefault ? "" : "/") + idx] = v; + var discr = (idx.StartsWith('-') && !useDefault ? "" : "/") + idx; + data[discr] = v; + foreach (var (k, o) in originalData) { + if (o!.AsValue().TryGetValue(out var o2) && o2 != v && k.Contains(discr)) + data[k] = o2; + } } } } @@ -360,8 +376,8 @@ namespace Elwig.Helpers.Billing { (rev1, rev2) = GetReverseKeys(data, false); var keyVaributes = data - .Select(e => e.Key.Split('-')[0]) - .Where(e => e.Length > 0 && e != "default") + .Select(e => e.Key) + .Where(e => e.Length > 0 && !e.Contains('-') && e != "default") .Distinct() .ToList(); foreach (var idx in keyVaributes) { @@ -419,8 +435,8 @@ namespace Elwig.Helpers.Billing { } } - CollapsePaymentData(payment, vaributes ?? payment.Select(e => new RawVaribute(e.Key)).ToList(), useDefaultPayment); - CollapsePaymentData(qualityWei, vaributes ?? qualityWei.Select(e => new RawVaribute(e.Key)).ToList(), useDefaultQuality); + CollapsePaymentData(payment, payment.DeepClone().AsObject(), vaributes ?? payment.Select(e => new RawVaribute(e.Key)).ToList(), useDefaultPayment); + CollapsePaymentData(qualityWei, qualityWei.DeepClone().AsObject(), vaributes ?? qualityWei.Select(e => new RawVaribute(e.Key)).ToList(), useDefaultQuality); var data = new JsonObject { ["mode"] = "elwig", diff --git a/Tests/HelperTests/BillingDataTest.cs b/Tests/HelperTests/BillingDataTest.cs index af30e86..3fb11df 100644 --- a/Tests/HelperTests/BillingDataTest.cs +++ b/Tests/HelperTests/BillingDataTest.cs @@ -1,6 +1,5 @@ using Elwig.Helpers; using Elwig.Helpers.Billing; -using Elwig.Models.Entities; using System.Text.Json; namespace Tests.HelperTests { @@ -452,7 +451,7 @@ namespace Tests.HelperTests { [73] = 0.5m, [83] = 1.0m }, null), GetSelection(["GV/-"])) - ]; + ]; var data = BillingData.FromGraphEntries(entries); Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" { @@ -476,14 +475,14 @@ namespace Tests.HelperTests { [Test] public void TestWrite_04_Simple() { List entries = [ - new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { - [73] = 0.5m, - [84] = 1.0m - }, null), GetSelection(["GV/-", "ZW/-"])), + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.5m, + [84] = 1.0m + }, null), GetSelection(["GV/-", "ZW/-"])), new GraphEntry(10, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.75m, }, null), GetSelection(["WR/-"])) - ]; + ]; var data = BillingData.FromGraphEntries(entries); Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" { @@ -510,18 +509,18 @@ namespace Tests.HelperTests { [Test] public void TestWrite_05_Attribute() { List entries = [ - new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { - [73] = 0.5m, - [84] = 1.0m - }, null), GetSelection(["GV/K-", "ZW/K-"])), + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.5m, + [84] = 1.0m + }, null), GetSelection(["GV/K-", "ZW/K-"])), new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.75m, - }, null), GetSelection(["WR/-", "BL/-", "RR/-", "FV/-"])), + }, null), GetSelection(["WR/-", "BL/-", "RR/-", "FV/-", "GV/-"])), new GraphEntry(4, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.65m, [84] = 1.2m }, null), GetSelection(["BP/-", "SA/-"])) - ]; + ]; var data = BillingData.FromGraphEntries(entries); Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" { @@ -564,12 +563,12 @@ namespace Tests.HelperTests { }, null), GetSelection(["GV/-B", "ZW/-B"])), new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.75m, - }, null), GetSelection(["WR/-", "BL/-", "RR/-", "FV/-"])), + }, null), GetSelection(["WR/-", "BL/-", "RR/-", "FV/-", "GV/-"])), new GraphEntry(4, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.65m, [84] = 1.2m }, null), GetSelection(["BP/-", "SA/-"])) - ]; + ]; var data = BillingData.FromGraphEntries(entries); Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" { @@ -616,7 +615,7 @@ namespace Tests.HelperTests { new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.8m, }, null), GetSelection(["BP/-", "BP/-B"])), - ]; + ]; var data = BillingData.FromGraphEntries(entries); Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" { @@ -653,8 +652,8 @@ namespace Tests.HelperTests { }, null), GetSelection(["BP/-B", "ZW/-B", "FV/-B"])), new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { [73] = 0.8m, - }, null), GetSelection(["BP/-", "ZW/-", "FV/-", "WR/-", "BL/-"])), - ]; + }, null), GetSelection(["BP/-", "ZW/-", "FV/-", "WR/-", "BL/-", "RR/-"])), + ]; var data = BillingData.FromGraphEntries(entries); Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" { @@ -711,5 +710,267 @@ namespace Tests.HelperTests { } """)); } + + [Test] + public void TestWrite_10_QualityLevel() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["ZW/-"])) + ]; + entries[0].Abgewertet = true; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": 0.2, + "quality": { + "WEI": 0.1 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_11_MixedCultivation_1() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "WR/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["GV/-B"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "default": 0.1, + "GV-B": 0.2 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_12_MixedCultivation_2() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "ZW/-", "WR/-", "FV/-", "RR/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["GV/-B", "FV/-B"])), + new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.3m, + }, null), GetSelection(["ZW/-B", "WR/-B"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "default": 0.1, + "GV-B": 0.2, + "FV-B": 0.2, + "ZW-B": 0.3, + "WR-B": 0.3 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_13_DefaultCultivation_1() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "GV/-B"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["WR/-B"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "default": 0.1, + "WR-B": 0.2 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_14_DefaultCultivation_2() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "GV/-B", "ZW/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["WR/-B", "ZW/-B"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "default": 0.1, + "-B": 0.2, + "GV-B": 0.1 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_15_DefaultCultivation_3() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "GV/-B", "ZW/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["GV/S-", "GV/S-B", "ZW/S-"])), + new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.3m, + }, null), GetSelection(["WR/S-B", "ZW/S-B"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "GV/S-B": 0.2, + "/S": 0.2, + "/S-B": 0.3, + "GV": 0.1, + "ZW": 0.1 + }, + "curves": [] + } + """)); + } + + + [Test] + public void TestWrite_16_DefaultCultivation_4() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "RR/-B", "ZW/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["RR/-"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "default": 0.1, + "RR-B": 0.1, + "RR": 0.2 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_17_DefaultCultivation_5() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "RR/-B", "ZW/-", "SW/-", "SO/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["GV/K-", "RR/K-B", "ZW/K-"])), + new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.3m, + }, null), GetSelection(["RR/K-"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "RR/K-B": 0.2, + "RR/K": 0.3, + "default": 0.1, + "/K": 0.2 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_18_DefaultAttribute_1() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "GV/S-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["WR/S-"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "WR/S": 0.2, + "default": 0.1 + }, + "curves": [] + } + """)); + } + + [Test] + public void TestWrite_19_DefaultAttribute_2() { + List entries = [ + new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.1m, + }, null), GetSelection(["GV/-", "GV/S-", "ZW/-"])), + new GraphEntry(1, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = 0.2m, + }, null), GetSelection(["WR/S-", "ZW/S-"])) + ]; + var data = BillingData.FromGraphEntries(entries); + Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo(""" + { + "mode": "elwig", + "version": 1, + "payment": { + "default": 0.1, + "/S": 0.2, + "GV/S": 0.1 + }, + "curves": [] + } + """)); + } } }