diff --git a/Elwig/Helpers/Billing/BillingData.cs b/Elwig/Helpers/Billing/BillingData.cs index 8f63888..dbd1372 100644 --- a/Elwig/Helpers/Billing/BillingData.cs +++ b/Elwig/Helpers/Billing/BillingData.cs @@ -306,7 +306,8 @@ namespace Elwig.Helpers.Billing { 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); + if (!(originalData[k.Split('-')[0]]?.AsValue().TryGetValue(out var o2) ?? false) || o2 == v) + data.Remove(k); } data["default"] = v; CollapsePaymentData(data, originalData, vaributes, useDefault); @@ -317,7 +318,8 @@ namespace Elwig.Helpers.Billing { 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); + if (!(originalData[k.Split('-')[0]]?.AsValue().TryGetValue(out var o2) ?? false) || o2 == v) + data.Remove(k); } data["default"] = v; CollapsePaymentData(data, originalData, vaributes, useDefault); @@ -371,6 +373,15 @@ namespace Elwig.Helpers.Billing { } else if (k.Contains("/-")) { data.Remove(k, out var val); data.Add(k.Replace("/-", "-"), val); + if (k[0] == '/' || k.Contains('-')) { + foreach (var (k2, o) in originalData) { + if (!data.ContainsKey(k2) && k2.Contains('-') && k2.Contains("-" + k.Split('-')[1]) && !k2.Contains("/-") + && (!k2.Contains('/') || k2.Length <= 4 || !data.ContainsKey(k2[2..]))) + { + data[k2] = o?.DeepClone(); + } + } + } } } diff --git a/Tests/HelperTests/BillingDataTest.cs b/Tests/HelperTests/BillingDataTest.cs index 3fb11df..6db2c25 100644 --- a/Tests/HelperTests/BillingDataTest.cs +++ b/Tests/HelperTests/BillingDataTest.cs @@ -972,5 +972,67 @@ namespace Tests.HelperTests { } """)); } + + private static IEnumerable> GetPermutations(T[] input) { + if (input.Length <= 1) + yield return [..input]; + for (int i = 0; i < input.Length; i++) { + yield return [input[i]]; + foreach (var p in GetPermutations(input.Where((_, j) => j != i).ToArray())) { + p.Insert(0, input[i]); + yield return p; + } + } + } + + private static IEnumerable>> GetCurves(RawVaribute[] vaributes, int minNumCurves = 1, int maxNumCurves = 10) { + foreach (var p in GetPermutations(vaributes)) { + for (int nCurves = minNumCurves; nCurves <= Math.Min(maxNumCurves, p.Count); nCurves++) { + yield return Enumerable.Range(0, nCurves) + .Select(n => p.Where((v, idx) => idx % nCurves == n).ToHashSet()) + .ToList(); + } + } + } + + private readonly HashSet TestedCurves = []; + + private void TestCollapse(List> curves) { + var str = string.Join("\n", curves.Select(c => string.Join(" ", c.Select(v => v.ToString().PadRight(6)).Order())).Order().Select((c, n) => $"{n + 1}: [ " + c + " ]")); + if (!TestedCurves.Add(str)) + return; + var vaributes = curves.SelectMany(v => v).ToList(); + List entries = curves + .Select((l, n) => new GraphEntry(n, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { + [73] = n + 1, + }, null), GetSelection(l.Select(v => v.ToString())))) + .ToList(); + var data = BillingData.FromGraphEntries(entries); + var test = PaymentBillingData.FromJson(data.ToJsonString(), vaributes); + for (int i = 0; i < curves.Count; i++) { + foreach (var v in curves[i]) { + var val = test.CalculatePrice(v.SortId!, v.AttrId, v.CultId, "QUW", false, 73.0, 15.0); + var actualCurve = (int)val; + Assert.That(actualCurve, Is.EqualTo(i + 1), $"Invalid: {v} (Curve {i + 1} -> {actualCurve})\n\n{str}\n\n{data.ToJsonString(JsonOpts)}\n"); + } + } + } + + [Test] + public void TestCollapse_01_Permutations() { + RawVaribute[][] configurations = [ + [new("GV/-"), new("WR/-"), new("ZW/-"), new("GV/K-"), new("WR/K-"), new("ZW/K-")], + [new("GV/-"), new("WR/-"), new("GV/K-"), new("WR/K-"), new("GV/S-"), new("WR/S-")], + [new("GV/-"), new("WR/-"), new("ZW/-"), new("GV/-B"), new("WR/-B"), new("ZW/-B")], + [new("GV/-"), new("WR/-"), new("GV/-B"), new("WR/-B"), new("GV/-KIP"), new("WR/-KIP")], + [new("GV/-"), new("GV/K-"), new("ZW/-"), new("ZW/K-"), new("GV/-B"), new("GV/K-B"), new("ZW/-B"), new("ZW/K-B")], + ]; + Assert.Multiple(() => { + foreach (var config in configurations) { + foreach (var c in GetCurves(config)) + TestCollapse(c); + } + }); + } } }