Compare commits
16 Commits
b52c09a176
...
v0.6.0
Author | SHA1 | Date | |
---|---|---|---|
42bf01656e | |||
51293baaae | |||
1d1398a9cd | |||
7d199282d0 | |||
b56a5ed5c6 | |||
201b63c2f1 | |||
b2bd0c9a21 | |||
8502afdc9a | |||
cb541cb6e6 | |||
403e7723d2 | |||
8fbce03031 | |||
b32a935150 | |||
337bfa89d9 | |||
f886888ccc | |||
4dd036babd | |||
b6fd62f8ca |
@@ -65,22 +65,27 @@ namespace Elwig {
|
|||||||
MainDispatcher = Dispatcher;
|
MainDispatcher = Dispatcher;
|
||||||
Scales = Array.Empty<IScale>();
|
Scales = Array.Empty<IScale>();
|
||||||
CurrentApp = this;
|
CurrentApp = this;
|
||||||
|
OverrideCulture();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnStartup(StartupEventArgs evt) {
|
private static void OverrideCulture() {
|
||||||
var locale = new CultureInfo("de-AT");
|
var locale = new CultureInfo("de-AT", false);
|
||||||
locale.NumberFormat.CurrencyGroupSeparator = "\u202f";
|
locale.NumberFormat.CurrencyGroupSeparator = Utils.GroupSeparator;
|
||||||
locale.NumberFormat.NumberGroupSeparator = "\u202f";
|
locale.NumberFormat.NumberGroupSeparator = Utils.GroupSeparator;
|
||||||
locale.NumberFormat.PercentGroupSeparator = "\u202f";
|
locale.NumberFormat.PercentGroupSeparator = Utils.GroupSeparator;
|
||||||
|
CultureInfo.CurrentCulture = locale;
|
||||||
|
CultureInfo.CurrentUICulture = locale;
|
||||||
Thread.CurrentThread.CurrentCulture = locale;
|
Thread.CurrentThread.CurrentCulture = locale;
|
||||||
Thread.CurrentThread.CurrentUICulture = locale;
|
Thread.CurrentThread.CurrentUICulture = locale;
|
||||||
CultureInfo.DefaultThreadCurrentCulture = locale;
|
CultureInfo.DefaultThreadCurrentCulture = locale;
|
||||||
CultureInfo.DefaultThreadCurrentUICulture = locale;
|
CultureInfo.DefaultThreadCurrentUICulture = locale;
|
||||||
FrameworkElement.LanguageProperty.OverrideMetadata(
|
FrameworkElement.LanguageProperty.OverrideMetadata(
|
||||||
typeof(FrameworkElement),
|
typeof(FrameworkElement),
|
||||||
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))
|
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.Name))
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async void OnStartup(StartupEventArgs evt) {
|
||||||
Version = typeof(App).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split("+")[0] ?? "0.0.0";
|
Version = typeof(App).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split("+")[0] ?? "0.0.0";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@@ -12,7 +12,7 @@ namespace Elwig.Dialogs {
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
TextLsNr.Text = lsnr;
|
TextLsNr.Text = lsnr;
|
||||||
TextMember.Text = name;
|
TextMember.Text = name;
|
||||||
TextWeight.Text = $"{weight:N0}\u202fkg";
|
TextWeight.Text = $"{weight:N0}{Utils.UnitSeparator}kg";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
@@ -14,7 +13,7 @@ namespace Elwig.Dialogs {
|
|||||||
|
|
||||||
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
Price = double.Parse(PriceInput.Text.Replace("\u202f", ""));
|
Price = double.Parse(PriceInput.Text.Replace(Utils.GroupSeparator, ""));
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>0.5.1</Version>
|
<Version>0.6.0</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -25,11 +25,11 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.1" />
|
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.1" />
|
||||||
<PackageReference Include="LinqKit" Version="1.2.5" />
|
<PackageReference Include="LinqKit" Version="1.2.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.25" />
|
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.26" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2151.40" />
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
|
||||||
<PackageReference Include="NJsonSchema" Version="11.0.0" />
|
<PackageReference Include="NJsonSchema" Version="11.0.0" />
|
||||||
<PackageReference Include="RazorLight" Version="2.3.1" />
|
<PackageReference Include="RazorLight" Version="2.3.1" />
|
||||||
<PackageReference Include="ScottPlot.WPF" Version="4.1.68" />
|
<PackageReference Include="ScottPlot.WPF" Version="4.1.68" />
|
||||||
|
@@ -13,7 +13,6 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
public enum CalculationMode { Elwig, WgMaster }
|
public enum CalculationMode { Elwig, WgMaster }
|
||||||
public enum CurveMode { Oe, Kmw }
|
public enum CurveMode { Oe, Kmw }
|
||||||
|
|
||||||
public record struct Curve(CurveMode Mode, Dictionary<double, decimal> Normal, Dictionary<double, decimal>? Gebunden);
|
public record struct Curve(CurveMode Mode, Dictionary<double, decimal> Normal, Dictionary<double, decimal>? Gebunden);
|
||||||
|
|
||||||
public static JsonSchema? Schema { get; private set; }
|
public static JsonSchema? Schema { get; private set; }
|
||||||
@@ -24,11 +23,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public readonly JsonObject Data;
|
public readonly JsonObject Data;
|
||||||
|
public readonly CalculationMode Mode;
|
||||||
private readonly CalculationMode Mode;
|
|
||||||
private readonly Dictionary<int, Curve> Curves;
|
|
||||||
private readonly Dictionary<string, Curve> PaymentData;
|
|
||||||
private readonly Dictionary<string, Curve> QualityData;
|
|
||||||
|
|
||||||
public bool ConsiderDelieryModifiers {
|
public bool ConsiderDelieryModifiers {
|
||||||
get => GetConsider("consider_delivery_modifiers");
|
get => GetConsider("consider_delivery_modifiers");
|
||||||
@@ -61,18 +56,13 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BillingData(JsonObject data, IEnumerable<string> attributeVariants) {
|
public BillingData(JsonObject data) {
|
||||||
if (attributeVariants.Any(e => e.Any(c => c < 'A' || c > 'Z')))
|
|
||||||
throw new ArgumentException("Invalid attributeVariants");
|
|
||||||
Data = data;
|
Data = data;
|
||||||
var mode = Data["mode"]?.GetValue<string>();
|
var mode = Data["mode"]?.GetValue<string>();
|
||||||
Mode = (mode == "elwig") ? CalculationMode.Elwig : CalculationMode.WgMaster;
|
Mode = (mode == "elwig") ? CalculationMode.Elwig : CalculationMode.WgMaster;
|
||||||
Curves = GetCurves(Data, Mode);
|
|
||||||
PaymentData = GetPaymentData(attributeVariants);
|
|
||||||
QualityData = GetQualityData(attributeVariants);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JsonObject ParseJson(string json) {
|
protected static JsonObject ParseJson(string json) {
|
||||||
if (Schema == null) throw new InvalidOperationException("Schema has to be initialized first");
|
if (Schema == null) throw new InvalidOperationException("Schema has to be initialized first");
|
||||||
try {
|
try {
|
||||||
var errors = Schema.Validate(json);
|
var errors = Schema.Validate(json);
|
||||||
@@ -84,11 +74,19 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static BillingData FromJson(string json) {
|
public static BillingData FromJson(string json) {
|
||||||
return FromJson(json, []);
|
return new(ParseJson(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BillingData FromJson(string json, IEnumerable<string> attributeVariants) {
|
protected JsonArray GetCurvesEntry() {
|
||||||
return new(ParseJson(json), attributeVariants);
|
return Data[Mode == CalculationMode.Elwig ? "curves" : "Kurven"]?.AsArray() ?? throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonNode GetPaymentEntry() {
|
||||||
|
return Data[Mode == CalculationMode.Elwig ? "payment" : "AuszahlungSorten"] ?? throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonObject? GetQualityEntry() {
|
||||||
|
return Data[Mode == CalculationMode.Elwig ? "quality" : "AuszahlungSortenQualitätsstufe"]?.AsObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<double, decimal> GetCurveData(JsonObject data, CurveMode mode) {
|
private static Dictionary<double, decimal> GetCurveData(JsonObject data, CurveMode mode) {
|
||||||
@@ -119,9 +117,9 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<int, Curve> GetCurves(JsonObject data, CalculationMode mode) {
|
protected Dictionary<int, Curve> GetCurves() {
|
||||||
var dict = new Dictionary<int, Curve>();
|
var dict = new Dictionary<int, Curve>();
|
||||||
var curves = data[mode == CalculationMode.Elwig ? "curves" : "Kurven"]?.AsArray() ?? throw new InvalidOperationException();
|
var curves = GetCurvesEntry();
|
||||||
foreach (var c in curves) {
|
foreach (var c in curves) {
|
||||||
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();
|
||||||
@@ -147,108 +145,5 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, Curve> GetData(JsonObject data, IEnumerable<string> attributeVariants) {
|
|
||||||
Dictionary<string, Curve> dict;
|
|
||||||
if (data["default"] is JsonValue def) {
|
|
||||||
var c = LookupCurve(def);
|
|
||||||
dict = attributeVariants.ToDictionary(e => e, _ => c);
|
|
||||||
} else {
|
|
||||||
dict = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var variants = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length == 2);
|
|
||||||
var attributes = data.Where(p => p.Key.StartsWith('/'));
|
|
||||||
var others = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length > 2);
|
|
||||||
foreach (var (idx, v) in variants) {
|
|
||||||
var curve = LookupCurve(v?.AsValue() ?? throw new InvalidOperationException());
|
|
||||||
foreach (var i in attributeVariants.Where(e => e.StartsWith(idx[..^1]))) {
|
|
||||||
dict[i] = curve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (var (idx, v) in attributes) {
|
|
||||||
var curve = LookupCurve(v?.AsValue() ?? throw new InvalidOperationException());
|
|
||||||
foreach (var i in attributeVariants.Where(e => e[2..] == idx[1..])) {
|
|
||||||
dict[i] = curve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (var (idx, v) in others) {
|
|
||||||
var curve = LookupCurve(v?.AsValue() ?? throw new InvalidOperationException());
|
|
||||||
dict[idx.Replace("/", "")] = curve;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, Curve> GetPaymentData(IEnumerable<string> attributeVariants) {
|
|
||||||
var p = Data[Mode == CalculationMode.Elwig ? "payment" : "AuszahlungSorten"];
|
|
||||||
if (p is JsonValue val) {
|
|
||||||
var c = LookupCurve(val);
|
|
||||||
return attributeVariants.ToDictionary(e => e, _ => c);
|
|
||||||
}
|
|
||||||
return GetData(p?.AsObject() ?? throw new InvalidOperationException(), attributeVariants);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, Curve> GetQualityData(IEnumerable<string> attributeVariants) {
|
|
||||||
var q = Data[Mode == CalculationMode.Elwig ? "quality" : "AuszahlungSortenQualitätsstufe"]?.AsObject();
|
|
||||||
Dictionary<string, Curve> dict = [];
|
|
||||||
if (q == null) return dict;
|
|
||||||
|
|
||||||
foreach (var (qualid, data) in q) {
|
|
||||||
Dictionary<string, Curve> qualDict;
|
|
||||||
if (data is JsonValue val) {
|
|
||||||
var c = LookupCurve(val);
|
|
||||||
qualDict = attributeVariants.ToDictionary(e => e, _ => c);
|
|
||||||
} else {
|
|
||||||
qualDict = GetData(data?.AsObject() ?? throw new InvalidOperationException(), attributeVariants);
|
|
||||||
}
|
|
||||||
foreach (var (idx, d) in qualDict) {
|
|
||||||
dict[$"{qualid}/{idx}"] = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 d = (gebunden ? curve.Gebunden : null) ?? curve.Normal;
|
|
||||||
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) {
|
|
||||||
if (val.TryGetValue(out string? curve)) {
|
|
||||||
var curveId = int.Parse(curve.Split(":")[1]);
|
|
||||||
return Curves[curveId];
|
|
||||||
} else if (val.TryGetValue(out decimal value)) {
|
|
||||||
return new(CurveMode.Oe, new() { { 73, value } }, null);
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Curve GetCurve(string sortid, string? attrid) {
|
|
||||||
return PaymentData[$"{sortid}{attrid ?? ""}"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Curve? GetQualityCurve(string qualid, string sortid, string? attrid) {
|
|
||||||
return QualityData.TryGetValue($"{qualid}/{sortid}{attrid ?? ""}", out var curve) ? curve : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
protected readonly int AvNr;
|
protected readonly int AvNr;
|
||||||
protected readonly PaymentVar PaymentVariant;
|
protected readonly PaymentVar PaymentVariant;
|
||||||
protected readonly BillingData Data;
|
protected readonly PaymentBillingData Data;
|
||||||
|
|
||||||
public BillingVariant(int year, int avnr) : base(year) {
|
public BillingVariant(int year, int avnr) : base(year) {
|
||||||
AvNr = avnr;
|
AvNr = avnr;
|
||||||
@@ -22,7 +22,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
.ToList()
|
.ToList()
|
||||||
.Union(Context.WineVarieties.Select(v => v.SortId))
|
.Union(Context.WineVarieties.Select(v => v.SortId))
|
||||||
.ToList();
|
.ToList();
|
||||||
Data = BillingData.FromJson(PaymentVariant.Data, attrVariants);
|
Data = PaymentBillingData.FromJson(PaymentVariant.Data, attrVariants);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Calculate() {
|
public async Task Calculate() {
|
||||||
|
90
Elwig/Helpers/Billing/EditBillingData.cs
Normal file
90
Elwig/Helpers/Billing/EditBillingData.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
|
namespace Elwig.Helpers.Billing {
|
||||||
|
public class EditBillingData : BillingData {
|
||||||
|
|
||||||
|
protected readonly IEnumerable<string> AttributeVariants;
|
||||||
|
|
||||||
|
public EditBillingData(JsonObject data, IEnumerable<string> attributeVariants) :
|
||||||
|
base(data) {
|
||||||
|
AttributeVariants = attributeVariants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EditBillingData FromJson(string json, IEnumerable<string> attributeVariants) {
|
||||||
|
return new(ParseJson(json), attributeVariants);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<GraphEntry> GetPaymentGraphEntries() {
|
||||||
|
Dictionary<int, List<string>> dict1 = [];
|
||||||
|
Dictionary<decimal, List<string>> dict2 = [];
|
||||||
|
var p = GetPaymentEntry();
|
||||||
|
if (p is JsonObject paymentObj) {
|
||||||
|
foreach (var (selector, node) in paymentObj) {
|
||||||
|
var val = node?.AsValue();
|
||||||
|
if (val == null) {
|
||||||
|
continue;
|
||||||
|
} else if (val.TryGetValue<decimal>(out var price)) {
|
||||||
|
if (!dict2.ContainsKey(price)) dict2[price] = [];
|
||||||
|
dict2[price].Add(selector);
|
||||||
|
} else if (val.TryGetValue<string>(out var curve)) {
|
||||||
|
var idx = int.Parse(curve.Split(":")[1] ?? "0");
|
||||||
|
if (!dict1.ContainsKey(idx)) dict1[idx] = [];
|
||||||
|
dict1[idx].Add(selector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p is JsonValue paymentVal) {
|
||||||
|
var idx = paymentVal.GetValue<decimal>();
|
||||||
|
if (!dict2.ContainsKey(idx)) dict2[idx] = [];
|
||||||
|
dict2[idx].Add("default");
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<int, Curve> curves = GetCurves();
|
||||||
|
decimal[] virtCurves = [.. dict2.Keys.Order()];
|
||||||
|
for (int i = 0; i < virtCurves.Length; i++) {
|
||||||
|
var idx = virtCurves[i];
|
||||||
|
dict1[1000 + i] = dict2[idx];
|
||||||
|
curves[1000 + i] = new Curve(CurveMode.Oe, new() { { 73, idx } }, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<int, List<string>> dict3 = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return dict3.Select(e => new GraphEntry(e.Key, curves[e.Key], 50, 120)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<GraphEntry> GetQualityGraphEntries() {
|
||||||
|
Dictionary<int, List<string>> dict1 = [];
|
||||||
|
Dictionary<decimal, List<string>> dict2 = [];
|
||||||
|
foreach (var (qualid, q) in GetQualityEntry() ?? []) {
|
||||||
|
if (q is JsonObject qualityObj) {
|
||||||
|
foreach (var (selector, node) in qualityObj) {
|
||||||
|
var val = node?.AsValue();
|
||||||
|
if (val == null) {
|
||||||
|
continue;
|
||||||
|
} else if (val.TryGetValue<decimal>(out var price)) {
|
||||||
|
if (!dict2.ContainsKey(price)) dict2[price] = [];
|
||||||
|
dict2[price].Add(selector);
|
||||||
|
} else if (val.TryGetValue<string>(out var curve)) {
|
||||||
|
var idx = int.Parse(curve.Split(":")[1] ?? "0");
|
||||||
|
if (!dict1.ContainsKey(idx)) dict1[idx] = [];
|
||||||
|
dict1[idx].Add(selector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (q is JsonValue qualityVal) {
|
||||||
|
var idx = qualityVal.GetValue<decimal>();
|
||||||
|
if (!dict2.ContainsKey(idx)) dict2[idx] = [];
|
||||||
|
dict2[idx].Add($"{qualid}/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
List<GraphEntry> list = [];
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -7,113 +7,101 @@ using System.Text.Json.Nodes;
|
|||||||
namespace Elwig.Helpers.Billing {
|
namespace Elwig.Helpers.Billing {
|
||||||
public class Graph : ICloneable {
|
public class Graph : ICloneable {
|
||||||
|
|
||||||
public string Type { get; set; }
|
|
||||||
public int Num { get; set; }
|
|
||||||
private int MinX { get; set; }
|
|
||||||
private int MaxX { get; set; }
|
|
||||||
public string Contracts { get; set; }
|
|
||||||
public double[] DataX { get; set; }
|
public double[] DataX { get; set; }
|
||||||
public double[] DataY { get; set; }
|
public double[] DataY { get; set; }
|
||||||
|
|
||||||
public Graph(int num, int minX, int maxX) {
|
public Graph(int minX, int maxX) {
|
||||||
Type = "oe";
|
DataX = DataGen.Range(minX, maxX + 1);
|
||||||
Num = num;
|
DataY = DataGen.Zeros(maxX - minX + 1);
|
||||||
Contracts = "";
|
|
||||||
MinX = minX;
|
|
||||||
MaxX = maxX;
|
|
||||||
|
|
||||||
DataX = DataGen.Range(MinX, MaxX + 1);
|
|
||||||
DataY = DataGen.Zeros(MaxX - MinX + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Graph(string type, int num, JsonObject graphData, string contracts, int minX, int maxX) {
|
public Graph(Dictionary<double, decimal> data, int minX, int maxX) {
|
||||||
Type = type;
|
DataX = DataGen.Range(minX, maxX + 1);
|
||||||
Num = num;
|
DataY = DataGen.Zeros(maxX - minX + 1);
|
||||||
Contracts = contracts;
|
ParseGraphData(data, minX, maxX);
|
||||||
MinX = minX;
|
|
||||||
MaxX = maxX;
|
|
||||||
|
|
||||||
DataX = DataGen.Range(MinX, MaxX + 1);
|
|
||||||
DataY = DataGen.Zeros(MaxX - MinX + 1);
|
|
||||||
ParseGraphData(graphData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Graph(string type, int num, int minX, int maxX, string contracts, double[] dataX, double[] dataY) {
|
public Graph(double[] dataX, double[] dataY) {
|
||||||
Type = type;
|
|
||||||
Num = num;
|
|
||||||
MinX = minX;
|
|
||||||
MaxX = maxX;
|
|
||||||
Contracts = contracts;
|
|
||||||
DataX = dataX;
|
DataX = dataX;
|
||||||
DataY = dataY;
|
DataY = dataY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ParseGraphData(JsonObject graphData) {
|
private void ParseGraphData(Dictionary<double, decimal> graphPoints, int minX, int maxX) {
|
||||||
var GraphPoints = graphData.ToDictionary(p => int.Parse(p.Key[..^2]), p => (double)p.Value?.AsValue());
|
if (graphPoints.Keys.Count < 1) {
|
||||||
|
|
||||||
if (GraphPoints.Keys.Count < 1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var minKey = GraphPoints.Keys.Order().First();
|
var minKey = graphPoints.Keys.Order().First();
|
||||||
var maxKey = GraphPoints.Keys.OrderDescending().First();
|
var maxKey = graphPoints.Keys.OrderDescending().First();
|
||||||
|
|
||||||
if (!GraphPoints.ContainsKey(MinX)) {
|
if (!graphPoints.ContainsKey(minX)) {
|
||||||
GraphPoints.Add(MinX, GraphPoints.GetValueOrDefault(minKey));
|
graphPoints.Add(minX, graphPoints.GetValueOrDefault(minKey));
|
||||||
}
|
}
|
||||||
if (!GraphPoints.ContainsKey(MaxX)) {
|
if (!graphPoints.ContainsKey(maxX)) {
|
||||||
GraphPoints.Add(MaxX, GraphPoints.GetValueOrDefault(maxKey));
|
graphPoints.Add(maxX, graphPoints.GetValueOrDefault(maxKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
var keys = GraphPoints.Keys.Order().ToArray();
|
var keys = graphPoints.Keys.Order().ToArray();
|
||||||
|
|
||||||
for (int i = 0; i < keys.Length; i++) {
|
for (int i = 0; i < keys.Length; i++) {
|
||||||
double point1Value = GraphPoints[keys[i]];
|
decimal point1Value = graphPoints[keys[i]];
|
||||||
if (i + 1 < keys.Length) {
|
if (i + 1 < keys.Length) {
|
||||||
double point2Value = GraphPoints[keys[i + 1]];
|
decimal point2Value = graphPoints[keys[i + 1]];
|
||||||
if (point1Value == point2Value) {
|
if (point1Value == point2Value) {
|
||||||
for (int j = keys[i] - MinX; j < keys[i + 1] - MinX; j++) {
|
for (int j = (int)(keys[i] - minX); j < keys[i + 1] - minX; j++) {
|
||||||
DataY[j] = point1Value;
|
DataY[j] = (double)point1Value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int steps = Math.Abs(keys[i + 1] - keys[i]);
|
int steps = (int)Math.Abs(keys[i + 1] - keys[i]);
|
||||||
double step = (point2Value - point1Value) / steps;
|
decimal step = (point2Value - point1Value) / steps;
|
||||||
|
|
||||||
DataY[keys[i] - MinX] = point1Value;
|
DataY[(int)(keys[i] - minX)] = (double)point1Value;
|
||||||
DataY[keys[i + 1] - MinX] = point2Value;
|
DataY[(int)(keys[i + 1] - minX)] = (double)point2Value;
|
||||||
|
|
||||||
for (int j = keys[i] - MinX; j < keys[i + 1] - MinX - 1; j++) {
|
for (int j = (int)(keys[i] - minX); j < keys[i + 1] - minX - 1; j++) {
|
||||||
DataY[j + 1] = Math.Round(DataY[j] + step, 4); // TODO richtig runden
|
DataY[j + 1] = Math.Round(DataY[j] + (double)step, 4); // TODO richtig runden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (int j = keys[i] - MinX; j < DataX.Length; j++) {
|
for (int j = (int)(keys[i] - minX); j < DataX.Length; j++) {
|
||||||
DataY[j] = point1Value;
|
DataY[j] = (double)point1Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonObject ToJson() {
|
public void FlattenGraph(int begin, int end, double value) {
|
||||||
JsonObject graph = new();
|
for (int i = begin; i <= end; i++) {
|
||||||
|
DataY[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LinearIncreaseGraph(int begin, int end, double inc) {
|
||||||
|
for (int i = begin; i < end; i++) {
|
||||||
|
DataY[i + 1] = DataY[i] + inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonObject ToJson(string mode) {
|
||||||
|
var data = new JsonObject();
|
||||||
|
|
||||||
if (DataY[0] != DataY[1]) {
|
if (DataY[0] != DataY[1]) {
|
||||||
graph.Add(new KeyValuePair<string, JsonNode?>(DataX[0] + Type.ToLower(), Math.Round(DataY[0], 4)));
|
data.Add(new KeyValuePair<string, JsonNode?>(DataX[0] + mode, Math.Round(DataY[0], 4)));
|
||||||
}
|
}
|
||||||
for (int i = 1; i < DataX.Length - 1; i++) {
|
for (int i = 1; i < DataX.Length - 1; i++) {
|
||||||
if (Math.Round(DataY[i] - DataY[i - 1], 4) != Math.Round(DataY[i + 1] - DataY[i], 4)) {
|
if (Math.Round(DataY[i] - DataY[i - 1], 10) != Math.Round(DataY[i + 1] - DataY[i], 10)) {
|
||||||
graph.Add(new KeyValuePair<string, JsonNode?>(DataX[i] + Type.ToLower(), Math.Round(DataY[i], 4)));
|
data.Add(new KeyValuePair<string, JsonNode?>(DataX[i] + mode, Math.Round(DataY[i], 4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DataY[^1] != DataY[^2]) {
|
if (DataY[^1] != DataY[^2]) {
|
||||||
graph.Add(new KeyValuePair<string, JsonNode?>(DataX[^1] + Type.ToLower(), Math.Round(DataY[^1], 4)));
|
data.Add(new KeyValuePair<string, JsonNode?>(DataX[^1] + mode, Math.Round(DataY[^1], 4)));
|
||||||
}
|
}
|
||||||
return graph;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Clone() {
|
public object Clone() {
|
||||||
return new Graph(Type, Num, MinX, MaxX, Contracts, (double[])DataX.Clone(), (double[])DataY.Clone());
|
return new Graph((double[])DataX.Clone(), (double[])DataY.Clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
70
Elwig/Helpers/Billing/GraphEntry.cs
Normal file
70
Elwig/Helpers/Billing/GraphEntry.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
|
namespace Elwig.Helpers.Billing {
|
||||||
|
public class GraphEntry {
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
public BillingData.CurveMode Mode { get; set; }
|
||||||
|
public Graph DataGraph { get; set; }
|
||||||
|
public Graph? GebundenGraph { get; set; }
|
||||||
|
public decimal? GebundenFlatPrice { get; set; }
|
||||||
|
public List<string> Contracts { get; set; }
|
||||||
|
private int MinX { get; set; }
|
||||||
|
private int MaxX { get; set; }
|
||||||
|
|
||||||
|
public GraphEntry(int id, BillingData.CurveMode mode, int minX, int maxX) {
|
||||||
|
Id = id;
|
||||||
|
Mode = mode;
|
||||||
|
MinX = minX;
|
||||||
|
MaxX = maxX;
|
||||||
|
DataGraph = new Graph(minX, maxX);
|
||||||
|
Contracts = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public GraphEntry(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, int minX, int maxX) :
|
||||||
|
this(id, mode, minX, maxX) {
|
||||||
|
DataGraph = new Graph(data, minX, maxX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GraphEntry(int id, BillingData.Curve curve, int minX, int maxX) :
|
||||||
|
this(id, curve.Mode, minX, maxX) {
|
||||||
|
DataGraph = new Graph(curve.Normal, minX, maxX);
|
||||||
|
if (curve.Gebunden != null)
|
||||||
|
GebundenGraph = new Graph(curve.Gebunden, minX, maxX);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GraphEntry(int id, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph,
|
||||||
|
decimal? gebundenFlatPrice, List<string> contracts, int minX, int maxX) {
|
||||||
|
Id = id;
|
||||||
|
Mode = mode;
|
||||||
|
MinX = minX;
|
||||||
|
MaxX = maxX;
|
||||||
|
DataGraph = dataGraph;
|
||||||
|
GebundenGraph = gebundenGraph;
|
||||||
|
GebundenFlatPrice = gebundenFlatPrice;
|
||||||
|
Contracts = contracts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonObject ToJson() {
|
||||||
|
var curve = new JsonObject {
|
||||||
|
["id"] = Id,
|
||||||
|
["mode"] = Mode.ToString().ToLower(),
|
||||||
|
};
|
||||||
|
|
||||||
|
curve["data"] = DataGraph.ToJson(Mode.ToString().ToLower());
|
||||||
|
|
||||||
|
if (GebundenFlatPrice != null) {
|
||||||
|
curve["geb"] = GebundenFlatPrice.ToString();
|
||||||
|
} else if (GebundenGraph != null) {
|
||||||
|
curve["geb"] = GebundenGraph.ToJson(Mode.ToString().ToLower());
|
||||||
|
}
|
||||||
|
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GraphEntry Copy(int id) {
|
||||||
|
return new GraphEntry(id, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatPrice, Contracts, MinX, MaxX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
132
Elwig/Helpers/Billing/PaymentBillingData.cs
Normal file
132
Elwig/Helpers/Billing/PaymentBillingData.cs
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
|
namespace Elwig.Helpers.Billing {
|
||||||
|
public class PaymentBillingData : BillingData {
|
||||||
|
|
||||||
|
protected readonly Dictionary<int, Curve> Curves;
|
||||||
|
protected readonly Dictionary<string, Curve> PaymentData;
|
||||||
|
protected readonly Dictionary<string, Curve> QualityData;
|
||||||
|
protected readonly IEnumerable<string> AttributeVariants;
|
||||||
|
|
||||||
|
public PaymentBillingData(JsonObject data, IEnumerable<string> attributeVariants) :
|
||||||
|
base(data) {
|
||||||
|
if (attributeVariants.Any(e => e.Any(c => c < 'A' || c > 'Z')))
|
||||||
|
throw new ArgumentException("Invalid attributeVariants");
|
||||||
|
AttributeVariants = attributeVariants;
|
||||||
|
Curves = GetCurves();
|
||||||
|
PaymentData = GetPaymentData();
|
||||||
|
QualityData = GetQualityData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PaymentBillingData FromJson(string json, IEnumerable<string> attributeVariants) {
|
||||||
|
return new(ParseJson(json), attributeVariants);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, Curve> GetData(JsonObject data) {
|
||||||
|
Dictionary<string, Curve> dict;
|
||||||
|
if (data["default"] is JsonValue def) {
|
||||||
|
var c = LookupCurve(def);
|
||||||
|
dict = AttributeVariants.ToDictionary(e => e, _ => c);
|
||||||
|
} else {
|
||||||
|
dict = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var variants = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length == 2);
|
||||||
|
var attributes = data.Where(p => p.Key.StartsWith('/'));
|
||||||
|
var others = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length > 2);
|
||||||
|
foreach (var (idx, v) in variants) {
|
||||||
|
var curve = LookupCurve(v?.AsValue() ?? throw new InvalidOperationException());
|
||||||
|
foreach (var i in AttributeVariants.Where(e => e.StartsWith(idx[..^1]))) {
|
||||||
|
dict[i] = curve;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var (idx, v) in attributes) {
|
||||||
|
var curve = LookupCurve(v?.AsValue() ?? throw new InvalidOperationException());
|
||||||
|
foreach (var i in AttributeVariants.Where(e => e[2..] == idx[1..])) {
|
||||||
|
dict[i] = curve;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var (idx, v) in others) {
|
||||||
|
var curve = LookupCurve(v?.AsValue() ?? throw new InvalidOperationException());
|
||||||
|
dict[idx.Replace("/", "")] = curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Dictionary<string, Curve> GetPaymentData() {
|
||||||
|
var p = GetPaymentEntry();
|
||||||
|
if (p is JsonValue val) {
|
||||||
|
var c = LookupCurve(val);
|
||||||
|
return AttributeVariants.ToDictionary(e => e, _ => c);
|
||||||
|
}
|
||||||
|
return GetData(p?.AsObject() ?? throw new InvalidOperationException());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Dictionary<string, Curve> GetQualityData() {
|
||||||
|
Dictionary<string, Curve> dict = [];
|
||||||
|
var q = GetQualityEntry();
|
||||||
|
if (q == null) return dict;
|
||||||
|
|
||||||
|
foreach (var (qualid, data) in q) {
|
||||||
|
Dictionary<string, Curve> qualDict;
|
||||||
|
if (data is JsonValue val) {
|
||||||
|
var c = LookupCurve(val);
|
||||||
|
qualDict = AttributeVariants.ToDictionary(e => e, _ => c);
|
||||||
|
} else {
|
||||||
|
qualDict = GetData(data?.AsObject() ?? throw new InvalidOperationException());
|
||||||
|
}
|
||||||
|
foreach (var (idx, d) in qualDict) {
|
||||||
|
dict[$"{qualid}/{idx}"] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 d = (gebunden ? curve.Gebunden : null) ?? curve.Normal;
|
||||||
|
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) {
|
||||||
|
if (val.TryGetValue(out string? curve)) {
|
||||||
|
var curveId = int.Parse(curve.Split(":")[1]);
|
||||||
|
return Curves[curveId];
|
||||||
|
} else if (val.TryGetValue(out decimal value)) {
|
||||||
|
return new(CurveMode.Oe, new() { { 73, value } }, null);
|
||||||
|
}
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Curve GetCurve(string sortid, string? attrid) {
|
||||||
|
return PaymentData[$"{sortid}{attrid ?? ""}"];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Curve? GetQualityCurve(string qualid, string sortid, string? attrid) {
|
||||||
|
return QualityData.TryGetValue($"{qualid}/{sortid}{attrid ?? ""}", out var curve) ? curve : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -24,9 +24,9 @@ namespace Elwig.Helpers {
|
|||||||
public void Read() {
|
public void Read() {
|
||||||
var config = new ConfigurationBuilder().AddIniFile(FileName).Build();
|
var config = new ConfigurationBuilder().AddIniFile(FileName).Build();
|
||||||
|
|
||||||
DatabaseFile = Utils.GetAbsolutePath(config["database:file"] ?? "database.sqlite3", App.DataPath);
|
DatabaseFile = Path.Combine(App.DataPath, config["database:file"] ?? "database.sqlite3");
|
||||||
var log = config["database:log"];
|
var log = config["database:log"];
|
||||||
DatabaseLog = log != null ? Utils.GetAbsolutePath(log, App.DataPath) : null;
|
DatabaseLog = log != null ? Path.Combine(App.DataPath, log) : null;
|
||||||
Branch = config["general:branch"];
|
Branch = config["general:branch"];
|
||||||
Debug = trueValues.Contains(config["general:debug"]?.ToLower());
|
Debug = trueValues.Contains(config["general:debug"]?.ToLower());
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ namespace Elwig.Helpers {
|
|||||||
Scales = ScaleList;
|
Scales = ScaleList;
|
||||||
foreach (var s in scales) {
|
foreach (var s in scales) {
|
||||||
string? scaleLog = config[$"scale.{s}:log"];
|
string? scaleLog = config[$"scale.{s}:log"];
|
||||||
if (scaleLog != null) scaleLog = Utils.GetAbsolutePath(scaleLog, App.DataPath);
|
if (scaleLog != null) scaleLog = Path.Combine(App.DataPath, scaleLog);
|
||||||
ScaleList.Add([
|
ScaleList.Add([
|
||||||
s, config[$"scale.{s}:type"], config[$"scale.{s}:model"], config[$"scale.{s}:connection"],
|
s, config[$"scale.{s}:type"], config[$"scale.{s}:model"], config[$"scale.{s}:connection"],
|
||||||
config[$"scale.{s}:empty"], config[$"scale.{s}:filling"], config[$"scale.{s}:limit"], scaleLog
|
config[$"scale.{s}:empty"], config[$"scale.{s}:filling"], config[$"scale.{s}:limit"], scaleLog
|
||||||
|
@@ -48,6 +48,9 @@ namespace Elwig.Helpers {
|
|||||||
[GeneratedRegex(@"^(.*?) +([0-9].*)$", RegexOptions.Compiled)]
|
[GeneratedRegex(@"^(.*?) +([0-9].*)$", RegexOptions.Compiled)]
|
||||||
private static partial Regex GeneratedAddressRegex();
|
private static partial Regex GeneratedAddressRegex();
|
||||||
|
|
||||||
|
public static readonly string GroupSeparator = "\u202F";
|
||||||
|
public static readonly string UnitSeparator = "\u00A0";
|
||||||
|
|
||||||
public static readonly KeyValuePair<string, string>[] PhoneNrTypes = [
|
public static readonly KeyValuePair<string, string>[] PhoneNrTypes = [
|
||||||
new("landline", "Tel.-Nr. (Festnetz)"),
|
new("landline", "Tel.-Nr. (Festnetz)"),
|
||||||
new("mobile", "Tel.-Nr. (mobil)"),
|
new("mobile", "Tel.-Nr. (mobil)"),
|
||||||
@@ -356,9 +359,5 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
return output.OrderByDescending(l => l.Count());
|
return output.OrderByDescending(l => l.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetAbsolutePath(string path, string basePath) {
|
|
||||||
return (path.Length > 1 && (path[1] == ':' || path[0] == '/' || path[0] == '\\')) ? Path.Combine(basePath, path) : path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,10 @@ namespace Elwig.Models.Dtos {
|
|||||||
MgNr = m.MgNr;
|
MgNr = m.MgNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DeliveryConfirmationData CreateEmpty(int year, Member m) {
|
||||||
|
return new([], year, m);
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<IDictionary<int, DeliveryConfirmationData>> ForSeason(DbSet<DeliveryPart> table, int year) {
|
public static async Task<IDictionary<int, DeliveryConfirmationData>> ForSeason(DbSet<DeliveryPart> table, int year) {
|
||||||
return (await FromDbSet(table, year))
|
return (await FromDbSet(table, year))
|
||||||
.GroupBy(
|
.GroupBy(
|
||||||
|
@@ -9,7 +9,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||||||
<PublishDir>bin\Publish</PublishDir>
|
<PublishDir>bin\Publish</PublishDir>
|
||||||
<PublishProtocol>FileSystem</PublishProtocol>
|
<PublishProtocol>FileSystem</PublishProtocol>
|
||||||
<_TargetId>Folder</_TargetId>
|
<_TargetId>Folder</_TargetId>
|
||||||
<TargetFramework>net7.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
<SelfContained>true</SelfContained>
|
<SelfContained>true</SelfContained>
|
||||||
<PublishSingleFile>false</PublishSingleFile>
|
<PublishSingleFile>false</PublishSingleFile>
|
||||||
|
@@ -125,6 +125,7 @@ namespace Elwig.Windows {
|
|||||||
if (old != null) _branches[old] = id;
|
if (old != null) _branches[old] = id;
|
||||||
branch.ZwstId = id;
|
branch.ZwstId = id;
|
||||||
branch.Name = BranchNameInput.Text;
|
branch.Name = BranchNameInput.Text;
|
||||||
|
branch.CountryNum = 40;
|
||||||
branch.PostalDestId = (BranchOrtInput.SelectedItem as AT_PlzDest)?.Id;
|
branch.PostalDestId = (BranchOrtInput.SelectedItem as AT_PlzDest)?.Id;
|
||||||
branch.Address = BranchAddressInput.Text;
|
branch.Address = BranchAddressInput.Text;
|
||||||
branch.PhoneNr = BranchPhoneNrInput.Text;
|
branch.PhoneNr = BranchPhoneNrInput.Text;
|
||||||
|
@@ -52,13 +52,13 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||||
foreach (var (modid, _) in _mods.Where(m => m.Value == null)) {
|
foreach (var (modid, _) in _mods.Where(m => m.Value == null)) {
|
||||||
Context.Remove(Context.Modifiers.Find(new object?[] { year, modid }));
|
Context.Remove(Context.Modifiers.Find(year, modid));
|
||||||
}
|
}
|
||||||
foreach (var (mod, old) in _modIds) {
|
foreach (var (mod, old) in _modIds) {
|
||||||
mod.ModId = old;
|
mod.ModId = old;
|
||||||
}
|
}
|
||||||
foreach (var (old, modid) in _mods.Where(m => m.Value != null)) {
|
foreach (var (old, modid) in _mods.Where(m => m.Value != null)) {
|
||||||
Context.Update(Context.Modifiers.Find(new object?[] { year, old }));
|
Context.Update(Context.Modifiers.Find(year, old));
|
||||||
}
|
}
|
||||||
await Context.SaveChangesAsync();
|
await Context.SaveChangesAsync();
|
||||||
|
|
||||||
@@ -102,8 +102,9 @@ namespace Elwig.Windows {
|
|||||||
if (_modList == null || SeasonList.SelectedItem is not Season s) return;
|
if (_modList == null || SeasonList.SelectedItem is not Season s) return;
|
||||||
_modChanged = true;
|
_modChanged = true;
|
||||||
var idx = (SeasonModifierList.SelectedIndex != -1) ? SeasonModifierList.SelectedIndex + 1 : _modList.Count;
|
var idx = (SeasonModifierList.SelectedIndex != -1) ? SeasonModifierList.SelectedIndex + 1 : _modList.Count;
|
||||||
var item = Context.CreateProxy<Modifier>();
|
var item = new Modifier {
|
||||||
item.Year = s.Year;
|
Year = s.Year
|
||||||
|
};
|
||||||
_modList.Insert(idx, item);
|
_modList.Insert(idx, item);
|
||||||
SeasonModifierList.SelectedIndex = idx;
|
SeasonModifierList.SelectedIndex = idx;
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
|
@@ -264,6 +264,8 @@ namespace Elwig.Windows {
|
|||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
FillInputs(App.Client);
|
FillInputs(App.Client);
|
||||||
LockInputs();
|
LockInputs();
|
||||||
|
|
||||||
|
await HintContextChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillInputs(ClientParameters p) {
|
private void FillInputs(ClientParameters p) {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<local:AdministrationWindow
|
<local:ContextWindow
|
||||||
x:Class="Elwig.Windows.ChartWindow"
|
x:Class="Elwig.Windows.ChartWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||||
xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF"
|
xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Auszahlung - Elwig" Height="700" Width="1500"
|
Title="Auszahlung - Elwig" Height="700" Width="1500" MinWidth="1000" MinHeight="500"
|
||||||
Loaded="Window_Loaded">
|
Loaded="Window_Loaded">
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
@@ -43,94 +43,77 @@
|
|||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="19"/>
|
<RowDefinition Height="40"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="330"/>
|
<ColumnDefinition Width="230"/>
|
||||||
<ColumnDefinition Width="1*"/>
|
<ColumnDefinition Width="1*"/>
|
||||||
<ColumnDefinition Width="200"/>
|
<ColumnDefinition Width="200"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Grid Grid.Row="1" Margin="5,0,0,0">
|
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
<RowDefinition Height="42"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="150"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="500"/>
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<DataGrid x:Name="GraphList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single"
|
|
||||||
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False"
|
|
||||||
SelectionChanged="GraphList_SelectionChanged"
|
|
||||||
Margin="5,15,5,0" Grid.Row="0" FontSize="14" Grid.ColumnSpan="3">
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTextColumn Header="Nr." Binding="{Binding Num}" Width="40">
|
|
||||||
<DataGridTextColumn.ElementStyle>
|
|
||||||
<Style>
|
|
||||||
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.ElementStyle>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
<DataGridTextColumn Header="Typ" Binding="{Binding Type}" Width="40"/>
|
|
||||||
<DataGridTextColumn Header="Angewandte Verträge" Binding="{Binding Contracts}" Width="4*"/>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
|
|
||||||
<Button x:Name="NewButton" Content="Neu"
|
<Label Content="Graph:" Margin="10,0,0,0" FontSize="14" Grid.Column="0" VerticalAlignment="Center"/>
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2"
|
<TextBlock x:Name="GraphNum" Margin="0,0,40,0" FontSize="14" Width="50" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||||
Click="NewButton_Click"/>
|
|
||||||
<Button x:Name="EditButton" Content="Bearbeiten" IsEnabled="False"
|
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2"
|
|
||||||
Click="EditButton_Click"/>
|
|
||||||
<Button x:Name="DeleteButton" Content="Löschen" IsEnabled="False"
|
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2"
|
|
||||||
Click="DeleteButton_Click"/>
|
|
||||||
|
|
||||||
<Button x:Name="SaveButton" Content="Speichern" IsEnabled="False" Visibility="Hidden"
|
<Label Content="Für:" Margin="10,0,0,0" FontSize="14" Grid.Column="1" VerticalAlignment="Center"/>
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2"
|
<xctk:CheckComboBox x:Name="AppliedInput" Margin="0,10,10,10" Grid.Column="1"
|
||||||
Click="SaveButton_Click"/>
|
Delimiter=", " AllItemsSelectedContent="Alle"
|
||||||
<Button x:Name="ResetButton" Content="Zurücksetzen" IsEnabled="False" Visibility="Hidden"
|
Width="400" HorizontalAlignment="Right">
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2"
|
<!--<xctk:CheckComboBox.ItemTemplate>
|
||||||
Click="ResetButton_Click"/>
|
<DataTemplate>
|
||||||
<Button x:Name="CancelButton" Content="Abbrechen" IsEnabled="False" Visibility="Hidden" IsCancel="True"
|
<StackPanel Orientation="Horizontal">
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2"
|
<TextBlock Text="{}" Width="40"/>
|
||||||
Click="CancelButton_Click"/>
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</xctk:CheckComboBox.ItemTemplate>-->
|
||||||
|
</xctk:CheckComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<ListBox x:Name="GraphList" Margin="10,10,35,50" Grid.Column="0" Grid.Row="1" SelectionChanged="GraphList_SelectionChanged">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding Id}" Width="40"/>
|
||||||
|
<TextBlock Text="{Binding Contracts}" Width="100"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
|
<Button x:Name="SaveButton" Content="Speichern" IsEnabled="True"
|
||||||
|
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="10,5,35,15" Grid.Column="0" Grid.Row="2"
|
||||||
|
Click="SaveButton_Click"/>
|
||||||
|
|
||||||
|
<Button x:Name="AddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" ToolTip="Neue Auszahlungsvariante hinzufügen"
|
||||||
|
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,60" Grid.Column="0" Grid.Row="1"
|
||||||
|
Click="AddButton_Click"/>
|
||||||
|
<Button x:Name="CopyButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="12" Padding="0,0,0,0" IsEnabled="False" ToolTip="Ausgewählte Auszahlungsvariante duplizieren"
|
||||||
|
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="0,0,5,0" Grid.Column="0" Grid.Row="1"
|
||||||
|
Click="CopyButton_Click"/>
|
||||||
|
<Button x:Name="DeleteButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" IsEnabled="False" ToolTip="Ausgewählte Auszahlungsvariante löschen"
|
||||||
|
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,60,5,0" Grid.Column="0" Grid.Row="1"
|
||||||
|
Click="DeleteButton_Click"/>
|
||||||
|
|
||||||
<Grid Grid.Row="1" Grid.Column="1">
|
<Grid Grid.Row="1" Grid.Column="1">
|
||||||
<ScottPlot:WpfPlot x:Name="OechslePricePlot" MouseMove="OechslePricePlot_MouseMove" MouseDown="OechslePricePlot_MouseDown" IsEnabled="False"/>
|
<ScottPlot:WpfPlot x:Name="OechslePricePlot" MouseMove="OechslePricePlot_MouseMove" MouseDown="OechslePricePlot_MouseDown" IsEnabled="False"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid Grid.Row="1" Grid.Column="2" Margin="0,0,5,0">
|
<Grid Grid.Row="1" Grid.Column="2" Margin="0,0,5,36">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="120"/>
|
<RowDefinition Height="120"/>
|
||||||
<RowDefinition Height="120"/>
|
<RowDefinition Height="90"/>
|
||||||
<RowDefinition Height="210"/>
|
<RowDefinition Height="210"/>
|
||||||
|
<RowDefinition Height="1*"/>
|
||||||
<RowDefinition Height="110"/>
|
<RowDefinition Height="110"/>
|
||||||
<RowDefinition Height="42"/>
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<GroupBox Header="Graph" Grid.Row="0" Margin="0,5,5,5">
|
<GroupBox Header="Datenpunkt" Grid.Row="0" Margin="0,5,5,5">
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="85"/>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<Label Content="Nummer:" Margin="10,10,0,0" Grid.Column="0"/>
|
|
||||||
<TextBox x:Name="GraphNumberInput" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0" Text="" Width="90" TextChanged="GraphNumberInput_TextChanged" LostFocus="GraphNumberInput_LostFocus"/>
|
|
||||||
|
|
||||||
<Label Content="Typ:" Margin="10,45,0,0" Grid.Column="0"/>
|
|
||||||
<RadioButton x:Name="OechsleGraphType_Input" GroupName="GraphType" Grid.Column="1" Margin="0,45,0,0">Oechsle</RadioButton>
|
|
||||||
<RadioButton x:Name="KmwGraphType_Input" GroupName="GraphType" Grid.Column="1" Margin="0,60,0,0">KMW</RadioButton>
|
|
||||||
</Grid>
|
|
||||||
</GroupBox>
|
|
||||||
|
|
||||||
<GroupBox Header="Datenpunkt" Grid.Row="1" Margin="0,5,5,5">
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="85"/>
|
<ColumnDefinition Width="85"/>
|
||||||
@@ -146,6 +129,23 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
|
<GroupBox Header="Gebunden" Grid.Row="1" Margin="0,5,5,5">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="85"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Margin="10,10,0,0">
|
||||||
|
<RadioButton GroupName="GebundenType">Fix</RadioButton>
|
||||||
|
<RadioButton GroupName="GebundenType">Graph</RadioButton>
|
||||||
|
<RadioButton GroupName="GebundenType" IsChecked="True">Nein</RadioButton>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<TextBox x:Name="GebundenBonus" IsReadOnly="True" Grid.Column="1" HorizontalAlignment="Left" Margin="0,12,0,0" Text="" Width="90" TextChanged="GebundenBonus_TextChanged"/>
|
||||||
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Aktionen" Grid.Row="2" Margin="0,5,5,5">
|
<GroupBox Header="Aktionen" Grid.Row="2" Margin="0,5,5,5">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Optionen" Grid.Row="3" Margin="0,5,5,5">
|
<GroupBox Header="Optionen" Grid.Row="4" Margin="0,5,5,5">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -186,4 +186,4 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</local:AdministrationWindow>
|
</local:ContextWindow>
|
||||||
|
@@ -17,10 +17,11 @@ using ScottPlot;
|
|||||||
using ScottPlot.Plottable;
|
using ScottPlot.Plottable;
|
||||||
|
|
||||||
namespace Elwig.Windows {
|
namespace Elwig.Windows {
|
||||||
public partial class ChartWindow : AdministrationWindow {
|
public partial class ChartWindow : ContextWindow {
|
||||||
|
|
||||||
public readonly int Year;
|
public readonly int Year;
|
||||||
public readonly int AvNr;
|
public readonly int AvNr;
|
||||||
|
private readonly PaymentVar PaymentVar;
|
||||||
|
|
||||||
private ScatterPlot OechslePricePlotScatter;
|
private ScatterPlot OechslePricePlotScatter;
|
||||||
private MarkerPlot HighlightedPoint;
|
private MarkerPlot HighlightedPoint;
|
||||||
@@ -38,21 +39,18 @@ namespace Elwig.Windows {
|
|||||||
private const int MinOechsle = 50;
|
private const int MinOechsle = 50;
|
||||||
private const int MaxOechsle = 140;
|
private const int MaxOechsle = 140;
|
||||||
|
|
||||||
private Graph? Graph;
|
private List<GraphEntry> GraphEntries = [];
|
||||||
|
private GraphEntry? SelectedGraphEntry;
|
||||||
|
|
||||||
public ChartWindow(int year, int avnr) {
|
public ChartWindow(int year, int avnr) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Year = year;
|
Year = year;
|
||||||
AvNr = avnr;
|
AvNr = avnr;
|
||||||
var v = Context.PaymentVariants.Find(year, avnr);
|
PaymentVar = Context.PaymentVariants.Find(year, avnr) ?? throw new ArgumentException("PaymentVar not found");
|
||||||
Title = $"{v?.Name} - Lese {year} - Elwig";
|
Title = $"{PaymentVar?.Name} - Lese {year} - Elwig";
|
||||||
ExemptInputs = [
|
|
||||||
GraphList, OechsleInput, PriceInput, FreeZoomInput, GradationLinesInput, TooltipInput
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
LockInputs();
|
|
||||||
OechslePricePlot.IsEnabled = false;
|
OechslePricePlot.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,170 +59,65 @@ namespace Elwig.Windows {
|
|||||||
await RefreshGraphListQuery();
|
await RefreshGraphListQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonObject? ParseData(PaymentVar variant) {
|
private async Task RefreshGraphListQuery() {
|
||||||
try {
|
var attrVariants = Context.DeliveryParts
|
||||||
return BillingData.ParseJson(variant.Data);
|
.Where(d => d.Year == Year)
|
||||||
} catch (ArgumentException) {
|
.Select(d => $"{d.SortId}{d.AttrId}")
|
||||||
return null;
|
.Distinct()
|
||||||
}
|
.ToList()
|
||||||
}
|
.Union(Context.WineVarieties.Select(v => v.SortId))
|
||||||
|
.Order()
|
||||||
|
.ToList();
|
||||||
|
var data = EditBillingData.FromJson(PaymentVar.Data, attrVariants);
|
||||||
|
GraphEntries.AddRange(data.GetPaymentGraphEntries());
|
||||||
|
GraphEntries.AddRange(data.GetQualityGraphEntries());
|
||||||
|
|
||||||
private async Task RefreshGraphListQuery(bool updateSort = false) {
|
ControlUtils.RenewItemsSource(AppliedInput, attrVariants, g => g);
|
||||||
var paymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr);
|
ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.Id, null, ControlUtils.RenewSourceDefault.IfOnly);
|
||||||
if (paymentVar == null) return;
|
|
||||||
var data = ParseData(paymentVar);
|
|
||||||
if (data == null) return;
|
|
||||||
|
|
||||||
var auszahlungsSorten = data["AuszahlungSorten"]?.AsObject();
|
|
||||||
if (auszahlungsSorten == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var Graphs = auszahlungsSorten["Kurven"]?.AsArray();
|
|
||||||
|
|
||||||
if (Graphs == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Graph> GraphsList = [];
|
|
||||||
|
|
||||||
int i = 1;
|
|
||||||
foreach (var graph in Graphs) {
|
|
||||||
GraphsList.Add(new Graph("Oe", i, graph?.AsObject(), ParseContracts(auszahlungsSorten, i - 1), 50, 140));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(GraphList, GraphsList, g => (g as Graph)?.Num);
|
|
||||||
if (GraphsList.Count == 1) {
|
|
||||||
GraphList.SelectedIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ParseContracts(JsonObject auszahlungsSorten, int num) {
|
private string ParseContracts(JsonObject auszahlungsSorten, int num) {
|
||||||
List<string> contracts = [];
|
return "";
|
||||||
|
|
||||||
foreach (var sorte in auszahlungsSorten) {
|
|
||||||
if (sorte.Key == "Kurven") continue;
|
|
||||||
foreach (var attribut in sorte.Value.AsObject()) {
|
|
||||||
foreach (var bindung in attribut.Value.AsObject()) {
|
|
||||||
if ((int)bindung.Value.AsValue() == num) {
|
|
||||||
contracts.Add($"{sorte.Key}/{attribut.Key}/{bindung.Key}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Join("\n", contracts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> RemoveGraph(int num) {
|
|
||||||
var paymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr);
|
|
||||||
if (paymentVar == null) return false;
|
|
||||||
var data = ParseData(paymentVar);
|
|
||||||
if (data == null) return false;
|
|
||||||
|
|
||||||
var auszahlungsSorten = data["AuszahlungSorten"]?.AsObject();
|
|
||||||
if (auszahlungsSorten == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var Graphs = auszahlungsSorten["Kurven"]?.AsObject();
|
|
||||||
if (Graphs == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = 1;
|
|
||||||
foreach (var graph in Graphs) {
|
|
||||||
if (i == num) {
|
|
||||||
Graphs.Remove(graph.Key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var sorte in auszahlungsSorten) {
|
|
||||||
if (sorte.Key == "Kurven") continue;
|
|
||||||
foreach (var attribut in sorte.Value.AsObject()) {
|
|
||||||
var bindungen = attribut.Value.AsObject();
|
|
||||||
foreach (var bindung in bindungen) {
|
|
||||||
int v = (int)bindung.Value;
|
|
||||||
if (v == num - 1) {
|
|
||||||
bindungen.Remove(bindung.Key);
|
|
||||||
} else if (v > num - 1) {
|
|
||||||
bindungen[bindung.Key] = v - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityEntry<PaymentVar>? tr = null;
|
|
||||||
try {
|
|
||||||
paymentVar.Data = data.ToString();
|
|
||||||
tr = Context.Update(paymentVar);
|
|
||||||
|
|
||||||
await Context.SaveChangesAsync();
|
|
||||||
} catch (Exception exc) {
|
|
||||||
if (tr != null) await tr.ReloadAsync();
|
|
||||||
var str = "Der Eintrag konnte nicht in der Datenbank gelöscht werden!\n\n" + exc.Message;
|
|
||||||
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
|
|
||||||
MessageBox.Show(str, "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RefreshInputs(bool validate = false) {
|
private void RefreshInputs(bool validate = false) {
|
||||||
ResetPlot();
|
ResetPlot();
|
||||||
ClearInputStates();
|
if (!PaymentVar.TestVariant) {
|
||||||
if (GraphList.SelectedItem is Graph g) {
|
AddButton.IsEnabled = false;
|
||||||
EditButton.IsEnabled = true;
|
CopyButton.IsEnabled = false;
|
||||||
DeleteButton.IsEnabled = true;
|
|
||||||
EnableOptionButtons();
|
|
||||||
FillInputs(g);
|
|
||||||
} else {
|
|
||||||
EditButton.IsEnabled = false;
|
|
||||||
DeleteButton.IsEnabled = false;
|
DeleteButton.IsEnabled = false;
|
||||||
|
OechsleInput.IsReadOnly = true;
|
||||||
|
PriceInput.IsReadOnly = true;
|
||||||
|
} else if (SelectedGraphEntry != null) {
|
||||||
|
CopyButton.IsEnabled = true;
|
||||||
|
DeleteButton.IsEnabled = true;
|
||||||
|
OechsleInput.IsReadOnly = false;
|
||||||
|
EnableOptionButtons();
|
||||||
|
FillInputs();
|
||||||
|
} else {
|
||||||
|
CopyButton.IsEnabled = false;
|
||||||
|
DeleteButton.IsEnabled = false;
|
||||||
|
OechsleInput.IsReadOnly = true;
|
||||||
DisableOptionButtons();
|
DisableOptionButtons();
|
||||||
ClearOriginalValues();
|
|
||||||
ClearInputs(validate);
|
|
||||||
ClearInputStates();
|
|
||||||
}
|
}
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillInputs(Graph g) {
|
private void FillInputs() {
|
||||||
ClearOriginalValues();
|
GraphNum.Text = SelectedGraphEntry.Id.ToString();
|
||||||
|
|
||||||
Graph = (Graph)g.Clone();
|
|
||||||
|
|
||||||
GraphNumberInput.Text = Graph.Num.ToString();
|
|
||||||
if (Graph.Type == "oe") {
|
|
||||||
OechsleGraphType_Input.IsChecked = true;
|
|
||||||
} else if (Graph.Type == "kmw") {
|
|
||||||
KmwGraphType_Input.IsChecked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitPlot();
|
InitPlot();
|
||||||
OechslePricePlot.IsEnabled = true;
|
OechslePricePlot.IsEnabled = true;
|
||||||
|
|
||||||
FinishInputFilling();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitInputs() {
|
|
||||||
GraphNumberInput.Text = (GraphList.Items.Count + 1).ToString();
|
|
||||||
OechsleGraphType_Input.IsChecked = true;
|
|
||||||
FinishInputFilling();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnRenewContext() {
|
protected override async Task OnRenewContext() {
|
||||||
await base.OnRenewContext();
|
|
||||||
await RefreshGraphList();
|
await RefreshGraphList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitPlot() {
|
private void InitPlot() {
|
||||||
OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(Graph.DataX, Graph.DataY);
|
OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY);
|
||||||
|
|
||||||
OechslePricePlot.Configuration.DoubleClickBenchmark = false;
|
OechslePricePlot.Configuration.DoubleClickBenchmark = false;
|
||||||
OechslePricePlotScatter.LineColor = Color.Blue;
|
OechslePricePlotScatter.LineColor = Color.Blue;
|
||||||
@@ -265,7 +158,6 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void ResetPlot() {
|
private void ResetPlot() {
|
||||||
Graph = null;
|
|
||||||
PrimaryMarkedPointIndex = -1;
|
PrimaryMarkedPointIndex = -1;
|
||||||
OechslePricePlot.Plot.Remove(OechslePricePlotScatter);
|
OechslePricePlot.Plot.Remove(OechslePricePlotScatter);
|
||||||
OechslePricePlot.Plot.Clear();
|
OechslePricePlot.Plot.Clear();
|
||||||
@@ -280,16 +172,12 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void FlattenGraph(int begin, int end, double value) {
|
private void FlattenGraph(int begin, int end, double value) {
|
||||||
for (int i = begin; i <= end; i++) {
|
SelectedGraphEntry.DataGraph.FlattenGraph(begin, end, value);
|
||||||
Graph.DataY[i] = value;
|
|
||||||
}
|
|
||||||
OechslePricePlot.Render();
|
OechslePricePlot.Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LinearIncreaseGraph(int begin, int end, double inc) {
|
private void LinearIncreaseGraph(int begin, int end, double inc) {
|
||||||
for (int i = begin; i < end; i++) {
|
SelectedGraphEntry.DataGraph.LinearIncreaseGraph(begin, end, inc);
|
||||||
Graph.DataY[i + 1] = Graph.DataY[i] + inc;
|
|
||||||
}
|
|
||||||
OechslePricePlot.Render();
|
OechslePricePlot.Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,8 +268,6 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void OechsleInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void OechsleInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
IntegerInput_TextChanged(sender, evt);
|
|
||||||
|
|
||||||
bool success = int.TryParse(OechsleInput.Text, out int oechsle);
|
bool success = int.TryParse(OechsleInput.Text, out int oechsle);
|
||||||
|
|
||||||
SecondaryMarkedPointIndex = -1;
|
SecondaryMarkedPointIndex = -1;
|
||||||
@@ -390,12 +276,13 @@ namespace Elwig.Windows {
|
|||||||
if (success) {
|
if (success) {
|
||||||
if (oechsle >= MinOechsle && oechsle <= MaxOechsle) {
|
if (oechsle >= MinOechsle && oechsle <= MaxOechsle) {
|
||||||
PrimaryMarkedPointIndex = oechsle - MinOechsle;
|
PrimaryMarkedPointIndex = oechsle - MinOechsle;
|
||||||
ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]);
|
ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
|
||||||
|
|
||||||
PriceInput.Text = Graph.DataY[PrimaryMarkedPointIndex].ToString();
|
PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex].ToString();
|
||||||
|
|
||||||
if (IsEditing || IsCreating) EnableActionButtons();
|
EnableActionButtons();
|
||||||
OechslePricePlot.Render();
|
OechslePricePlot.Render();
|
||||||
|
PriceInput.IsReadOnly = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,6 +292,7 @@ namespace Elwig.Windows {
|
|||||||
DisableActionButtons();
|
DisableActionButtons();
|
||||||
PriceInput.Text = "";
|
PriceInput.Text = "";
|
||||||
OechslePricePlot.Render();
|
OechslePricePlot.Render();
|
||||||
|
PriceInput.IsReadOnly = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) {
|
private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||||
@@ -412,10 +300,8 @@ namespace Elwig.Windows {
|
|||||||
bool success = Double.TryParse(PriceInput.Text, out double price);
|
bool success = Double.TryParse(PriceInput.Text, out double price);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
Graph.DataY[PrimaryMarkedPointIndex] = price;
|
SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex] = price;
|
||||||
PrimaryMarkedPoint.Y = price;
|
PrimaryMarkedPoint.Y = price;
|
||||||
SaveButton.IsEnabled = true;
|
|
||||||
ResetButton.IsEnabled = true;
|
|
||||||
OechslePricePlot.Refresh();
|
OechslePricePlot.Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,18 +311,14 @@ namespace Elwig.Windows {
|
|||||||
if (PrimaryMarkedPointIndex == -1) {
|
if (PrimaryMarkedPointIndex == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FlattenGraph(0, PrimaryMarkedPointIndex, Graph.DataY[PrimaryMarkedPointIndex]);
|
FlattenGraph(0, PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
|
||||||
SaveButton.IsEnabled = true;
|
|
||||||
ResetButton.IsEnabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
|
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (PrimaryMarkedPointIndex == -1) {
|
if (PrimaryMarkedPointIndex == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FlattenGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, Graph.DataY[PrimaryMarkedPointIndex]);
|
FlattenGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
|
||||||
SaveButton.IsEnabled = true;
|
|
||||||
ResetButton.IsEnabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
|
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
@@ -446,13 +328,11 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex);
|
var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex);
|
||||||
|
|
||||||
double step = (Graph.DataY[highIndex] - Graph.DataY[lowIndex]) / steps;
|
double step = (SelectedGraphEntry.DataGraph.DataY[highIndex] - SelectedGraphEntry.DataGraph.DataY[lowIndex]) / steps;
|
||||||
|
|
||||||
for (int i = lowIndex; i < highIndex - 1; i++) {
|
for (int i = lowIndex; i < highIndex - 1; i++) {
|
||||||
Graph.DataY[i + 1] = Math.Round(Graph.DataY[i] + step, 4); // TODO richtig runden
|
SelectedGraphEntry.DataGraph.DataY[i + 1] = Math.Round(SelectedGraphEntry.DataGraph.DataY[i] + step, 4); // TODO richtig runden
|
||||||
}
|
}
|
||||||
SaveButton.IsEnabled = true;
|
|
||||||
ResetButton.IsEnabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
|
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
|
||||||
@@ -463,23 +343,21 @@ namespace Elwig.Windows {
|
|||||||
if (priceIncrease == null) {
|
if (priceIncrease == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LinearIncreaseGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, priceIncrease.Value);
|
LinearIncreaseGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, priceIncrease.Value);
|
||||||
SaveButton.IsEnabled = true;
|
|
||||||
ResetButton.IsEnabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
|
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
|
||||||
if (!IsCreating && GraphList.SelectedItem == null) {
|
if (GraphList.SelectedItem == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HoverActive) {
|
if (HoverActive) {
|
||||||
if ((IsEditing || IsCreating) && Keyboard.IsKeyDown(Key.LeftCtrl)) {
|
if (PaymentVar.TestVariant && Keyboard.IsKeyDown(Key.LeftCtrl)) {
|
||||||
if (PrimaryMarkedPointIndex == -1) {
|
if (PrimaryMarkedPointIndex == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SecondaryMarkedPointIndex = HighlightedIndex;
|
SecondaryMarkedPointIndex = HighlightedIndex;
|
||||||
ChangeMarker(SecondaryMarkedPoint, true, Graph.DataX[SecondaryMarkedPointIndex], Graph.DataY[SecondaryMarkedPointIndex]);
|
ChangeMarker(SecondaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[SecondaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[SecondaryMarkedPointIndex]);
|
||||||
|
|
||||||
InterpolateButton.IsEnabled = true;
|
InterpolateButton.IsEnabled = true;
|
||||||
|
|
||||||
@@ -487,12 +365,12 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrimaryMarkedPointIndex = HighlightedIndex;
|
PrimaryMarkedPointIndex = HighlightedIndex;
|
||||||
ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]);
|
ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
|
||||||
|
|
||||||
OechsleInput.Text = Graph.DataX[HighlightedIndex].ToString();
|
OechsleInput.Text = SelectedGraphEntry.DataGraph.DataX[HighlightedIndex].ToString();
|
||||||
PriceInput.Text = Graph.DataY[HighlightedIndex].ToString();
|
PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[HighlightedIndex].ToString();
|
||||||
|
|
||||||
if (IsEditing || IsCreating) {
|
if (PaymentVar.TestVariant) {
|
||||||
EnableActionButtons();
|
EnableActionButtons();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -509,7 +387,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) {
|
private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) {
|
||||||
if (!IsCreating && GraphList.SelectedItem == null) {
|
if (GraphList.SelectedItem == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,188 +424,45 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override protected void UpdateButtons() {
|
private int getMaxGraphId() {
|
||||||
if (!IsEditing && !IsCreating) return;
|
return GraphEntries.Count == 0 ? 0 : GraphEntries.Select(g => g.Id).Max();
|
||||||
bool ch = HasChanged, v = IsValid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisableNewEditDeleteButtons() {
|
private void AddButton_Click(object sender, RoutedEventArgs e) {
|
||||||
NewButton.IsEnabled = false;
|
GraphEntry newGraphEntry = new(getMaxGraphId() + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle);
|
||||||
EditButton.IsEnabled = false;
|
GraphEntries.Add(newGraphEntry);
|
||||||
DeleteButton.IsEnabled = false;
|
GraphList.Items.Refresh();
|
||||||
|
GraphList.SelectedItem = newGraphEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnableNewEditDeleteButtons() {
|
private void CopyButton_Click(object sender, RoutedEventArgs e) {
|
||||||
NewButton.IsEnabled = true;
|
if (SelectedGraphEntry == null) return;
|
||||||
EditButton.IsEnabled = GraphList.SelectedItem != null;
|
|
||||||
DeleteButton.IsEnabled = GraphList.SelectedItem != null;
|
GraphEntry newGraphEntry = SelectedGraphEntry.Copy(getMaxGraphId() + 1);
|
||||||
|
GraphEntries.Add(newGraphEntry);
|
||||||
|
GraphList.Items.Refresh();
|
||||||
|
GraphList.SelectedItem = newGraphEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowSaveResetCancelButtons() {
|
private void DeleteButton_Click(object sender, RoutedEventArgs e) {
|
||||||
SaveButton.IsEnabled = false;
|
if (SelectedGraphEntry == null) return;
|
||||||
ResetButton.IsEnabled = false;
|
|
||||||
CancelButton.IsEnabled = true;
|
|
||||||
SaveButton.Visibility = Visibility.Visible;
|
|
||||||
ResetButton.Visibility = Visibility.Visible;
|
|
||||||
CancelButton.Visibility = Visibility.Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HideSaveResetCancelButtons() {
|
|
||||||
SaveButton.IsEnabled = false;
|
|
||||||
ResetButton.IsEnabled = false;
|
|
||||||
CancelButton.IsEnabled = false;
|
|
||||||
SaveButton.Visibility = Visibility.Hidden;
|
|
||||||
ResetButton.Visibility = Visibility.Hidden;
|
|
||||||
CancelButton.Visibility = Visibility.Hidden;
|
|
||||||
}
|
|
||||||
private void ShowNewEditDeleteButtons() {
|
|
||||||
EnableNewEditDeleteButtons();
|
|
||||||
NewButton.Visibility = Visibility.Visible;
|
|
||||||
EditButton.Visibility = Visibility.Visible;
|
|
||||||
DeleteButton.Visibility = Visibility.Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HideNewEditDeleteButtons() {
|
|
||||||
DisableNewEditDeleteButtons();
|
|
||||||
NewButton.Visibility = Visibility.Hidden;
|
|
||||||
EditButton.Visibility = Visibility.Hidden;
|
|
||||||
DeleteButton.Visibility = Visibility.Hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NewButton_Click(object sender, RoutedEventArgs e) {
|
|
||||||
IsCreating = true;
|
|
||||||
GraphList.IsEnabled = false;
|
|
||||||
GraphList.SelectedItem = null;
|
|
||||||
HideNewEditDeleteButtons();
|
|
||||||
ShowSaveResetCancelButtons();
|
|
||||||
UnlockInputs();
|
|
||||||
PriceInput.IsReadOnly = false;
|
|
||||||
OechsleInput.IsReadOnly = false;
|
|
||||||
InitInputs();
|
|
||||||
FillInputs(new Graph(GraphList.Items.Count + 1, MinOechsle, MaxOechsle));
|
|
||||||
EnableOptionButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EditButton_Click(object sender, RoutedEventArgs e) {
|
|
||||||
if (GraphList.SelectedItem == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IsEditing = true;
|
|
||||||
GraphList.IsEnabled = false;
|
|
||||||
|
|
||||||
HideNewEditDeleteButtons();
|
|
||||||
ShowSaveResetCancelButtons();
|
|
||||||
UnlockInputs();
|
|
||||||
PriceInput.IsReadOnly = false;
|
|
||||||
OechsleInput.IsReadOnly = false;
|
|
||||||
if (PrimaryMarkedPointIndex != -1) EnableActionButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void DeleteButton_Click(object sender, RoutedEventArgs e) {
|
|
||||||
Graph g = (Graph)GraphList.SelectedItem;
|
|
||||||
if (g == null) return;
|
|
||||||
|
|
||||||
var r = MessageBox.Show(
|
var r = MessageBox.Show(
|
||||||
$"Soll der Graph {g.Num} (verwendet in folgenden Verträgen: {g.Contracts}) wirklich unwiderruflich gelöscht werden?",
|
$"Soll der Graph {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.Contracts}) wirklich gelöscht werden?",
|
||||||
"Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
"Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||||
|
|
||||||
if (r == MessageBoxResult.Yes) {
|
if (r == MessageBoxResult.Yes) {
|
||||||
bool success = await RemoveGraph(g.Num);
|
GraphEntries.Remove(SelectedGraphEntry);
|
||||||
if (!success) {
|
GraphList.Items.Refresh();
|
||||||
MessageBox.Show("Der Graph konnte nicht gelöscht werden", "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
}
|
|
||||||
await RefreshGraphList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, RoutedEventArgs e) {
|
||||||
private async void SaveButton_Click(object sender, RoutedEventArgs e) {
|
//TODO SAVE
|
||||||
int? index = await UpdateGraph(Graph);
|
|
||||||
if (index == null) {
|
|
||||||
MessageBox.Show("Der Graph konnte nicht gespeichert werden", "Graph speichern", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
}
|
|
||||||
IsEditing = false;
|
|
||||||
IsCreating = false;
|
|
||||||
GraphList.IsEnabled = true;
|
|
||||||
HideSaveResetCancelButtons();
|
|
||||||
ShowNewEditDeleteButtons();
|
|
||||||
LockInputs();
|
|
||||||
PriceInput.IsReadOnly = true;
|
|
||||||
OechsleInput.IsReadOnly = true;
|
|
||||||
await RefreshGraphList();
|
|
||||||
GraphList.SelectedIndex = index.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int?> UpdateGraph(Graph g) {
|
private void GraphList_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||||
List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync();
|
SelectedGraphEntry = (GraphEntry)GraphList.SelectedItem;
|
||||||
|
|
||||||
if (paymentVars.Count != 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PaymentVar paymentVar = paymentVars[0];
|
|
||||||
var data = JsonNode.Parse(paymentVar.Data).AsObject();
|
|
||||||
|
|
||||||
var auszahlungsSorten = data["AuszahlungSorten"];
|
|
||||||
if (auszahlungsSorten == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var Graphs = auszahlungsSorten["Kurven"].AsArray();
|
|
||||||
if (Graphs == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsEditing) {
|
|
||||||
Graphs[g.Num - 1] = g.ToJson();
|
|
||||||
} else if(IsCreating) {
|
|
||||||
Graphs.Add(g.ToJson());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityEntry<PaymentVar>? tr = null;
|
|
||||||
try {
|
|
||||||
paymentVar.Data = data.ToString();
|
|
||||||
tr = Context.Update(paymentVar);
|
|
||||||
|
|
||||||
await Context.SaveChangesAsync();
|
|
||||||
} catch (Exception exc) {
|
|
||||||
if (tr != null) await tr.ReloadAsync();
|
|
||||||
var str = "Der Eintrag konnte nicht in der Datenbank gelöscht werden!\n\n" + exc.Message;
|
|
||||||
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
|
|
||||||
MessageBox.Show(str, "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g.Num - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetButton_Click(object sender, RoutedEventArgs e) {
|
|
||||||
if (IsEditing) {
|
|
||||||
RefreshInputs();
|
|
||||||
} else if (IsCreating) {
|
|
||||||
InitInputs();
|
|
||||||
}
|
|
||||||
UpdateButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CancelButton_Click(object sender, RoutedEventArgs e) {
|
|
||||||
IsEditing = false;
|
|
||||||
IsCreating = false;
|
|
||||||
GraphList.IsEnabled = true;
|
|
||||||
HideSaveResetCancelButtons();
|
|
||||||
ShowNewEditDeleteButtons();
|
|
||||||
DisableActionButtons();
|
|
||||||
RefreshInputs();
|
|
||||||
PriceInput.Text = "";
|
|
||||||
OechsleInput.Text = "";
|
|
||||||
ClearInputStates();
|
|
||||||
LockInputs();
|
|
||||||
PriceInput.IsReadOnly = true;
|
|
||||||
OechsleInput.IsReadOnly = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GraphList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) {
|
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
|
|
||||||
//var x = OechslePricePlot.Plot.GetPlottables().OfType<ScatterPlot>();
|
//var x = OechslePricePlot.Plot.GetPlottables().OfType<ScatterPlot>();
|
||||||
@@ -742,11 +477,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GraphNumberInput_TextChanged(object sender, TextChangedEventArgs e) {
|
private void GebundenBonus_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GraphNumberInput_LostFocus(object sender, RoutedEventArgs e) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -100,7 +100,8 @@
|
|||||||
<LineBreak/>
|
<LineBreak/>
|
||||||
Filtern nach:<LineBreak/>
|
Filtern nach:<LineBreak/>
|
||||||
<Bold>Sorte</Bold>: z.B. GV, ZW, rr, sa, !gv (ausgenommen GV), ...<LineBreak/>
|
<Bold>Sorte</Bold>: z.B. GV, ZW, rr, sa, !gv (ausgenommen GV), ...<LineBreak/>
|
||||||
<Bold>Qualitätsstufe</Bold>: z.B. QUW, kab, ldw, ...<LineBreak/>
|
<Bold>Rot/Weiß</Bold>: z.B. r, Rot, w, weiß, ...<LineBreak/>
|
||||||
|
<Bold>Qualitätsstufe</Bold>: z.B. QUW, kab, !ldw (ausgenommen LDW), ...<LineBreak/>
|
||||||
<Bold>Gradation</Bold>: z.B. >73, <15, 17-18, 15-, >17,5, 62-75, ...<LineBreak/>
|
<Bold>Gradation</Bold>: z.B. >73, <15, 17-18, 15-, >17,5, 62-75, ...<LineBreak/>
|
||||||
<Bold>Mitglied</Bold>: z.B. 1234, 987, ...<LineBreak/>
|
<Bold>Mitglied</Bold>: z.B. 1234, 987, ...<LineBreak/>
|
||||||
<Bold>Saison</Bold>: z.B. 2020, >2015, 2017-2019, <2005, 2019-, ...<LineBreak/>
|
<Bold>Saison</Bold>: z.B. 2020, >2015, 2017-2019, <2005, 2019-, ...<LineBreak/>
|
||||||
|
@@ -326,6 +326,7 @@ namespace Elwig.Windows {
|
|||||||
var filterVar = new List<string>();
|
var filterVar = new List<string>();
|
||||||
var filterNotVar = new List<string>();
|
var filterNotVar = new List<string>();
|
||||||
var filterQual = new List<string>();
|
var filterQual = new List<string>();
|
||||||
|
var filterNotQual = new List<string>();
|
||||||
var filterMgNr = new List<int>();
|
var filterMgNr = new List<int>();
|
||||||
var filterZwst = new List<string>();
|
var filterZwst = new List<string>();
|
||||||
var filterAttr = new List<string>();
|
var filterAttr = new List<string>();
|
||||||
@@ -346,7 +347,15 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
for (int i = 0; i < filter.Count; i++) {
|
for (int i = 0; i < filter.Count; i++) {
|
||||||
var e = filter[i];
|
var e = filter[i];
|
||||||
if (e.Length == 2 && var.ContainsKey(e.ToUpper())) {
|
if (e.ToLower() is "r" or "rot") {
|
||||||
|
filterVar.AddRange(var.Values.Where(v => v.IsRed).Select(v => v.SortId));
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("Rotweinsorten");
|
||||||
|
} else if (e.ToLower() is "w" or "weiß" or "weiss") {
|
||||||
|
filterVar.AddRange(var.Values.Where(v => v.IsWhite).Select(v => v.SortId));
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("Weißweinsorten");
|
||||||
|
} else if (e.Length == 2 && var.ContainsKey(e.ToUpper())) {
|
||||||
filterVar.Add(e.ToUpper());
|
filterVar.Add(e.ToUpper());
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add(var[e.ToUpper()].Name);
|
filterNames.Add(var[e.ToUpper()].Name);
|
||||||
@@ -358,6 +367,10 @@ namespace Elwig.Windows {
|
|||||||
filterQual.Add(e.ToUpper());
|
filterQual.Add(e.ToUpper());
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add(qual[e.ToUpper()].Name);
|
filterNames.Add(qual[e.ToUpper()].Name);
|
||||||
|
} else if (e[0] == '!' && qual.ContainsKey(e[1..].ToUpper())) {
|
||||||
|
filterNotQual.Add(e[1..].ToUpper());
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("außer " + qual[e[1..].ToUpper()].Name);
|
||||||
} else if (e.All(char.IsAsciiDigit) && mgnr.TryGetValue(e, out var member)) {
|
} else if (e.All(char.IsAsciiDigit) && mgnr.TryGetValue(e, out var member)) {
|
||||||
filterMgNr.Add(int.Parse(e));
|
filterMgNr.Add(int.Parse(e));
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
@@ -492,9 +505,10 @@ namespace Elwig.Windows {
|
|||||||
if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId));
|
if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId));
|
||||||
if (filterNotVar.Count > 0) dpq = dpq.Where(p => !filterNotVar.Contains(p.SortId));
|
if (filterNotVar.Count > 0) dpq = dpq.Where(p => !filterNotVar.Contains(p.SortId));
|
||||||
if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId));
|
if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId));
|
||||||
|
if (filterNotQual.Count > 0) dpq = dpq.Where(p => !filterNotQual.Contains(p.QualId));
|
||||||
if (filterZwst.Count > 0) dpq = dpq.Where(p => filterZwst.Contains(p.Delivery.ZwstId));
|
if (filterZwst.Count > 0) dpq = dpq.Where(p => filterZwst.Contains(p.Delivery.ZwstId));
|
||||||
if (filterAttr.Count > 0) dpq = dpq.Where(p => p.AttrId != null && filterAttr.Contains(p.AttrId));
|
if (filterAttr.Count > 0) dpq = dpq.Where(p => p.AttrId != null && filterAttr.Contains(p.AttrId));
|
||||||
if (filterNotAttr.Count > 0) dpq = dpq.Where(p => p.AttrId == null || !filterAttr.Contains(p.AttrId));
|
if (filterNotAttr.Count > 0) dpq = dpq.Where(p => p.AttrId == null || !filterNotAttr.Contains(p.AttrId));
|
||||||
if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt);
|
if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt);
|
||||||
if (filterKmwLt > 0) dpq = dpq.Where(p => p.Kmw < filterKmwLt);
|
if (filterKmwLt > 0) dpq = dpq.Where(p => p.Kmw < filterKmwLt);
|
||||||
if (filterOeGt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt);
|
if (filterOeGt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt);
|
||||||
@@ -875,7 +889,7 @@ namespace Elwig.Windows {
|
|||||||
p.Acid = (AcidInput.Text == "") ? null : double.Parse(AcidInput.Text);
|
p.Acid = (AcidInput.Text == "") ? null : double.Parse(AcidInput.Text);
|
||||||
p.Comment = (PartCommentInput.Text == "") ? null : PartCommentInput.Text;
|
p.Comment = (PartCommentInput.Text == "") ? null : PartCommentInput.Text;
|
||||||
|
|
||||||
p.Weight = int.Parse(WeightInput.Text.Replace("\u202f", ""));
|
p.Weight = int.Parse(WeightInput.Text.Replace(Utils.GroupSeparator, ""));
|
||||||
p.ManualWeighing = ManualWeighingInput.IsChecked ?? false;
|
p.ManualWeighing = ManualWeighingInput.IsChecked ?? false;
|
||||||
p.ScaleId = ScaleId;
|
p.ScaleId = ScaleId;
|
||||||
p.WeighingId = WeighingId;
|
p.WeighingId = WeighingId;
|
||||||
|
@@ -76,7 +76,7 @@ namespace Elwig.Dialogs {
|
|||||||
IEnumerable<Member> list = await members.ToListAsync();
|
IEnumerable<Member> list = await members.ToListAsync();
|
||||||
var data = await DeliveryConfirmationData.ForSeason(Context.DeliveryParts, Year);
|
var data = await DeliveryConfirmationData.ForSeason(Context.DeliveryParts, Year);
|
||||||
using var doc = Document.Merge(list.Select(m =>
|
using var doc = Document.Merge(list.Select(m =>
|
||||||
new DeliveryConfirmation(Context, Year, m, data[m.MgNr]) {
|
new DeliveryConfirmation(Context, Year, m, data.TryGetValue(m.MgNr, out var d) ? d : DeliveryConfirmationData.CreateEmpty(Year, m)) {
|
||||||
//DoubleSided = true
|
//DoubleSided = true
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
@@ -259,8 +259,12 @@ namespace Elwig.Windows {
|
|||||||
return;
|
return;
|
||||||
CommitButton.IsEnabled = false;
|
CommitButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
var b = new BillingVariant(v.Year, v.AvNr);
|
try {
|
||||||
await b.Commit();
|
var b = new BillingVariant(v.Year, v.AvNr);
|
||||||
|
await b.Commit();
|
||||||
|
} catch (Exception exc) {
|
||||||
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
RevertButton.IsEnabled = true;
|
RevertButton.IsEnabled = true;
|
||||||
await App.HintContextChange();
|
await App.HintContextChange();
|
||||||
@@ -396,13 +400,13 @@ namespace Elwig.Windows {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
var json = BillingData.ParseJson(DataInput.Text);
|
var data = BillingData.FromJson(DataInput.Text);
|
||||||
var origJson = v.Data;
|
var origJson = v.Data;
|
||||||
try {
|
try {
|
||||||
origJson = JsonSerializer.Serialize(BillingData.ParseJson(v.Data));
|
origJson = JsonSerializer.Serialize(BillingData.FromJson(v.Data).Data);
|
||||||
} catch { }
|
} catch { }
|
||||||
DataValid = true;
|
DataValid = true;
|
||||||
if (JsonSerializer.Serialize(json) != origJson) {
|
if (JsonSerializer.Serialize(data.Data) != origJson) {
|
||||||
ControlUtils.SetInputChanged(DataInput);
|
ControlUtils.SetInputChanged(DataInput);
|
||||||
DataChanged = true;
|
DataChanged = true;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -86,7 +86,7 @@ namespace Elwig.Windows {
|
|||||||
private async void AutoBusinessSharesButton_Click(object sender, RoutedEventArgs evt) {
|
private async void AutoBusinessSharesButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (SeasonInput.Value is not int year)
|
if (SeasonInput.Value is not int year)
|
||||||
return;
|
return;
|
||||||
if (App.Client.IsMatzen) {
|
if (false && App.Client.IsMatzen) {
|
||||||
AutoBusinessSharesButton.IsEnabled = false;
|
AutoBusinessSharesButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
|
||||||
|
@@ -60,6 +60,6 @@
|
|||||||
<None Include="Files\config.ini" />
|
<None Include="Files\config.ini" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="WixToolset.Heat" Version="4.0.1" />
|
<PackageReference Include="WixToolset.Heat" Version="4.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
</Target>
|
</Target>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Installer\Installer.wixproj" />
|
<ProjectReference Include="..\Installer\Installer.wixproj" />
|
||||||
<PackageReference Include="WixToolset.Bal.wixext" Version="4.0.1" />
|
<PackageReference Include="WixToolset.Bal.wixext" Version="4.0.3" />
|
||||||
<PackageReference Include="WixToolset.Util.wixext" Version="4.0.1" />
|
<PackageReference Include="WixToolset.Util.wixext" Version="4.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -26,14 +26,14 @@ namespace Tests.Helpers {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TestCalcOe(BillingData data, string bucket, double oe, decimal expected, string? qualid = null, bool geb = false) {
|
private static void TestCalcOe(PaymentBillingData data, string bucket, double oe, decimal expected, string? qualid = null, bool geb = false) {
|
||||||
var (sortid, attrid) = GetSortIdAttrId(bucket);
|
var (sortid, attrid) = GetSortIdAttrId(bucket);
|
||||||
var kmw = Utils.OeToKmw(oe);
|
var kmw = Utils.OeToKmw(oe);
|
||||||
var v = data.CalculatePrice(sortid, attrid, qualid ?? GetQualId(kmw), geb, oe, kmw);
|
var v = data.CalculatePrice(sortid, attrid, qualid ?? GetQualId(kmw), geb, oe, kmw);
|
||||||
Assert.That(Math.Round(v, 6), Is.EqualTo(expected));
|
Assert.That(Math.Round(v, 6), Is.EqualTo(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TestCalcKmw(BillingData data, string bucket, double kmw, decimal expected, string? qualid = null, bool geb = false) {
|
private static void TestCalcKmw(PaymentBillingData data, string bucket, double kmw, decimal expected, string? qualid = null, bool geb = false) {
|
||||||
var (sortid, attrid) = GetSortIdAttrId(bucket);
|
var (sortid, attrid) = GetSortIdAttrId(bucket);
|
||||||
var oe = Utils.KmwToOe(kmw);
|
var oe = Utils.KmwToOe(kmw);
|
||||||
var v = data.CalculatePrice(sortid, attrid, qualid ?? GetQualId(kmw), geb, oe, kmw);
|
var v = data.CalculatePrice(sortid, attrid, qualid ?? GetQualId(kmw), geb, oe, kmw);
|
||||||
@@ -42,7 +42,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_01_Flatrate() {
|
public void Test_01_Flatrate() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -58,7 +58,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_02_Simple() {
|
public void Test_02_Simple() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -93,7 +93,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_03_GreaterThanAndLessThan() {
|
public void Test_03_GreaterThanAndLessThan() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -132,7 +132,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_04_VariantsAndAttributes() {
|
public void Test_04_VariantsAndAttributes() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -162,7 +162,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_05_QualityLevel() {
|
public void Test_05_QualityLevel() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -193,7 +193,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_06_ModeOeAndKmw() {
|
public void Test_06_ModeOeAndKmw() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -235,7 +235,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_07_MultipleCurves() {
|
public void Test_07_MultipleCurves() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "elwig",
|
"mode": "elwig",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
@@ -304,7 +304,7 @@ namespace Tests.Helpers {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test_08_WgMaster() {
|
public void Test_08_WgMaster() {
|
||||||
var data = BillingData.FromJson("""
|
var data = PaymentBillingData.FromJson("""
|
||||||
{
|
{
|
||||||
"mode": "wgmaster",
|
"mode": "wgmaster",
|
||||||
"Grundbetrag": 0.033,
|
"Grundbetrag": 0.033,
|
||||||
|
@@ -18,11 +18,17 @@
|
|||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="3.5.0" />
|
<PackageReference Include="NUnit.Analyzers" Version="3.10.0">
|
||||||
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Reference in New Issue
Block a user