BillingData: Add GetCurveValueAt(), extracted from PaymentBillingData
This commit is contained in:
@ -124,6 +124,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
var obj = c?.AsObject() ?? throw new InvalidOperationException();
|
var obj = c?.AsObject() ?? throw new InvalidOperationException();
|
||||||
var id = obj["id"]?.GetValue<int>() ?? throw new InvalidOperationException();
|
var id = obj["id"]?.GetValue<int>() ?? throw new InvalidOperationException();
|
||||||
var cMode = (obj["mode"]?.GetValue<string>() == "kmw") ? CurveMode.Kmw : CurveMode.Oe;
|
var cMode = (obj["mode"]?.GetValue<string>() == "kmw") ? CurveMode.Kmw : CurveMode.Oe;
|
||||||
|
double quw = cMode == CurveMode.Oe ? 73 : 15;
|
||||||
|
|
||||||
Dictionary<double, decimal> c1;
|
Dictionary<double, decimal> c1;
|
||||||
Dictionary<double, decimal>? c2 = null;
|
Dictionary<double, decimal>? c2 = null;
|
||||||
@ -131,7 +132,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
if (norm is JsonObject) {
|
if (norm is JsonObject) {
|
||||||
c1 = GetCurveData(norm.AsObject(), cMode);
|
c1 = GetCurveData(norm.AsObject(), cMode);
|
||||||
} else if (norm?.AsValue().TryGetValue(out decimal v) == true) {
|
} else if (norm?.AsValue().TryGetValue(out decimal v) == true) {
|
||||||
c1 = new() { { cMode == CurveMode.Oe ? 73 : 15, v } };
|
c1 = new() { { quw, v } };
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
@ -139,7 +140,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
if (geb is JsonObject) {
|
if (geb is JsonObject) {
|
||||||
c2 = GetCurveData(geb.AsObject(), cMode);
|
c2 = GetCurveData(geb.AsObject(), cMode);
|
||||||
} else if (geb?.AsValue().TryGetValue(out decimal v) == true) {
|
} else if (geb?.AsValue().TryGetValue(out decimal v) == true) {
|
||||||
c2 = c1.ToDictionary(e => e.Key, e => e.Value + v);
|
var splitVal = GetCurveValueAt(c1, quw);
|
||||||
|
c2 = c1.ToDictionary(e => e.Key, e => e.Value + (e.Key >= quw ? v : 0));
|
||||||
|
c2[quw] = splitVal + v;
|
||||||
|
c2[Math.BitDecrement(quw)] = splitVal;
|
||||||
}
|
}
|
||||||
dict.Add(id, new(cMode, c1, c2));
|
dict.Add(id, new(cMode, c1, c2));
|
||||||
}
|
}
|
||||||
@ -181,5 +185,25 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static decimal GetCurveValueAt(Dictionary<double, decimal> curve, double key) {
|
||||||
|
if (curve.Count == 1) return curve.First().Value;
|
||||||
|
|
||||||
|
var lt = curve.Keys.Where(v => v <= key);
|
||||||
|
var gt = curve.Keys.Where(v => v >= key);
|
||||||
|
if (!lt.Any()) {
|
||||||
|
return curve[gt.Min()];
|
||||||
|
} else if (!gt.Any()) {
|
||||||
|
return curve[lt.Max()];
|
||||||
|
}
|
||||||
|
|
||||||
|
var max = lt.Max();
|
||||||
|
var min = gt.Min();
|
||||||
|
if (max == min) return curve[key];
|
||||||
|
|
||||||
|
var p1 = ((decimal)key - (decimal)min) / ((decimal)max - (decimal)min);
|
||||||
|
var p2 = 1 - p1;
|
||||||
|
return curve[min] * p2 + curve[max] * p1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,25 +49,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
public decimal CalculatePrice(string sortid, string? attrid, string qualid, bool gebunden, double oe, double kmw) {
|
public decimal CalculatePrice(string sortid, string? attrid, string qualid, bool gebunden, double oe, double kmw) {
|
||||||
var curve = GetQualityCurve(qualid, sortid, attrid) ?? GetCurve(sortid, attrid);
|
var curve = GetQualityCurve(qualid, sortid, attrid) ?? GetCurve(sortid, attrid);
|
||||||
var d = (gebunden ? curve.Gebunden : null) ?? curve.Normal;
|
return GetCurveValueAt((gebunden ? curve.Gebunden : null) ?? curve.Normal, curve.Mode == CurveMode.Oe ? oe : kmw);
|
||||||
if (d.Count == 1) return d.First().Value;
|
|
||||||
|
|
||||||
var r = curve.Mode == CurveMode.Oe ? oe : kmw;
|
|
||||||
var lt = d.Keys.Where(v => v <= r);
|
|
||||||
var gt = d.Keys.Where(v => v >= r);
|
|
||||||
if (!lt.Any()) {
|
|
||||||
return d[gt.Min()];
|
|
||||||
} else if (!gt.Any()) {
|
|
||||||
return d[lt.Max()];
|
|
||||||
}
|
|
||||||
|
|
||||||
var max = lt.Max();
|
|
||||||
var min = gt.Min();
|
|
||||||
if (max == min) return d[r];
|
|
||||||
|
|
||||||
var p1 = ((decimal)r - (decimal)min) / ((decimal)max - (decimal)min);
|
|
||||||
var p2 = 1 - p1;
|
|
||||||
return d[min] * p2 + d[max] * p1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Curve LookupCurve(JsonValue val) {
|
private Curve LookupCurve(JsonValue val) {
|
||||||
|
Reference in New Issue
Block a user