Billing: Add functionality to collapse curves
This commit is contained in:
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Billing {
|
namespace Elwig.Helpers.Billing {
|
||||||
public class BillingData {
|
public class BillingData {
|
||||||
@ -206,30 +207,41 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return curve[min] * p2 + curve[max] * p1;
|
return curve[min] * p2 + curve[max] * p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static JsonNode GraphToJson(Graph graph, string mode) {
|
protected static JsonObject GraphToJson(Graph graph, string mode) {
|
||||||
var x = graph.DataX;
|
var x = graph.DataX;
|
||||||
var y = graph.DataY;
|
var y = graph.DataY;
|
||||||
if (y.Distinct().Count() == 1) {
|
var prec = graph.Precision;
|
||||||
return JsonValue.Create((decimal)graph.DataY[0]);
|
|
||||||
}
|
try {
|
||||||
|
return new JsonObject() {
|
||||||
|
["15kmw"] = Math.Round(x.Distinct().Single(), prec)
|
||||||
|
};
|
||||||
|
} catch { }
|
||||||
|
|
||||||
var data = new JsonObject();
|
var data = new JsonObject();
|
||||||
|
|
||||||
if (y[0] != y[1]) {
|
if (y[0] != y[1]) {
|
||||||
data[$"{x[0]}{mode}"] = Math.Round(y[0], graph.Precision);
|
data[$"{x[0]}{mode}"] = Math.Round(y[0], prec);
|
||||||
}
|
}
|
||||||
for (int i = 1; i < x.Length - 1; i++) {
|
for (int i = 1; i < x.Length - 1; i++) {
|
||||||
if (Math.Round(y[i] - y[i - 1], 10) != Math.Round(y[i + 1] - y[i], 10)) {
|
var d1 = Math.Round(y[i] - y[i - 1], prec);
|
||||||
data[$"{x[i]}{mode}"] = Math.Round(y[i], graph.Precision);
|
var d2 = Math.Round(y[i + 1] - y[i], prec);
|
||||||
|
if (d1 != d2) {
|
||||||
|
data[$"{x[i]}{mode}"] = Math.Round(y[i], prec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y[^1] != y[^2]) {
|
if (y[^1] != y[^2]) {
|
||||||
data[$"{x[^1]}{mode}"] = Math.Round(y[^1], graph.Precision);
|
data[$"{x[^1]}{mode}"] = Math.Round(y[^1], prec);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static JsonObject GraphEntryToJson(GraphEntry entry) {
|
protected static JsonNode GraphEntryToJson(GraphEntry entry) {
|
||||||
|
try {
|
||||||
|
if (entry.GebundenFlatBonus == null) {
|
||||||
|
return JsonValue.Create((decimal)entry.DataGraph.DataY.Distinct().Single());
|
||||||
|
}
|
||||||
|
} catch { }
|
||||||
|
|
||||||
var curve = new JsonObject {
|
var curve = new JsonObject {
|
||||||
["id"] = entry.Id,
|
["id"] = entry.Id,
|
||||||
["mode"] = entry.Mode.ToString().ToLower(),
|
["mode"] = entry.Mode.ToString().ToLower(),
|
||||||
@ -238,7 +250,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
curve["data"] = GraphToJson(entry.DataGraph, entry.Mode.ToString().ToLower());
|
curve["data"] = GraphToJson(entry.DataGraph, entry.Mode.ToString().ToLower());
|
||||||
|
|
||||||
if (entry.GebundenFlatBonus != null) {
|
if (entry.GebundenFlatBonus != null) {
|
||||||
curve["geb"] = entry.GebundenFlatBonus;
|
curve["geb"] = (decimal)entry.GebundenFlatBonus;
|
||||||
} else if (entry.GebundenGraph != null) {
|
} else if (entry.GebundenGraph != null) {
|
||||||
curve["geb"] = GraphToJson(entry.GebundenGraph, entry.Mode.ToString().ToLower());
|
curve["geb"] = GraphToJson(entry.GebundenGraph, entry.Mode.ToString().ToLower());
|
||||||
}
|
}
|
||||||
@ -246,31 +258,122 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return curve;
|
return curve;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonObject FromGraphEntries(IEnumerable<GraphEntry> graphEntries) {
|
protected static void CollapsePaymentData(JsonObject data) {
|
||||||
|
Dictionary<string, List<string>> rev1 = [];
|
||||||
|
Dictionary<decimal, List<string>> rev2 = [];
|
||||||
|
foreach (var (k, v) in data) {
|
||||||
|
if (k == "default" || k.StartsWith('/') || !k.Contains('/') || v is not JsonValue val) {
|
||||||
|
continue;
|
||||||
|
} else if (val.TryGetValue<decimal>(out var dec)) {
|
||||||
|
rev2[dec] = rev2.GetValueOrDefault(dec) ?? [];
|
||||||
|
rev2[dec].Add(k);
|
||||||
|
} else if (val.TryGetValue<string>(out var cur)) {
|
||||||
|
rev1[cur] = rev1.GetValueOrDefault(cur) ?? [];
|
||||||
|
rev1[cur].Add(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!data.ContainsKey("default")) {
|
||||||
|
foreach (var (v, ks) in rev1) {
|
||||||
|
if (ks.Count >= data.Count / 2.0) {
|
||||||
|
foreach (var k in ks) data.Remove(k);
|
||||||
|
data["default"] = v;
|
||||||
|
CollapsePaymentData(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var (v, ks) in rev2) {
|
||||||
|
if (ks.Count >= data.Count / 2.0) {
|
||||||
|
foreach (var k in ks) data.Remove(k);
|
||||||
|
data["default"] = v;
|
||||||
|
CollapsePaymentData(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var attributes = data
|
||||||
|
.Select(e => e.Key)
|
||||||
|
.Where(k => k.Length > 3 && k.Contains('/'))
|
||||||
|
.Select(k => "/" + k.Split('/')[1])
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
foreach (var idx in attributes) {
|
||||||
|
var len = data.Count(e => e.Key.EndsWith(idx));
|
||||||
|
foreach (var (v, ks) in rev1) {
|
||||||
|
var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
|
||||||
|
if (myKs.Count > 1 && myKs.Count >= len / 2.0) {
|
||||||
|
foreach (var k in myKs) data.Remove(k);
|
||||||
|
data[idx] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var (v, ks) in rev2) {
|
||||||
|
var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
|
||||||
|
if (myKs.Count > 1 && myKs.Count >= len / 2.0) {
|
||||||
|
foreach (var k in myKs) data.Remove(k);
|
||||||
|
data[idx] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonObject FromGraphEntries(IEnumerable<GraphEntry> graphEntries, BillingData? origData = null) {
|
||||||
|
var payment = new JsonObject();
|
||||||
|
var qualityWei = new JsonObject();
|
||||||
|
var curves = new JsonArray();
|
||||||
|
int curveId = 0;
|
||||||
|
foreach (var entry in graphEntries) {
|
||||||
|
var curve = GraphEntryToJson(entry);
|
||||||
|
JsonValue node;
|
||||||
|
if (curve is JsonObject obj) {
|
||||||
|
obj["id"] = ++curveId;
|
||||||
|
node = JsonValue.Create($"curve:{curveId}");
|
||||||
|
curves.Add(obj);
|
||||||
|
} else if (curve is JsonValue val && val.TryGetValue<decimal>(out var flat)) {
|
||||||
|
node = JsonValue.Create(flat);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach (var c in entry.Contracts) {
|
||||||
|
if (entry.Abgewertet) {
|
||||||
|
qualityWei[$"{c.Variety?.SortId}/{c.Attribute?.AttrId}"] = node.DeepClone();
|
||||||
|
} else {
|
||||||
|
payment[$"{c.Variety?.SortId}/{c.Attribute?.AttrId}"] = node.DeepClone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CollapsePaymentData(payment);
|
||||||
|
CollapsePaymentData(qualityWei);
|
||||||
|
|
||||||
var data = new JsonObject {
|
var data = new JsonObject {
|
||||||
["mode"] = "elwig",
|
["mode"] = "elwig",
|
||||||
["version"] = 1,
|
["version"] = 1,
|
||||||
};
|
};
|
||||||
if (ConsiderDelieryModifiers)
|
|
||||||
|
if (origData?.ConsiderDelieryModifiers == true)
|
||||||
data["consider_delivery_modifiers"] = true;
|
data["consider_delivery_modifiers"] = true;
|
||||||
if (ConsiderContractPenalties)
|
if (origData?.ConsiderContractPenalties == true)
|
||||||
data["consider_contract_penalties"] = true;
|
data["consider_contract_penalties"] = true;
|
||||||
if (ConsiderTotalPenalty)
|
if (origData?.ConsiderTotalPenalty == true)
|
||||||
data["consider_total_penalty"] = true;
|
data["consider_total_penalty"] = true;
|
||||||
if (ConsiderAutoBusinessShares)
|
if (origData?.ConsiderAutoBusinessShares == true)
|
||||||
data["consider_auto_business_shares"] = true;
|
data["consider_auto_business_shares"] = true;
|
||||||
|
|
||||||
var payment = new JsonObject();
|
if (payment.Count == 0) {
|
||||||
var curves = new JsonArray();
|
data["payment"] = 0;
|
||||||
|
} else if (payment.Count == 1) {
|
||||||
foreach (var entry in graphEntries) {
|
data["payment"] = payment.Single().Value?.DeepClone();
|
||||||
curves.Add(GraphEntryToJson(entry));
|
} else {
|
||||||
foreach (var contract in entry.Contracts) {
|
data["payment"] = payment;
|
||||||
payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}";
|
}
|
||||||
}
|
if (qualityWei.Count == 1) {
|
||||||
|
data["quality"] = new JsonObject() {
|
||||||
|
["WEI"] = qualityWei.Single().Value
|
||||||
|
};
|
||||||
|
} else if (qualityWei.Count > 1) {
|
||||||
|
data["quality"] = new JsonObject() {
|
||||||
|
["WEI"] = qualityWei
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
data["payment"] = payment;
|
|
||||||
data["curves"] = curves;
|
data["curves"] = curves;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -18,10 +18,11 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public double? GebundenFlatBonus {
|
public double? GebundenFlatBonus {
|
||||||
get {
|
get {
|
||||||
try {
|
try {
|
||||||
return GebundenGraph?.DataX.Zip(GebundenGraph.DataY)
|
var val = GebundenGraph?.DataX.Zip(GebundenGraph.DataY)
|
||||||
.Select(e => Math.Round(e.Second - DataGraph.GetPriceAtOe(e.First), Precision))
|
.Select(e => Math.Round(e.Second - DataGraph.GetPriceAtOe(e.First), Precision))
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.Single();
|
.Single();
|
||||||
|
return (val == 0) ? null : val;
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,13 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("fill_lower")]
|
[Column("fill_lower")]
|
||||||
public int FillLower { get; set; }
|
public int FillLower { get; set; }
|
||||||
|
|
||||||
|
public WineAttr() { }
|
||||||
|
|
||||||
|
public WineAttr(string attrId, string name) {
|
||||||
|
AttrId = attrId;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,13 @@ namespace Elwig.Models.Entities {
|
|||||||
public bool IsRed => Type == "R";
|
public bool IsRed => Type == "R";
|
||||||
public bool IsWhite => Type == "W";
|
public bool IsWhite => Type == "W";
|
||||||
|
|
||||||
|
public WineVar() { }
|
||||||
|
|
||||||
|
public WineVar(string sortId, string name) {
|
||||||
|
SortId = sortId;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,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 = origData.FromGraphEntries(GraphEntries);
|
var data = BillingData.FromGraphEntries(GraphEntries, origData);
|
||||||
|
|
||||||
EntityEntry<PaymentVar>? tr = null;
|
EntityEntry<PaymentVar>? tr = null;
|
||||||
try {
|
try {
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using Elwig.Helpers.Billing;
|
using Elwig.Helpers.Billing;
|
||||||
|
using Elwig.Models.Entities;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Tests.HelperTests {
|
namespace Tests.HelperTests {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class BillingDataTest {
|
public class BillingDataTest {
|
||||||
|
|
||||||
|
private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true };
|
||||||
private static readonly string[] AttributeVariants = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"];
|
private static readonly string[] AttributeVariants = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"];
|
||||||
|
|
||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
@ -41,7 +44,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_01_Flatrate() {
|
public void TestRead_01_Flatrate() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -57,7 +60,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_02_Simple() {
|
public void TestRead_02_Simple() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -92,7 +95,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_03_GreaterThanAndLessThan() {
|
public void TestRead_03_GreaterThanAndLessThan() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -131,7 +134,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_04_VariantsAndAttributes() {
|
public void TestRead_04_VariantsAndAttributes() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -161,7 +164,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_05_QualityLevel() {
|
public void TestRead_05_QualityLevel() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -192,7 +195,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_06_ModeOeAndKmw() {
|
public void TestRead_06_ModeOeAndKmw() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -234,7 +237,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_07_MultipleCurves() {
|
public void TestRead_07_MultipleCurves() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
@ -303,7 +306,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_08_WgMaster() {
|
public void TestRead_08_WgMaster() {
|
||||||
var data = PaymentBillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "wgmaster",
|
"mode": "wgmaster",
|
||||||
@ -345,5 +348,162 @@ namespace Tests.HelperTests {
|
|||||||
TestCalcOe(data, "GVK", 115, 0.065m);
|
TestCalcOe(data, "GVK", 115, 0.065m);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<ContractSelection> GetSelection(IEnumerable<string> attVars) {
|
||||||
|
return attVars.Select(s => {
|
||||||
|
var sortid = s[..2];
|
||||||
|
var attrid = s.Length > 2 ? s[2..] : null;
|
||||||
|
return new ContractSelection(
|
||||||
|
new WineVar(sortid, sortid),
|
||||||
|
attrid == null ? null : new WineAttr(attrid, attrid)
|
||||||
|
);
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWrite_01_Empty() {
|
||||||
|
List<GraphEntry> entries = [
|
||||||
|
new GraphEntry(1, 4, BillingData.CurveMode.Oe, new() {
|
||||||
|
[73] = 0.5m
|
||||||
|
}, null)
|
||||||
|
];
|
||||||
|
var updated = BillingData.FromGraphEntries(entries);
|
||||||
|
Assert.That(updated.ToJsonString(JsonOpts), Is.EqualTo("""
|
||||||
|
{
|
||||||
|
"mode": "elwig",
|
||||||
|
"version": 1,
|
||||||
|
"payment": 0,
|
||||||
|
"curves": []
|
||||||
|
}
|
||||||
|
"""));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWrite_02_Flatrate() {
|
||||||
|
List<GraphEntry> entries = [
|
||||||
|
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
|
||||||
|
[73] = 0.5m
|
||||||
|
}, null), GetSelection(["GV"]))
|
||||||
|
];
|
||||||
|
var data = BillingData.FromGraphEntries(entries);
|
||||||
|
Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo("""
|
||||||
|
{
|
||||||
|
"mode": "elwig",
|
||||||
|
"version": 1,
|
||||||
|
"payment": 0.5,
|
||||||
|
"curves": []
|
||||||
|
}
|
||||||
|
"""));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWrite_03_SingleCurve() {
|
||||||
|
List<GraphEntry> entries = [
|
||||||
|
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
|
||||||
|
[73] = 0.5m,
|
||||||
|
[83] = 1.0m
|
||||||
|
}, null), GetSelection(["GV"]))
|
||||||
|
];
|
||||||
|
var data = BillingData.FromGraphEntries(entries);
|
||||||
|
Assert.That(data.ToJsonString(JsonOpts), Is.EqualTo("""
|
||||||
|
{
|
||||||
|
"mode": "elwig",
|
||||||
|
"version": 1,
|
||||||
|
"payment": "curve:1",
|
||||||
|
"curves": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {
|
||||||
|
"73oe": 0.5,
|
||||||
|
"83oe": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWrite_04_Simple() {
|
||||||
|
List<GraphEntry> entries = [
|
||||||
|
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("""
|
||||||
|
{
|
||||||
|
"mode": "elwig",
|
||||||
|
"version": 1,
|
||||||
|
"payment": {
|
||||||
|
"WR/": 0.75,
|
||||||
|
"default": "curve:1"
|
||||||
|
},
|
||||||
|
"curves": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {
|
||||||
|
"73oe": 0.5,
|
||||||
|
"84oe": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWrite_05_Attribute() {
|
||||||
|
List<GraphEntry> entries = [
|
||||||
|
new GraphEntry(0, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
|
||||||
|
[73] = 0.5m,
|
||||||
|
[84] = 1.0m
|
||||||
|
}, null), GetSelection(["GVB", "ZWB"])),
|
||||||
|
new GraphEntry(2, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
|
||||||
|
[73] = 0.75m,
|
||||||
|
}, null), GetSelection(["WR", "BL", "RR", "FV"])),
|
||||||
|
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("""
|
||||||
|
{
|
||||||
|
"mode": "elwig",
|
||||||
|
"version": 1,
|
||||||
|
"payment": {
|
||||||
|
"BP/": "curve:2",
|
||||||
|
"SA/": "curve:2",
|
||||||
|
"default": 0.75,
|
||||||
|
"/B": "curve:1"
|
||||||
|
},
|
||||||
|
"curves": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {
|
||||||
|
"73oe": 0.5,
|
||||||
|
"84oe": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {
|
||||||
|
"73oe": 0.65,
|
||||||
|
"84oe": 1.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user