From a2bb09cfbdbc3e0579f3030cf46758dbb835b8cf Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sun, 21 Jan 2024 00:31:20 +0100 Subject: [PATCH] Billing: Build BillingData-Json in BillingData instead of anywhere else --- Elwig/Helpers/Billing/BillingData.cs | 70 ++++++++++++++++++++++++ Elwig/Helpers/Billing/EditBillingData.cs | 2 +- Elwig/Helpers/Billing/Graph.cs | 43 ++++----------- Elwig/Helpers/Billing/GraphEntry.cs | 53 ++++++------------ Elwig/Windows/ChartWindow.xaml.cs | 39 +++---------- 5 files changed, 106 insertions(+), 101 deletions(-) diff --git a/Elwig/Helpers/Billing/BillingData.cs b/Elwig/Helpers/Billing/BillingData.cs index d59e4e4..858089d 100644 --- a/Elwig/Helpers/Billing/BillingData.cs +++ b/Elwig/Helpers/Billing/BillingData.cs @@ -205,5 +205,75 @@ namespace Elwig.Helpers.Billing { var p2 = 1 - p1; return curve[min] * p2 + curve[max] * p1; } + + protected static JsonNode GraphToJson(Graph graph, string mode) { + var x = graph.DataX; + var y = graph.DataY; + if (y.Distinct().Count() == 1) { + return JsonValue.Create(graph.DataY[0]); + } + + var data = new JsonObject(); + + if (y[0] != y[1]) { + data.Add(new KeyValuePair(x[0] + mode, Math.Round(y[0], graph.Precision))); + } + 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)) { + data.Add(new KeyValuePair(x[i] + mode, Math.Round(y[i], graph.Precision))); + } + } + if (y[^1] != y[^2]) { + data.Add(new KeyValuePair(x[^1] + mode, Math.Round(y[^1], graph.Precision))); + } + return data; + } + + protected static JsonObject GraphEntryToJson(GraphEntry entry) { + var curve = new JsonObject { + ["id"] = entry.Id, + ["mode"] = entry.Mode.ToString().ToLower(), + }; + + curve["data"] = GraphToJson(entry.DataGraph, entry.Mode.ToString().ToLower()); + + if (entry.GebundenFlatBonus != null) { + curve["geb"] = entry.GebundenFlatBonus; + } else if (entry.GebundenGraph != null) { + curve["geb"] = GraphToJson(entry.GebundenGraph, entry.Mode.ToString().ToLower()); + } + + return curve; + } + + public JsonObject FromGraphEntries(IEnumerable graphEntries) { + var payment = new JsonObject(); + var curves = new JsonArray(); + + foreach (var entry in graphEntries) { + curves.Add(GraphEntryToJson(entry)); + foreach (var contract in entry.Contracts) { + payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}"; + } + } + + var data = new JsonObject { + ["mode"] = "elwig", + ["version"] = 1, + }; + if (ConsiderDelieryModifiers) + data["consider_delivery_modifiers"] = true; + if (ConsiderContractPenalties) + data["consider_contract_penalties"] = true; + if (ConsiderTotalPenalty) + data["consider_total_penalty"] = true; + if (ConsiderAutoBusinessShares) + data["consider_auto_business_shares"] = true; + + data["payment"] = payment; + data["curves"] = curves; + + return data; + } } } diff --git a/Elwig/Helpers/Billing/EditBillingData.cs b/Elwig/Helpers/Billing/EditBillingData.cs index a287cd4..cf026cb 100644 --- a/Elwig/Helpers/Billing/EditBillingData.cs +++ b/Elwig/Helpers/Billing/EditBillingData.cs @@ -67,7 +67,7 @@ namespace Elwig.Helpers.Billing { var attrs = context.WineAttributes.ToDictionary(a => a.AttrId, a => a); return dict3 - .Select(e => new GraphEntry(e.Key, season, curves[e.Key], e.Value + .Select(e => new GraphEntry(e.Key, season.Precision, curves[e.Key], e.Value .Select(s => new ContractSelection(vars[s[..2]], s.Length > 2 ? attrs[s[2..]] : null)) .ToList(), 50, 73, 140)) .ToList(); diff --git a/Elwig/Helpers/Billing/Graph.cs b/Elwig/Helpers/Billing/Graph.cs index d199aed..d86c989 100644 --- a/Elwig/Helpers/Billing/Graph.cs +++ b/Elwig/Helpers/Billing/Graph.cs @@ -1,37 +1,35 @@ -using Elwig.Models.Entities; using ScottPlot; using System; using System.Collections.Generic; using System.Linq; -using System.Text.Json.Nodes; namespace Elwig.Helpers.Billing { public class Graph : ICloneable { - private readonly Season Season; + public readonly int Precision; public double[] DataX { get; set; } public double[] DataY { get; set; } public int MinX { get; set; } public int MaxX { get; set; } - public Graph(Season season, int minX, int maxX) { - Season = season; + public Graph(int precision, int minX, int maxX) { + Precision = precision; MinX = minX; MaxX = maxX; DataX = DataGen.Range(minX, maxX + 1); DataY = DataGen.Zeros(maxX - minX + 1); } - public Graph(Dictionary data, Season season, int minX, int maxX) { - Season = season; + public Graph(Dictionary data, int precision, int minX, int maxX) { + Precision = precision; MinX = minX; MaxX = maxX; DataX = DataGen.Range(minX, maxX + 1); DataY = DataX.Select(i => (double)BillingData.GetCurveValueAt(data, i)).ToArray(); } - private Graph(double[] dataX, double[] dataY, Season season, int minX, int maxX) { - Season = season; + private Graph(double[] dataX, double[] dataY, int precision, int minX, int maxX) { + Precision = precision; MinX = minX; MaxX = maxX; DataX = dataX; @@ -70,7 +68,7 @@ namespace Elwig.Helpers.Billing { private void LinearIncreaseGraph(int begin, int end, double inc) { for (int i = begin; i < end; i++) { - DataY[i + 1] = Math.Round(DataY[i] + inc, Season.Precision); + DataY[i + 1] = Math.Round(DataY[i] + inc, Precision); } } @@ -87,33 +85,12 @@ namespace Elwig.Helpers.Billing { double step = (DataY[highIndex] - DataY[lowIndex]) / steps; for (int i = lowIndex; i < highIndex - 1; i++) { - DataY[i + 1] = Math.Round(DataY[i] + step, Season.Precision); + DataY[i + 1] = Math.Round(DataY[i] + step, Precision); } } - public JsonNode ToJson(string mode) { - if (DataY.Distinct().Count() == 1) { - return JsonValue.Create(DataY[0]); - } - - var data = new JsonObject(); - - if (DataY[0] != DataY[1]) { - data.Add(new KeyValuePair(DataX[0] + mode, Math.Round(DataY[0], Season.Precision))); - } - for (int i = 1; i < DataX.Length - 1; i++) { - if (Math.Round(DataY[i] - DataY[i - 1], 10) != Math.Round(DataY[i + 1] - DataY[i], 10)) { - data.Add(new KeyValuePair(DataX[i] + mode, Math.Round(DataY[i], Season.Precision))); - } - } - if (DataY[^1] != DataY[^2]) { - data.Add(new KeyValuePair(DataX[^1] + mode, Math.Round(DataY[^1], Season.Precision))); - } - return data; - } - public object Clone() { - return new Graph((double[])DataX.Clone(), (double[])DataY.Clone(), Season, MinX, MaxX); + return new Graph((double[])DataX.Clone(), (double[])DataY.Clone(), Precision, MinX, MaxX); } } } diff --git a/Elwig/Helpers/Billing/GraphEntry.cs b/Elwig/Helpers/Billing/GraphEntry.cs index 3bcb47a..255f78f 100644 --- a/Elwig/Helpers/Billing/GraphEntry.cs +++ b/Elwig/Helpers/Billing/GraphEntry.cs @@ -1,13 +1,11 @@ -using Elwig.Models.Entities; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text.Json.Nodes; namespace Elwig.Helpers.Billing { public class GraphEntry { public int Id { get; set; } - private readonly Season Season; + private readonly int Precision; public BillingData.CurveMode Mode { get; set; } public bool Abgewertet { get; set; } public Graph DataGraph { get; set; } @@ -20,36 +18,36 @@ namespace Elwig.Helpers.Billing { private int MinXGebunden { get; set; } private int MaxX { get; set; } - public GraphEntry(int id, Season season, BillingData.CurveMode mode, int minX, int minXGebunden, int maxX) { + public GraphEntry(int id, int precision, BillingData.CurveMode mode, int minX, int minXGebunden, int maxX) { Id = id; - Season = season; + Precision = precision; Mode = mode; Abgewertet = false; MinX = minX; MinXGebunden = minXGebunden; MaxX = maxX; - DataGraph = new Graph(season, minX, maxX); + DataGraph = new Graph(precision, minX, maxX); Contracts = []; } - public GraphEntry(int id, Season season, BillingData.CurveMode mode, Dictionary data, Dictionary? gebunden, - int minX, int minXGebunden, int maxX) : this(id, season, mode, minX, minXGebunden, maxX) { - DataGraph = new Graph(data, season, minX, maxX); - if (gebunden != null) GebundenGraph = new Graph(gebunden, season, minXGebunden, maxX); + public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary data, Dictionary? gebunden, + int minX, int minXGebunden, int maxX) : this(id, precision, mode, minX, minXGebunden, maxX) { + DataGraph = new Graph(data, precision, minX, maxX); + if (gebunden != null) GebundenGraph = new Graph(gebunden, precision, minXGebunden, maxX); } - public GraphEntry(int id, Season season, BillingData.Curve curve, List contracts, int minX, int minXGebunden, int maxX) : - this(id, season, curve.Mode, minX, minXGebunden, maxX) { - DataGraph = new Graph(curve.Normal, season, minX, maxX); + public GraphEntry(int id, int precision, BillingData.Curve curve, List contracts, int minX, int minXGebunden, int maxX) : + this(id, precision, curve.Mode, minX, minXGebunden, maxX) { + DataGraph = new Graph(curve.Normal, precision, minX, maxX); if (curve.Gebunden != null) - GebundenGraph = new Graph(curve.Gebunden, season, minXGebunden, maxX); + GebundenGraph = new Graph(curve.Gebunden, precision, minXGebunden, maxX); Contracts = contracts; } - private GraphEntry(int id, Season season, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, + private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, decimal? gebundenFlatPrice, List contracts, int minX, int minXGebunden, int maxX) { Id = id; - Season = season; + Precision = precision; Mode = mode; MinX = minX; MinXGebunden = minXGebunden; @@ -61,7 +59,7 @@ namespace Elwig.Helpers.Billing { } public void AddGebundenGraph() { - GebundenGraph ??= new Graph(Season, MinXGebunden, MaxX); + GebundenGraph ??= new Graph(Precision, MinXGebunden, MaxX); } public void RemoveGebundenGraph() { @@ -72,25 +70,8 @@ namespace Elwig.Helpers.Billing { GebundenFlatBonus = value; } - public JsonObject ToJson() { - var curve = new JsonObject { - ["id"] = Id, - ["mode"] = Mode.ToString().ToLower(), - }; - - curve["data"] = DataGraph.ToJson(Mode.ToString().ToLower()); - - if (GebundenFlatBonus != null) { - curve["geb"] = GebundenFlatBonus; - } else if (GebundenGraph != null) { - curve["geb"] = GebundenGraph.ToJson(Mode.ToString().ToLower()); - } - - return curve; - } - public GraphEntry Copy(int id) { - return new GraphEntry(id, Season, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatBonus, [], MinX, MinXGebunden, MaxX); + return new GraphEntry(id, Precision, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatBonus, [], MinX, MinXGebunden, MaxX); } } } diff --git a/Elwig/Windows/ChartWindow.xaml.cs b/Elwig/Windows/ChartWindow.xaml.cs index 59672d2..eecc21c 100644 --- a/Elwig/Windows/ChartWindow.xaml.cs +++ b/Elwig/Windows/ChartWindow.xaml.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; -using System.Text.Json.Nodes; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -26,7 +25,7 @@ namespace Elwig.Windows { public readonly int Year; public readonly int AvNr; public readonly Season Season; - private readonly PaymentVar PaymentVar; + private PaymentVar PaymentVar; private ScatterPlot DataPlot; private ScatterPlot? GebundenPlot; @@ -66,6 +65,7 @@ namespace Elwig.Windows { private async Task RefreshGraphList() { await Context.PaymentVariants.LoadAsync(); + PaymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found"); var attrVariants = (await Context.DeliveryParts .Where(d => d.Year == Year) @@ -497,7 +497,7 @@ namespace Elwig.Windows { } private void AddButton_Click(object sender, RoutedEventArgs e) { - GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, Season, BillingData.CurveMode.Oe, MinOechsle, MinOechsleGebunden, MaxOechsle); + GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, Season.Precision, BillingData.CurveMode.Oe, MinOechsle, MinOechsleGebunden, MaxOechsle); GraphEntries.Add(newGraphEntry); GraphList.Items.Refresh(); GraphList.SelectedItem = newGraphEntry; @@ -526,46 +526,23 @@ namespace Elwig.Windows { } private async void SaveButton_Click(object sender, RoutedEventArgs e) { - await SaveGraphs(); - } + var origData = BillingData.FromJson(PaymentVar.Data); + var data = origData.FromGraphEntries(GraphEntries); - private async Task SaveGraphs() { - var payment = new JsonObject(); - var curves = new JsonArray(); - - foreach (var entry in GraphEntries) { - curves.Add(entry.ToJson()); - foreach (var contract in entry.Contracts) { - payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}"; - } - } - - var data = new JsonObject { - ["mode"] = "elwig", - ["version"] = 1, - ["payment"] = payment, - ["curves"] = curves - }; - - - MessageBox.Show(data.ToJsonString()); - - /* EntityEntry? tr = null; try { PaymentVar.Data = data.ToJsonString(); tr = Context.Update(PaymentVar); - await Context.SaveChangesAsync(); + LockContext = false; await App.HintContextChange(); - await RefreshGraphList(); } catch (Exception exc) { if (tr != null) await tr.ReloadAsync(); var str = "Der Eintrag konnte nicht in der Datenbank gespeichert werden!\n\n" + exc.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; - MessageBox.Show(str, "Graph speichern", MessageBoxButton.OK, MessageBoxImage.Error); + MessageBox.Show(str, "Auszahlungsvariante speichern", MessageBoxButton.OK, MessageBoxImage.Error); } - */ + LockContext = true; } private void EnableUnitTextBox(UnitTextBox u) {