using Elwig.Helpers; using Elwig.Helpers.Billing; namespace Tests.Helpers { [TestFixture] public class BillingDataTest { private static readonly string[] AttributeVariants = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"]; [OneTimeSetUp] public async Task SetupBilling() { await BillingData.Init(); } private static (string, string?) GetSortIdAttrId(string bucket) { return (bucket[..2], bucket.Length > 2 ? bucket[2..] : null); } private static string GetQualId(double kmw) { return kmw switch { >= 17.0 => "KAB", >= 15.0 => "QUW", >= 14.0 => "LDW", >= 10.6 => "RSW", _ => "WEI", }; } private static void TestCalcOe(PaymentBillingData data, string bucket, double oe, decimal expected, string? qualid = null, bool geb = false) { var (sortid, attrid) = GetSortIdAttrId(bucket); var kmw = Utils.OeToKmw(oe); var v = data.CalculatePrice(sortid, attrid, qualid ?? GetQualId(kmw), geb, oe, kmw); Assert.That(Math.Round(v, 6), Is.EqualTo(expected)); } private static void TestCalcKmw(PaymentBillingData data, string bucket, double kmw, decimal expected, string? qualid = null, bool geb = false) { var (sortid, attrid) = GetSortIdAttrId(bucket); var oe = Utils.KmwToOe(kmw); var v = data.CalculatePrice(sortid, attrid, qualid ?? GetQualId(kmw), geb, oe, kmw); Assert.That(Math.Round(v, 6), Is.EqualTo(expected)); } [Test] public void Test_01_Flatrate() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": 0.5, "curves": [] } """, AttributeVariants); Assert.Multiple(() => { TestCalcOe(data, "GV", 73, 0.5m); TestCalcOe(data, "WRS", 74, 0.5m); }); } [Test] public void Test_02_Simple() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": "curve:1", "curves": [{ "id": 1, "mode": "oe", "data": { "72.0oe": 0.25, "15.0kmw": 0.5, "83oe": 1 }, "geb": 0.10 }] } """, AttributeVariants); Assert.Multiple(() => { TestCalcOe(data, "GV", 70, 0.25m); TestCalcOe(data, "GV", 72, 0.25m); TestCalcOe(data, "GV", 73, 0.50m); TestCalcOe(data, "GV", 74, 0.55m); TestCalcOe(data, "GV", 80, 0.85m); TestCalcOe(data, "GV", 83, 1.00m); TestCalcOe(data, "GV", 90, 1.00m); TestCalcOe(data, "GV", 73, 0.60m, geb: true); TestCalcOe(data, "GV", 74, 0.65m, geb: true); TestCalcOe(data, "GV", 80, 0.95m, geb: true); TestCalcOe(data, "GV", 83, 1.10m, geb: true); TestCalcOe(data, "GV", 90, 1.10m, geb: true); }); } [Test] public void Test_03_GreaterThanAndLessThan() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": "curve:1", "curves": [{ "id": 1, "mode": "kmw", "data": { "<14kmw": 0.1, "14kmw": 0.2, "<15kmw": 0.25, "15kmw": 0.5, "17kmw": 1, ">17kmw": 1.25 } }] } """, AttributeVariants); Assert.Multiple(() => { TestCalcKmw(data, "GV", 13.00, 0.10m); TestCalcKmw(data, "GV", 13.50, 0.10m); TestCalcKmw(data, "GV", 13.99, 0.10m); TestCalcKmw(data, "GV", 14.00, 0.20m); TestCalcKmw(data, "GV", 14.50, 0.225m); TestCalcKmw(data, "GV", 15.00, 0.50m); TestCalcKmw(data, "GV", 15.50, 0.625m); TestCalcKmw(data, "GV", 16.00, 0.75m); TestCalcKmw(data, "GV", 16.50, 0.875m); TestCalcKmw(data, "GV", 17.00, 1.00m); TestCalcKmw(data, "GV", 17.01, 1.25m); TestCalcKmw(data, "GV", 17.50, 1.25m); TestCalcKmw(data, "GV", 18.00, 1.25m); TestCalcKmw(data, "GV", 18.50, 1.25m); }); } [Test] public void Test_04_VariantsAndAttributes() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": { "default": 0.10, "GV/": 0.20, "ZW": 0.25, "/S": 0.15, "GV/K": 0.30 }, "curves": [] } """, AttributeVariants); Assert.Multiple(() => { TestCalcOe(data, "WR", 73, 0.10m); TestCalcOe(data, "WRS", 73, 0.15m); TestCalcOe(data, "GV", 73, 0.20m); TestCalcOe(data, "GVD", 73, 0.10m); TestCalcOe(data, "GVK", 73, 0.30m); TestCalcOe(data, "GVS", 73, 0.15m); TestCalcOe(data, "GVZ", 73, 0.10m); TestCalcOe(data, "ZW", 73, 0.25m); TestCalcOe(data, "ZWS", 73, 0.15m); TestCalcOe(data, "ZWZ", 73, 0.25m); }); } [Test] public void Test_05_QualityLevel() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": 0.5, "quality": { "WEI": { "default": 0.25, "GV": 0.3, "/S": 0.2 } }, "curves": [] } """, AttributeVariants); Assert.Multiple(() => { TestCalcOe(data, "GV", 75, 0.30m, qualid: "WEI"); TestCalcOe(data, "ZW", 76, 0.25m, qualid: "WEI"); TestCalcOe(data, "GVS", 75, 0.20m, qualid: "WEI"); TestCalcOe(data, "GVK", 74, 0.30m, qualid: "WEI"); TestCalcOe(data, "ZWS", 73, 0.20m, qualid: "WEI"); TestCalcOe(data, "GV", 70, 0.5m); TestCalcOe(data, "GV", 72, 0.5m); TestCalcOe(data, "GV", 73, 0.5m); TestCalcOe(data, "ZWS", 74, 0.5m); TestCalcOe(data, "GVK", 80, 0.5m); }); } [Test] public void Test_06_ModeOeAndKmw() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": { "default": 1.0, "GV": "curve:1", "ZW": "curve:2" }, "curves": [{ "id": 1, "mode": "oe", "data": { "73oe": 2.0, "17kmw": 3.0 } }, { "id": 2, "mode": "kmw", "data": { "73oe": 2.0, "17kmw": 3.0 } }] } """, AttributeVariants); Assert.Multiple(() => { TestCalcKmw(data, "GV", 15.0, 2.0m); TestCalcKmw(data, "GV", 15.5, 2.272727m); TestCalcKmw(data, "GV", 16.0, 2.454545m); TestCalcKmw(data, "GV", 16.5, 2.727273m); TestCalcKmw(data, "GV", 17.0, 3.0m); TestCalcKmw(data, "ZW", 15.0, 2.0m); TestCalcKmw(data, "ZW", 15.5, 2.25m); TestCalcKmw(data, "ZW", 16.0, 2.50m); TestCalcKmw(data, "ZW", 16.5, 2.75m); TestCalcKmw(data, "ZW", 17.0, 3.0m); }); } [Test] public void Test_07_MultipleCurves() { var data = PaymentBillingData.FromJson(""" { "mode": "elwig", "version": 1, "payment": { "default": 0.25, "/S": "curve:1", "GV/": 0.75, "GV/K": "curve:2", "WR/S": "curve:3" }, "curves": [{ "id": 3, "mode": "kmw", "data": { "73oe": 0.7, "17kmw": 0.8 }, "geb": { "15kmw": 0.8, "17kmw": 0.95 } }, { "id": 1, "mode": "kmw", "data": { "73oe": 0.5, "17kmw": 0.6 }, "geb": 0.1 }, { "id": 2, "mode": "kmw", "data": { "15kmw": 0.6, "17kmw": 0.7 }, "geb": { "73oe": 0.65, "17kmw": 0.80 } }] } """, AttributeVariants); Assert.Multiple(() => { TestCalcKmw(data, "GV", 15.0, 0.75m); TestCalcKmw(data, "GVS", 15.0, 0.50m); TestCalcKmw(data, "GVS", 16.0, 0.55m); TestCalcKmw(data, "GVS", 17.0, 0.60m); TestCalcKmw(data, "GVS", 15.0, 0.60m, geb: true); TestCalcKmw(data, "GVS", 16.0, 0.65m, geb: true); TestCalcKmw(data, "GVS", 17.0, 0.70m, geb: true); TestCalcKmw(data, "GVK", 15.0, 0.60m); TestCalcKmw(data, "GVK", 16.0, 0.65m); TestCalcKmw(data, "GVK", 17.0, 0.70m); TestCalcKmw(data, "GVK", 15.0, 0.65m, geb: true); TestCalcKmw(data, "GVK", 16.0, 0.725m, geb: true); TestCalcKmw(data, "GVK", 17.0, 0.80m, geb: true); TestCalcKmw(data, "WRS", 15.0, 0.70m); TestCalcKmw(data, "WRS", 16.0, 0.75m); TestCalcKmw(data, "WRS", 17.0, 0.80m); TestCalcKmw(data, "WRS", 15.0, 0.80m, geb: true); TestCalcKmw(data, "WRS", 16.0, 0.875m, geb: true); TestCalcKmw(data, "WRS", 17.0, 0.95m, geb: true); }); } [Test] public void Test_08_WgMaster() { var data = PaymentBillingData.FromJson(""" { "mode": "wgmaster", "Grundbetrag": 0.033, "GBZS": 0.0, "Ausgabefaktor": 1.0, "Rebelzuschlag": 0.0, "AufschlagVolllieferanten": 0.0, "AuszahlungSorten": { "BL/": 0.097, "BP/": 0.097, "GV/K": "curve:1", "SL/": 0.097, "ZW/": 0.097, "default": "curve:0" }, "AuszahlungSortenQualitätsstufe": { "WEI": 0.005 }, "Kurven": [{ "id": 0, "mode": "oe", "data": 0.033, "geb": 0 }, { "id": 1, "mode": "oe", "data": { "88oe": 0.032, "89oe": 0.065 } }] } """, AttributeVariants); Assert.Multiple(() => { TestCalcOe(data, "GVK", 73, 0.032m); TestCalcOe(data, "ZWS", 74, 0.033m); TestCalcOe(data, "GV", 75, 0.005m, qualid: "WEI"); TestCalcOe(data, "GVK", 115, 0.065m); }); } } }