Compare commits

...

10 Commits

12 changed files with 561 additions and 250 deletions
+36
View File
@@ -145,5 +145,41 @@ namespace Elwig.Helpers.Billing {
}
return dict;
}
protected static Dictionary<string, JsonValue> GetSelection(JsonNode value, IEnumerable<string> attributeVariants) {
if (value is JsonValue flatRate) {
return attributeVariants.ToDictionary(e => e, _ => flatRate);
} if (value is not JsonObject data) {
throw new InvalidOperationException();
}
Dictionary<string, JsonValue> dict;
if (data["default"] is JsonValue def) {
dict = attributeVariants.ToDictionary(e => e, _ => def);
} 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 && p.Key != "default");
foreach (var (idx, v) in variants) {
var curve = 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 = 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 = v?.AsValue() ?? throw new InvalidOperationException();
dict[idx.Replace("/", "")] = curve;
}
return dict;
}
}
}
@@ -0,0 +1,47 @@
using Elwig.Models.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Elwig.Helpers.Billing {
public class ContractSelection : IComparable<ContractSelection> {
public WineVar? Variety { get; }
public WineAttr? Attribute { get; }
public string Listing => Variety != null || Attribute != null ? $"{Variety?.SortId}{Attribute?.AttrId}" : "";
public ContractSelection(WineVar? var, WineAttr? attr) {
Variety = var;
Attribute = attr;
}
public ContractSelection(WineVar var) {
Variety = var;
}
public ContractSelection(WineAttr attr) {
Attribute = attr;
}
public override string ToString() {
return (Variety != null ? $"{Variety.Name}" : "") + (Attribute != null ? $" {Attribute.Name}" : "");
}
public static List<ContractSelection> GetContractsForYear(AppDbContext context, int year) {
return context.DeliveryParts
.Where(d => d.Year == year)
.Select(d => new ContractSelection(d.Variant, d.Attribute))
.Distinct()
.ToList()
.Union(context.WineVarieties.Select(v => new ContractSelection(v)))
.ToList();
}
public int CompareTo(ContractSelection? other) {
//MessageBox.Show($"{Listing} -- {other.Listing} : {Listing.CompareTo(other.Listing)}");
return other != null ?
Listing.CompareTo(other.Listing) :
throw new ArgumentException();
}
}
}
+25 -8
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
@@ -16,7 +17,7 @@ namespace Elwig.Helpers.Billing {
return new(ParseJson(json), attributeVariants);
}
public IEnumerable<GraphEntry> GetPaymentGraphEntries() {
public IEnumerable<GraphEntry> GetPaymentGraphEntries(AppDbContext context) {
Dictionary<int, List<string>> dict1 = [];
Dictionary<decimal, List<string>> dict2 = [];
var p = GetPaymentEntry();
@@ -40,22 +41,38 @@ namespace Elwig.Helpers.Billing {
dict2[idx].Add("default");
}
var virtOffset = dict1.Count;
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);
dict1[i + virtOffset] = dict2[idx];
curves[i + virtOffset] = new Curve(CurveMode.Oe, new() { { 73, idx } }, null);
}
Dictionary<int, List<string>> dict3 = [];
Dictionary<int, List<string>> dict3 = curves.ToDictionary(c => c.Key, _ => new List<string>());
foreach (var (selector, value) in GetSelection(p, AttributeVariants)) {
int? idx = null;
if (value.TryGetValue<decimal>(out var val)) {
idx = Array.IndexOf(virtCurves, val) + virtOffset;
} else if (value.TryGetValue<string>(out var str)) {
idx = int.Parse(str.Split(":")[1]);
}
if (idx != null)
dict3[(int)idx].Add(selector);
}
var vars = context.WineVarieties.ToDictionary(v => v.SortId, v => v);
var attrs = context.WineAttributes.ToDictionary(a => a.AttrId, a => a);
return dict3.Select(e => new GraphEntry(e.Key, curves[e.Key], 50, 120)).ToList();
return dict3
.Select(e => new GraphEntry(e.Key, curves[e.Key], e.Value
.Select(s => new ContractSelection(vars[s[..2]], s.Length > 2 ? attrs[s[2..]] : null))
.ToList(), 50, 120))
.ToList();
}
public IEnumerable<GraphEntry> GetQualityGraphEntries() {
public IEnumerable<GraphEntry> GetQualityGraphEntries(AppDbContext context) {
Dictionary<int, List<string>> dict1 = [];
Dictionary<decimal, List<string>> dict2 = [];
foreach (var (qualid, q) in GetQualityEntry() ?? []) {
+49 -4
View File
@@ -26,6 +26,22 @@ namespace Elwig.Helpers.Billing {
DataY = dataY;
}
public double GetOechsleAt(int index) {
return DataX[index];
}
public void SetOechsleAt(int index, double oechsle) {
DataX[index] = oechsle;
}
public void SetPriceAt(int index, double price) {
DataY[index] = price;
}
public double GetPriceAt(int index) {
return DataY[index];
}
private void ParseGraphData(Dictionary<double, decimal> graphPoints, int minX, int maxX) {
if (graphPoints.Keys.Count < 1) {
return;
@@ -71,19 +87,48 @@ namespace Elwig.Helpers.Billing {
}
}
public void FlattenGraph(int begin, int end, double value) {
private void FlattenGraph(int begin, int end, double value) {
for (int i = begin; i <= end; i++) {
DataY[i] = value;
}
}
public void LinearIncreaseGraph(int begin, int end, double inc) {
public void FlattenGraphLeft(int pointIndex) {
FlattenGraph(0, pointIndex, DataY[pointIndex]);
}
public void FlattenGraphRight(int pointIndex) {
FlattenGraph(pointIndex, DataY.Length - 1, DataY[pointIndex]);
}
private void LinearIncreaseGraph(int begin, int end, double inc) {
for (int i = begin; i < end; i++) {
DataY[i + 1] = DataY[i] + inc;
DataY[i + 1] = Math.Round(DataY[i] + inc, 4); //TODO richtig runden
}
}
public JsonObject ToJson(string mode) {
public void LinearIncreaseGraphToEnd(int begin, double inc) {
LinearIncreaseGraph(begin, DataY.Length - 1, inc);
}
public void InterpolateGraph(int firstPoint, int secondPoint) {
int steps = Math.Abs(firstPoint - secondPoint);
if (firstPoint == -1 || secondPoint == -1 || steps < 2) {
return;
}
var (lowIndex, highIndex) = firstPoint < secondPoint ? (firstPoint, secondPoint) : (secondPoint, firstPoint);
double step = (DataY[highIndex] - DataY[lowIndex]) / steps;
for (int i = lowIndex; i < highIndex - 1; i++) {
DataY[i + 1] = Math.Round(DataY[i] + step, 4); // TODO richtig runden
}
}
public JsonNode ToJson(string mode) {
if (DataY.Distinct().Count() == 1) {
return JsonValue.Create(DataY[0]);
}
var data = new JsonObject();
if (DataY[0] != DataY[1]) {
+27 -10
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
namespace Elwig.Helpers.Billing {
@@ -8,8 +9,10 @@ namespace Elwig.Helpers.Billing {
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; }
public decimal? GebundenFlatBonus { get; set; }
public List<ContractSelection> Contracts { get; set; }
public string ContractsStringSimple => Contracts.Any() ? string.Join(", ", Contracts.Select(c => c.Listing)) : "-";
public string ContractsString => Contracts.Any() ? string.Join("\n", Contracts.Select(c => c.ToString())) : "-";
private int MinX { get; set; }
private int MaxX { get; set; }
@@ -22,30 +25,44 @@ namespace Elwig.Helpers.Billing {
Contracts = [];
}
public GraphEntry(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, int minX, int maxX) :
this(id, mode, minX, maxX) {
public GraphEntry(int id, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden,
int minX, int maxX) : this(id, mode, minX, maxX) {
DataGraph = new Graph(data, minX, maxX);
if (gebunden != null) GebundenGraph = new Graph(gebunden, minX, maxX);
}
public GraphEntry(int id, BillingData.Curve curve, int minX, int maxX) :
public GraphEntry(int id, BillingData.Curve curve, List<ContractSelection> contracts, 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);
Contracts = contracts;
}
private GraphEntry(int id, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph,
decimal? gebundenFlatPrice, List<string> contracts, int minX, int maxX) {
decimal? gebundenFlatPrice, List<ContractSelection> contracts, int minX, int maxX) {
Id = id;
Mode = mode;
MinX = minX;
MaxX = maxX;
DataGraph = dataGraph;
GebundenGraph = gebundenGraph;
GebundenFlatPrice = gebundenFlatPrice;
GebundenFlatBonus = gebundenFlatPrice;
Contracts = contracts;
}
public void AddGebundenGraph() {
GebundenGraph ??= new Graph(MinX, MaxX);
}
public void RemoveGebundenGraph() {
GebundenGraph = null;
}
public void SetGebundenFlatBonus(decimal? value) {
GebundenFlatBonus = value;
}
public JsonObject ToJson() {
var curve = new JsonObject {
["id"] = Id,
@@ -54,8 +71,8 @@ namespace Elwig.Helpers.Billing {
curve["data"] = DataGraph.ToJson(Mode.ToString().ToLower());
if (GebundenFlatPrice != null) {
curve["geb"] = GebundenFlatPrice.ToString();
if (GebundenFlatBonus != null) {
curve["geb"] = GebundenFlatBonus;
} else if (GebundenGraph != null) {
curve["geb"] = GebundenGraph.ToJson(Mode.ToString().ToLower());
}
@@ -64,7 +81,7 @@ namespace Elwig.Helpers.Billing {
}
public GraphEntry Copy(int id) {
return new GraphEntry(id, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatPrice, Contracts, MinX, MaxX);
return new GraphEntry(id, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), GebundenFlatBonus, [], MinX, MaxX);
}
}
}
+4 -45
View File
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json.Nodes;
@@ -26,45 +25,12 @@ namespace Elwig.Helpers.Billing {
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;
private Dictionary<string, Curve> GetData(JsonNode data) {
return GetSelection(data, AttributeVariants).ToDictionary(e => e.Key, e => LookupCurve(e.Value));
}
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());
return GetData(GetPaymentEntry());
}
protected Dictionary<string, Curve> GetQualityData() {
@@ -73,14 +39,7 @@ namespace Elwig.Helpers.Billing {
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) {
foreach (var (idx, d) in GetData(data ?? throw new InvalidOperationException())) {
dict[$"{qualid}/{idx}"] = d;
}
}
+14 -1
View File
@@ -68,19 +68,32 @@ namespace Elwig.Models.Entities {
[InverseProperty("Delivery")]
public virtual ISet<DeliveryPart> Parts { get; private set; }
[NotMapped]
public IEnumerable<DeliveryPart> FilteredParts => PartFilter == null ? Parts : Parts.Where(p => PartFilter(p));
[NotMapped]
public Predicate<DeliveryPart>? PartFilter { get; set; }
public int Weight => Parts.Select(p => p.Weight).Sum();
public int FilteredWeight => FilteredParts.Select(p => p.Weight).Sum();
public IEnumerable<string> SortIds => Parts
.GroupBy(p => p.SortId)
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
.Select(g => g.Select(p => p.SortId).First());
.Select(g => g.Key);
public IEnumerable<string> FilteredSortIds => FilteredParts
.GroupBy(p => p.SortId)
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
.Select(g => g.Key);
public string SortIdString => string.Join(", ", SortIds);
public string FilteredSortIdString => string.Join(", ", FilteredSortIds);
public double Kmw => Utils.AggregateDeliveryPartsKmw(Parts);
public double FilteredKmw => Utils.AggregateDeliveryPartsKmw(FilteredParts);
public double Oe => Utils.KmwToOe(Kmw);
public double FilteredOe => Utils.KmwToOe(FilteredKmw);
public int SearchScore(IEnumerable<string> keywords) {
var list = new string?[] {
+18 -14
View File
@@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Elwig.Windows"
xmlns:ctrl="clr-namespace:Elwig.Controls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF"
mc:Ignorable="d"
@@ -59,12 +60,12 @@
</Grid.ColumnDefinitions>
<Label Content="Graph:" Margin="10,0,0,0" FontSize="14" Grid.Column="0" VerticalAlignment="Center"/>
<TextBlock x:Name="GraphNum" Margin="0,0,40,0" FontSize="14" Width="50" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBlock x:Name="GraphNum" Margin="55,0,0,0" FontSize="14" Width="50" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<Label Content="Für:" Margin="10,0,0,0" FontSize="14" Grid.Column="1" VerticalAlignment="Center"/>
<xctk:CheckComboBox x:Name="AppliedInput" Margin="0,10,10,10" Grid.Column="1"
Delimiter=", " AllItemsSelectedContent="Alle"
Width="400" HorizontalAlignment="Right">
<xctk:CheckComboBox x:Name="ContractInput" Margin="0,10,-42,5" Grid.Column="1" DisplayMemberPath="{Binding Listing}"
Delimiter=", " AllItemsSelectedContent="Alle" IsEnabled="False" ItemSelectionChanged="ContractInput_Changed"
Width="500" Height="25" HorizontalAlignment="Right">
<!--<xctk:CheckComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
@@ -79,8 +80,8 @@
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Width="40"/>
<TextBlock Text="{Binding Contracts}" Width="100"/>
<TextBlock Text="{Binding Id}" Width="30"/>
<TextBlock Text="{Binding ContractsStringSimple}" Width="140" ToolTip="{Binding ContractsString}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
@@ -121,11 +122,13 @@
</Grid.ColumnDefinitions>
<Label Content="Oechsle:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="OechsleInput" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0" Text="" Width="90" TextChanged="OechsleInput_TextChanged" LostFocus="OechsleInput_LostFocus"/>
<ctrl:UnitTextBox x:Name="OechsleInput" Unit="°Oe" TextChanged="OechsleInput_TextChanged" IsEnabled="False" LostFocus="OechsleInput_LostFocus"
Grid.Column="1" Width="90" Margin="0,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Label Content="Preis pro kg:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="PriceInput" Grid.Column="1" HorizontalAlignment="Left" Margin="0,40,0,0" Text="" Width="90" TextChanged="PriceInput_TextChanged" LostFocus="PriceInput_LostFocus"/>
<Label Content="Preis:" Margin="10,40,0,0" Grid.Column="0"/>
<ctrl:UnitTextBox x:Name="PriceInput" Unit="€/kg" TextChanged="PriceInput_TextChanged" IsEnabled="False" LostFocus="PriceInput_LostFocus"
Grid.Column="1" Width="90" Margin="0,40,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
</GroupBox>
@@ -137,13 +140,14 @@
</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>
<RadioButton x:Name="GebundenTypeFixed" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Fix</RadioButton>
<RadioButton x:Name="GebundenTypeGraph" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Graph</RadioButton>
<RadioButton x:Name="GebundenTypeNone" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">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>
<ctrl:UnitTextBox x:Name="GebundenFlatBonus" Unit="€/kg" TextChanged="GebundenFlatBonus_TextChanged" IsEnabled="False"
Width="90" Margin="0,5,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1"/>
</Grid>
</GroupBox>
<GroupBox Header="Aktionen" Grid.Row="2" Margin="0,5,5,5">
+301 -135
View File
@@ -2,12 +2,12 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Elwig.Controls;
using Elwig.Helpers;
using Elwig.Helpers.Billing;
using Elwig.Models.Entities;
@@ -19,20 +19,25 @@ using ScottPlot.Plottable;
namespace Elwig.Windows {
public partial class ChartWindow : ContextWindow {
public static readonly Color ColorUngebunden = Color.Blue;
public static readonly Color ColorGebunden = Color.Gold;
public readonly int Year;
public readonly int AvNr;
private readonly PaymentVar PaymentVar;
private ScatterPlot OechslePricePlotScatter;
private MarkerPlot HighlightedPoint;
private MarkerPlot PrimaryMarkedPoint;
private MarkerPlot SecondaryMarkedPoint;
private Tooltip Tooltip;
private ScatterPlot DataPlot;
private ScatterPlot? GebundenPlot;
private MarkerPlot HighlightedPointPlot;
private MarkerPlot PrimaryMarkedPointPlot;
private MarkerPlot SecondaryMarkedPointPlot;
private Tooltip TooltipPlot;
private int LastHighlightedIndex = -1;
private int HighlightedIndex = -1;
private int PrimaryMarkedPointIndex = -1;
private int SecondaryMarkedPointIndex = -1;
private (Graph? graph, int index) LastHighlighted = (null, -1);
private (Graph? graph, int index) Highlighted = (null, -1);
private Graph? ActiveGraph = null;
private int PrimaryMarkedPoint = -1;
private int SecondaryMarkedPoint = -1;
private bool HoverChanged = false;
private bool HoverActive = false;
@@ -56,10 +61,7 @@ namespace Elwig.Windows {
private async Task RefreshGraphList() {
await Context.PaymentVariants.LoadAsync();
await RefreshGraphListQuery();
}
private async Task RefreshGraphListQuery() {
var attrVariants = Context.DeliveryParts
.Where(d => d.Year == Year)
.Select(d => $"{d.SortId}{d.AttrId}")
@@ -69,44 +71,58 @@ namespace Elwig.Windows {
.Order()
.ToList();
var data = EditBillingData.FromJson(PaymentVar.Data, attrVariants);
GraphEntries.AddRange(data.GetPaymentGraphEntries());
GraphEntries.AddRange(data.GetQualityGraphEntries());
GraphEntries = [ ..data.GetPaymentGraphEntries(Context), ..data.GetQualityGraphEntries(Context)];
ControlUtils.RenewItemsSource(AppliedInput, attrVariants, g => g);
ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.Id, null, ControlUtils.RenewSourceDefault.IfOnly);
var contracts = ContractSelection.GetContractsForYear(Context, Year).DistinctBy(c => c.Listing).Order().ToList();
ControlUtils.RenewItemsSource(ContractInput, contracts, g => (g as ContractSelection)?.ToString());
ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.Id, null, ControlUtils.RenewSourceDefault.First);
RefreshInputs();
}
private string ParseContracts(JsonObject auszahlungsSorten, int num) {
return "";
}
private void RefreshInputs(bool validate = false) {
private void RefreshInputs() {
ResetPlot();
if (!PaymentVar.TestVariant) {
AddButton.IsEnabled = false;
CopyButton.IsEnabled = false;
DeleteButton.IsEnabled = false;
OechsleInput.IsReadOnly = true;
PriceInput.IsReadOnly = true;
} else if (SelectedGraphEntry != null) {
if (SelectedGraphEntry != null) {
CopyButton.IsEnabled = true;
DeleteButton.IsEnabled = true;
OechsleInput.IsReadOnly = false;
//EnableUnitTextBox(OechsleInput);
GebundenTypeFixed.IsEnabled = true;
GebundenTypeGraph.IsEnabled = true;
GebundenTypeNone.IsEnabled = true;
ContractInput.IsEnabled = true;
EnableOptionButtons();
FillInputs();
} else {
CopyButton.IsEnabled = false;
DeleteButton.IsEnabled = false;
OechsleInput.IsReadOnly = true;
DisableUnitTextBox(OechsleInput);
DisableOptionButtons();
}
GC.Collect();
if (!PaymentVar.TestVariant) {
AddButton.IsEnabled = false;
CopyButton.IsEnabled = false;
DeleteButton.IsEnabled = false;
DisableUnitTextBox(OechsleInput);
DisableUnitTextBox(PriceInput);
GebundenTypeFixed.IsEnabled = false;
GebundenTypeGraph.IsEnabled = false;
GebundenTypeNone.IsEnabled = false;
ContractInput.IsEnabled = false;
}
}
private void FillInputs() {
GraphNum.Text = SelectedGraphEntry.Id.ToString();
GraphNum.Text = SelectedGraphEntry?.Id.ToString();
if (SelectedGraphEntry?.GebundenFlatBonus != null) {
GebundenTypeFixed.IsChecked = true;
} else if (SelectedGraphEntry?.GebundenGraph != null) {
GebundenTypeGraph.IsChecked = true;
} else {
GebundenTypeNone.IsChecked = true; ;
}
ControlUtils.SelectCheckComboBoxItems(ContractInput, SelectedGraphEntry?.Contracts ?? [], i => (i as ContractSelection)?.Listing);
InitPlot();
OechslePricePlot.IsEnabled = true;
@@ -117,13 +133,24 @@ namespace Elwig.Windows {
}
private void InitPlot() {
OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY);
if (SelectedGraphEntry?.GebundenGraph != null) {
GebundenPlot = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry.GebundenGraph.DataX, SelectedGraphEntry.GebundenGraph.DataY);
GebundenPlot.LineColor = ColorGebunden;
GebundenPlot.MarkerColor = ColorGebunden;
GebundenPlot.MarkerSize = 9;
}
DataPlot = OechslePricePlot.Plot.AddScatter(SelectedGraphEntry!.DataGraph.DataX, SelectedGraphEntry!.DataGraph.DataY);
DataPlot.LineColor = ColorUngebunden;
DataPlot.MarkerColor = ColorUngebunden;
DataPlot.MarkerSize = 9;
if (SelectedGraphEntry?.GebundenGraph == null) {
ChangeActiveGraph(SelectedGraphEntry?.DataGraph);
}
OechslePricePlot.RightClicked -= OechslePricePlot.DefaultRightClickEvent;
OechslePricePlot.Configuration.DoubleClickBenchmark = false;
OechslePricePlotScatter.LineColor = Color.Blue;
OechslePricePlotScatter.MarkerColor = Color.Blue;
OechslePricePlotScatter.MarkerSize = 9;
//OechslePricePlot.Plot.XAxis.ManualTickSpacing(1);
OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1);
OechslePricePlot.Plot.SetAxisLimits(MinOechsle - 1, MaxOechsle + 1, -0.1, 2);
@@ -133,23 +160,23 @@ namespace Elwig.Windows {
OechslePricePlot.Plot.YAxis.Layout(padding: 0);
OechslePricePlot.Plot.YAxis2.Layout(padding: 0);
HighlightedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
HighlightedPoint.Color = Color.Red;
HighlightedPoint.MarkerSize = 10;
HighlightedPoint.MarkerShape = MarkerShape.openCircle;
HighlightedPoint.IsVisible = false;
HighlightedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
HighlightedPointPlot.Color = Color.Red;
HighlightedPointPlot.MarkerSize = 10;
HighlightedPointPlot.MarkerShape = MarkerShape.openCircle;
HighlightedPointPlot.IsVisible = false;
PrimaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
PrimaryMarkedPoint.Color = Color.Red;
PrimaryMarkedPoint.MarkerSize = 6;
PrimaryMarkedPoint.MarkerShape = MarkerShape.filledCircle;
PrimaryMarkedPoint.IsVisible = false;
PrimaryMarkedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
PrimaryMarkedPointPlot.Color = Color.Red;
PrimaryMarkedPointPlot.MarkerSize = 6;
PrimaryMarkedPointPlot.MarkerShape = MarkerShape.filledCircle;
PrimaryMarkedPointPlot.IsVisible = false;
SecondaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
SecondaryMarkedPoint.Color = Color.Red;
SecondaryMarkedPoint.MarkerSize = 6;
SecondaryMarkedPoint.MarkerShape = MarkerShape.filledCircle;
SecondaryMarkedPoint.IsVisible = false;
SecondaryMarkedPointPlot = OechslePricePlot.Plot.AddPoint(0, 0);
SecondaryMarkedPointPlot.Color = Color.Red;
SecondaryMarkedPointPlot.MarkerSize = 6;
SecondaryMarkedPointPlot.MarkerShape = MarkerShape.filledCircle;
SecondaryMarkedPointPlot.IsVisible = false;
OechslePricePlot.Refresh();
@@ -158,8 +185,12 @@ namespace Elwig.Windows {
}
private void ResetPlot() {
PrimaryMarkedPointIndex = -1;
OechslePricePlot.Plot.Remove(OechslePricePlotScatter);
PrimaryMarkedPoint = -1;
SecondaryMarkedPoint = -1;
ChangeActiveGraph(null);
HideGradationLines();
OechslePricePlot.Plot.Remove(DataPlot);
OechslePricePlot.Plot.Remove(GebundenPlot);
OechslePricePlot.Plot.Clear();
OechslePricePlot.Reset();
OechslePricePlot.Refresh();
@@ -171,20 +202,16 @@ namespace Elwig.Windows {
point.IsVisible = visible;
}
private void FlattenGraph(int begin, int end, double value) {
SelectedGraphEntry.DataGraph.FlattenGraph(begin, end, value);
OechslePricePlot.Render();
}
private void LinearIncreaseGraph(int begin, int end, double inc) {
SelectedGraphEntry.DataGraph.LinearIncreaseGraph(begin, end, inc);
OechslePricePlot.Render();
}
private void EnableActionButtons() {
LeftFlatButton.IsEnabled = true;
RightFlatButton.IsEnabled = true;
LinearIncreaseButton.IsEnabled = true;
if (PaymentVar.TestVariant) {
LeftFlatButton.IsEnabled = true;
RightFlatButton.IsEnabled = true;
LinearIncreaseButton.IsEnabled = true;
}
}
private void DisableActionButtons() {
@@ -239,10 +266,10 @@ namespace Elwig.Windows {
}
private void RefreshGradationLines() {
if (GradationLinesInput.IsChecked == true) {
if (GradationLinesInput.IsChecked == true && SelectedGraphEntry != null && !OechslePricePlot.Plot.GetPlottables().OfType<VLine>().Any()) {
ShowGradationLines();
ShowLegend();
} else {
} else if (GradationLinesInput.IsChecked == false) {
HideGradationLines();
HideLegend();
}
@@ -268,82 +295,85 @@ namespace Elwig.Windows {
}
private void OechsleInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (ActiveGraph == null) {
return;
}
bool success = int.TryParse(OechsleInput.Text, out int oechsle);
SecondaryMarkedPointIndex = -1;
ChangeMarker(SecondaryMarkedPoint, false);
SecondaryMarkedPoint = -1;
ChangeMarker(SecondaryMarkedPointPlot, false);
if (success) {
if (oechsle >= MinOechsle && oechsle <= MaxOechsle) {
PrimaryMarkedPointIndex = oechsle - MinOechsle;
ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
PrimaryMarkedPoint = oechsle - MinOechsle;
ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));
PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex].ToString();
PriceInput.Text = ActiveGraph.GetPriceAt(PrimaryMarkedPoint).ToString();
EnableActionButtons();
OechslePricePlot.Render();
PriceInput.IsReadOnly = false;
EnableUnitTextBox(PriceInput);
return;
}
}
PrimaryMarkedPointIndex = -1;
ChangeMarker(PrimaryMarkedPoint, false);
PrimaryMarkedPoint = -1;
//ChangeActiveGraph(null);
ChangeMarker(PrimaryMarkedPointPlot, false);
DisableActionButtons();
PriceInput.Text = "";
DisableUnitTextBox(PriceInput);
OechslePricePlot.Render();
PriceInput.IsReadOnly = true;
DisableUnitTextBox(PriceInput);
}
private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) {
if (PrimaryMarkedPointIndex != -1) {
bool success = Double.TryParse(PriceInput.Text, out double price);
private void PriceInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PrimaryMarkedPoint != -1 && ActiveGraph != null) {
bool success = double.TryParse(PriceInput.Text, out double price);
if (success) {
SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex] = price;
PrimaryMarkedPoint.Y = price;
ActiveGraph.SetPriceAt(PrimaryMarkedPoint, price);
PrimaryMarkedPointPlot.Y = price;
OechslePricePlot.Refresh();
}
}
}
private void LeftFlatButton_Click(object sender, RoutedEventArgs evt) {
if (PrimaryMarkedPointIndex == -1) {
if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
return;
}
FlattenGraph(0, PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
ActiveGraph.FlattenGraphLeft(PrimaryMarkedPoint);
OechslePricePlot.Render();
}
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
if (PrimaryMarkedPointIndex == -1) {
if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
return;
}
FlattenGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
ActiveGraph.FlattenGraphRight(PrimaryMarkedPoint);
OechslePricePlot.Render();
}
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
int steps = Math.Abs(PrimaryMarkedPointIndex - SecondaryMarkedPointIndex);
if (PrimaryMarkedPointIndex == -1 || SecondaryMarkedPointIndex == -1 || steps < 2) {
if (PrimaryMarkedPoint == SecondaryMarkedPoint || PrimaryMarkedPoint == -1 || SecondaryMarkedPoint == -1 || ActiveGraph == null) {
return;
}
var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex);
double step = (SelectedGraphEntry.DataGraph.DataY[highIndex] - SelectedGraphEntry.DataGraph.DataY[lowIndex]) / steps;
for (int i = lowIndex; i < highIndex - 1; i++) {
SelectedGraphEntry.DataGraph.DataY[i + 1] = Math.Round(SelectedGraphEntry.DataGraph.DataY[i] + step, 4); // TODO richtig runden
}
ActiveGraph.InterpolateGraph(PrimaryMarkedPoint, SecondaryMarkedPoint);
OechslePricePlot.Render();
}
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
if (PrimaryMarkedPointIndex == -1) {
if (PrimaryMarkedPoint == -1 || ActiveGraph == null) {
return;
}
double? priceIncrease = Utils.ShowLinearPriceIncreaseDialog();
if (priceIncrease == null) {
return;
}
LinearIncreaseGraph(PrimaryMarkedPointIndex, SelectedGraphEntry.DataGraph.DataY.Length - 1, priceIncrease.Value);
ActiveGraph.LinearIncreaseGraphToEnd(PrimaryMarkedPoint, priceIncrease.Value);
OechslePricePlot.Render();
}
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
@@ -353,83 +383,112 @@ namespace Elwig.Windows {
if (HoverActive) {
if (PaymentVar.TestVariant && Keyboard.IsKeyDown(Key.LeftCtrl)) {
if (PrimaryMarkedPointIndex == -1) {
if (PrimaryMarkedPoint == -1 || ActiveGraph == null || ActiveGraph != Highlighted.graph) {
return;
}
SecondaryMarkedPointIndex = HighlightedIndex;
ChangeMarker(SecondaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[SecondaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[SecondaryMarkedPointIndex]);
SecondaryMarkedPoint = Highlighted.index;
ChangeMarker(SecondaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(SecondaryMarkedPoint), ActiveGraph.GetPriceAt(SecondaryMarkedPoint));
InterpolateButton.IsEnabled = true;
return;
}
PrimaryMarkedPointIndex = HighlightedIndex;
ChangeMarker(PrimaryMarkedPoint, true, SelectedGraphEntry.DataGraph.DataX[PrimaryMarkedPointIndex], SelectedGraphEntry.DataGraph.DataY[PrimaryMarkedPointIndex]);
PrimaryMarkedPoint = Highlighted.index;
ChangeActiveGraph(Highlighted.graph);
OechsleInput.Text = SelectedGraphEntry.DataGraph.DataX[HighlightedIndex].ToString();
PriceInput.Text = SelectedGraphEntry.DataGraph.DataY[HighlightedIndex].ToString();
ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));
if (PaymentVar.TestVariant) {
EnableActionButtons();
}
OechsleInput.Text = Highlighted.graph.GetOechsleAt(Highlighted.index).ToString();
PriceInput.Text = Highlighted.graph.GetPriceAt(Highlighted.index).ToString();
EnableActionButtons();
} else {
PrimaryMarkedPointIndex = -1;
SecondaryMarkedPointIndex = -1;
ChangeMarker(PrimaryMarkedPoint, false);
ChangeMarker(SecondaryMarkedPoint, false);
PrimaryMarkedPoint = -1;
SecondaryMarkedPoint = -1;
if (SelectedGraphEntry!.GebundenGraph != null) {
ChangeActiveGraph(null);
}
ChangeMarker(PrimaryMarkedPointPlot, false);
ChangeMarker(SecondaryMarkedPointPlot, false);
OechsleInput.Text = "";
PriceInput.Text = "";
DisableUnitTextBox(PriceInput);
DisableActionButtons();
}
}
private (double, double, int)? MouseOnPlot(ScatterPlot? plot) {
if (plot == null) {
return null;
}
(double mouseCoordX, double mouseCoordY) = OechslePricePlot.GetMouseCoordinates();
(double mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel();
double xyRatio = OechslePricePlot.Plot.XAxis.Dims.PxPerUnit / OechslePricePlot.Plot.YAxis.Dims.PxPerUnit;
(double pointX, double pointY, int pointIndex) = plot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
(double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY);
if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) {
return (pointX, pointY, pointIndex);
} else {
return null;
}
}
private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) {
if (GraphList.SelectedItem == null) {
return;
}
(double mouseCoordX, double mouseCoordY) = OechslePricePlot.GetMouseCoordinates();
double xyRatio = OechslePricePlot.Plot.XAxis.Dims.PxPerUnit / OechslePricePlot.Plot.YAxis.Dims.PxPerUnit;
(double pointX, double pointY, int pointIndex) = OechslePricePlotScatter.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
(double x, double y, int index)? mouseOnData = MouseOnPlot(DataPlot);
(double x, double y , int index)? mouseOnGebunden = MouseOnPlot(GebundenPlot);
(double mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel();
(double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY);
Highlighted = LastHighlighted;
HighlightedIndex = LastHighlightedIndex;
if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) {
ChangeMarker(HighlightedPoint, true, pointX, pointY);
HighlightedPoint.IsVisible = true;
if (mouseOnData != null) {
ChangeMarker(HighlightedPointPlot, true, mouseOnData.Value.x, mouseOnData.Value.y);
HighlightedPointPlot.IsVisible = true;
HoverChanged = true ^ HoverActive;
HoverActive = true;
HandleTooltip(mouseOnData.Value.x, mouseOnData.Value.y, mouseOnData.Value.index, SelectedGraphEntry!.DataGraph);
} else if (mouseOnGebunden != null) {
ChangeMarker(HighlightedPointPlot, true, mouseOnGebunden.Value.x, mouseOnGebunden.Value.y);
HighlightedPointPlot.IsVisible = true;
HoverChanged = true ^ HoverActive;
HoverActive = true;
HandleTooltip(mouseOnGebunden.Value.x, mouseOnGebunden.Value.y, mouseOnGebunden.Value.index, SelectedGraphEntry!.GebundenGraph!);
} else {
ChangeMarker(HighlightedPoint, false);
HoverChanged= false ^ HoverActive;
HoverActive= false;
OechslePricePlot.Plot.Remove(Tooltip);
ChangeMarker(HighlightedPointPlot, false);
HoverChanged = false ^ HoverActive;
HoverActive = false;
OechslePricePlot.Plot.Remove(TooltipPlot);
OechslePricePlot.Render();
}
}
if (LastHighlightedIndex != HighlightedIndex || HoverChanged) {
OechslePricePlot.Plot.Remove(Tooltip);
private void HandleTooltip(double pointX, double pointY, int pointIndex, Graph g) {
if (LastHighlighted != Highlighted || HoverChanged) {
OechslePricePlot.Plot.Remove(TooltipPlot);
if (TooltipInput.IsChecked == true) {
Tooltip = OechslePricePlot.Plot.AddTooltip($"Oechsle: {pointX:N2}, Preis: {Math.Round(pointY, 4)})", pointX, pointY);
TooltipPlot = OechslePricePlot.Plot.AddTooltip($"Oechsle: {pointX:N2}, Preis: {Math.Round(pointY, 4)}€/kg)", pointX, pointY);
}
LastHighlightedIndex = pointIndex;
LastHighlighted = (g, pointIndex);
HoverChanged = false;
OechslePricePlot.Render();
}
}
private int getMaxGraphId() {
private int GetMaxGraphId() {
return GraphEntries.Count == 0 ? 0 : GraphEntries.Select(g => g.Id).Max();
}
private void AddButton_Click(object sender, RoutedEventArgs e) {
GraphEntry newGraphEntry = new(getMaxGraphId() + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle);
GraphEntry newGraphEntry = new(GetMaxGraphId() + 1, BillingData.CurveMode.Oe, MinOechsle, MaxOechsle);
GraphEntries.Add(newGraphEntry);
GraphList.Items.Refresh();
GraphList.SelectedItem = newGraphEntry;
@@ -438,7 +497,7 @@ namespace Elwig.Windows {
private void CopyButton_Click(object sender, RoutedEventArgs e) {
if (SelectedGraphEntry == null) return;
GraphEntry newGraphEntry = SelectedGraphEntry.Copy(getMaxGraphId() + 1);
GraphEntry newGraphEntry = SelectedGraphEntry.Copy(GetMaxGraphId() + 1);
GraphEntries.Add(newGraphEntry);
GraphList.Items.Refresh();
GraphList.SelectedItem = newGraphEntry;
@@ -457,12 +516,86 @@ namespace Elwig.Windows {
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e) {
//TODO SAVE
private async void SaveButton_Click(object sender, RoutedEventArgs e) {
await SaveGraphs();
}
private async Task SaveGraphs() {
var payment = new JsonObject();
var curves = new JsonArray();
foreach (var entry in GraphEntries) {
curves.Add(entry.ToJson());
foreach (var contract in entry.Contracts) {
payment[$"{contract.Variety?.SortId}/{contract.Attribute?.AttrId}"] = $"curve:{entry.Id}";
}
}
var data = new JsonObject {
["mode"] = "elwig",
["version"] = 1,
["payment"] = payment,
["curves"] = curves
};
MessageBox.Show(data.ToJsonString());
EntityEntry<PaymentVar>? tr = null;
try {
PaymentVar.Data = data.ToJsonString();
tr = Context.Update(PaymentVar);
await Context.SaveChangesAsync();
await App.HintContextChange();
} catch (Exception exc) {
if (tr != null) await tr.ReloadAsync();
var str = "Der Eintrag konnte nicht in der Datenbank gespeichert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Graph speichern", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void EnableUnitTextBox(UnitTextBox u) {
if (PaymentVar.TestVariant) {
u.IsEnabled = true;
u.TextBox.IsReadOnly = false;
}
}
private void DisableUnitTextBox(UnitTextBox u) {
u.IsEnabled = false;
u.TextBox.IsReadOnly = true;
}
private void ChangeActiveGraph(Graph? g) {
if (g != null && g == SelectedGraphEntry?.DataGraph) {
EnableUnitTextBox(OechsleInput);
ChangeLineWidth(DataPlot, 4);
ChangeLineWidth(GebundenPlot, 1);
} else if (g != null && g == SelectedGraphEntry?.GebundenGraph) {
EnableUnitTextBox(OechsleInput);
ChangeLineWidth(GebundenPlot, 4);
ChangeLineWidth(DataPlot, 1);
} else {
DisableUnitTextBox(OechsleInput);
DisableUnitTextBox(PriceInput);
OechsleInput.Text = "";
PriceInput.Text = "";
ChangeLineWidth(DataPlot, 1);
ChangeLineWidth(GebundenPlot, 1);
}
ActiveGraph = g;
}
private void ChangeLineWidth(ScatterPlot? p, double lineWidth) {
if (p != null) {
p.LineWidth = lineWidth;
}
}
private void GraphList_SelectionChanged(object sender, SelectionChangedEventArgs e) {
SelectedGraphEntry = (GraphEntry)GraphList.SelectedItem;
SelectedGraphEntry = GraphList.SelectedItem as GraphEntry;
RefreshInputs();
//var x = OechslePricePlot.Plot.GetPlottables().OfType<ScatterPlot>();
@@ -477,8 +610,41 @@ namespace Elwig.Windows {
}
private void GebundenBonus_TextChanged(object sender, TextChangedEventArgs evt) {
private void GebundenFlatBonus_TextChanged(object sender, TextChangedEventArgs e) {
var r = Validator.CheckDecimal(GebundenFlatBonus.TextBox, true, 2, 8);
if (r.IsValid) {
SelectedGraphEntry?.SetGebundenFlatBonus(decimal.Parse(GebundenFlatBonus.Text));
}
}
private void ContractInput_Changed(object sender, RoutedEventArgs e) {
var r = ContractInput.SelectedItems.Cast<ContractSelection>();
SelectedGraphEntry!.Contracts = r.ToList();
// FIXME when using arrow keys, selection does not work nicely
GraphList.Items.Refresh();
}
private void GebundenType_Checked(object sender, RoutedEventArgs e) {
if (SelectedGraphEntry == null) {
DisableUnitTextBox(GebundenFlatBonus);
return;
} else if (GebundenTypeNone.IsChecked == true) {
SelectedGraphEntry.SetGebundenFlatBonus(null);
SelectedGraphEntry.RemoveGebundenGraph();
DisableUnitTextBox(GebundenFlatBonus);
RefreshInputs();
} else if (GebundenTypeFixed.IsChecked == true) {
SelectedGraphEntry.SetGebundenFlatBonus(0);
SelectedGraphEntry.RemoveGebundenGraph();
EnableUnitTextBox(GebundenFlatBonus);
RefreshInputs();
} else if (GebundenTypeGraph.IsChecked == true) {
GebundenFlatBonus.Text = "";
SelectedGraphEntry.SetGebundenFlatBonus(null);
SelectedGraphEntry.AddGebundenGraph();
DisableUnitTextBox(GebundenFlatBonus);
RefreshInputs();
}
}
}
}
+3 -3
View File
@@ -148,21 +148,21 @@
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Sorte" Binding="{Binding SortIdString}" Width="50">
<DataGridTextColumn Header="Sorte" Binding="{Binding FilteredSortIdString}" Width="50">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg '}" Width="75">
<DataGridTextColumn Header="Gewicht" Binding="{Binding FilteredWeight, StringFormat='{}{0:N0} kg '}" Width="75">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Gradation" Binding="{Binding Kmw, StringFormat='{}{0:N1}° '}" Width="50">
<DataGridTextColumn Header="Gradation" Binding="{Binding FilteredKmw, StringFormat='{}{0:N1}° '}" Width="50">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
+36 -29
View File
@@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -168,7 +169,7 @@ namespace Elwig.Windows {
private async void Menu_Print_DeliveryJournal_ShowFilter_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting;
var (f, _, d, _) = await GetFilters();
var (f, _, d, _, _) = await GetFilters();
var doc = new DeliveryJournal(string.Join(" / ", f), d);
await doc.Generate();
Mouse.OverrideCursor = null;
@@ -177,7 +178,7 @@ namespace Elwig.Windows {
private async void Menu_Print_DeliveryJournal_PrintFilter_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting;
var (f, _, d, _) = await GetFilters();
var (f, _, d, _, _) = await GetFilters();
var doc = new DeliveryJournal(string.Join(" / ", f), d);
await doc.Generate();
Mouse.OverrideCursor = null;
@@ -296,7 +297,7 @@ namespace Elwig.Windows {
await RefreshDeliveryListQuery();
}
private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, List<string>)> GetFilters() {
private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, Predicate<DeliveryPart>, List<string>)> GetFilters() {
List<string> filterNames = [];
IQueryable<Delivery> deliveryQuery = Context.Deliveries;
if (IsReceipt && App.BranchNum > 1) {
@@ -316,12 +317,8 @@ namespace Elwig.Windows {
deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value);
filterNames.Add(SeasonInput.Value.ToString() ?? "");
}
IQueryable<DeliveryPart> dpq = deliveryQuery
.SelectMany(d => d.Parts)
.OrderBy(p => p.Delivery.DateString)
.ThenBy(p => p.Delivery.TimeString)
.ThenBy(p => p.Delivery.LsNr)
.ThenBy(p => p.DPNr);
Expression<Func<DeliveryPart, bool>> prd = p => true;
var filterVar = new List<string>();
var filterNotVar = new List<string>();
@@ -487,32 +484,32 @@ namespace Elwig.Windows {
}
}
if (filterYearGt > 0) dpq = dpq.Where(p => p.Year >= filterYearGt);
if (filterYearLt > 0) dpq = dpq.Where(p => p.Year < filterYearLt);
if (filterMgNr.Count > 0) dpq = dpq.Where(p => filterMgNr.Contains(p.Delivery.MgNr));
if (filterYearGt > 0) prd = prd.And(p => p.Year >= filterYearGt);
if (filterYearLt > 0) prd = prd.And(p => p.Year < filterYearLt);
if (filterMgNr.Count > 0) prd = prd.And(p => filterMgNr.Contains(p.Delivery.MgNr));
if (filterDate.Count > 0) {
var pr = PredicateBuilder.New<DeliveryPart>(false);
foreach (var (d1, d2) in filterDate)
pr.Or(p => (d1 == null || d1.CompareTo(p.Delivery.DateString.Substring(10 - d1.Length)) <= 0) && (d2 == null || d2.CompareTo(p.Delivery.DateString.Substring(10 - d2.Length)) >= 0));
dpq = dpq.Where(pr);
prd = prd.And(pr);
}
if (filterTime.Count > 0) {
var pr = PredicateBuilder.New<DeliveryPart>(false);
foreach (var (t1, t2) in filterTime)
pr.Or(p => (t1 == null || t1.CompareTo(p.Delivery.TimeString) <= 0) && (t2 == null || t2.CompareTo(p.Delivery.TimeString) > 0));
dpq = dpq.Where(p => p.Delivery.TimeString != null).Where(pr);
prd = prd.And(p => p.Delivery.TimeString != null).And(pr);
}
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 (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 (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 || !filterNotAttr.Contains(p.AttrId));
if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt);
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 (filterOeLt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt);
if (filterVar.Count > 0) prd = prd.And(p => filterVar.Contains(p.SortId));
if (filterNotVar.Count > 0) prd = prd.And(p => !filterNotVar.Contains(p.SortId));
if (filterQual.Count > 0) prd = prd.And(p => filterQual.Contains(p.QualId));
if (filterNotQual.Count > 0) prd = prd.And(p => !filterNotQual.Contains(p.QualId));
if (filterZwst.Count > 0) prd = prd.And(p => filterZwst.Contains(p.Delivery.ZwstId));
if (filterAttr.Count > 0) prd = prd.And(p => p.AttrId != null && filterAttr.Contains(p.AttrId));
if (filterNotAttr.Count > 0) prd = prd.And(p => p.AttrId == null || !filterNotAttr.Contains(p.AttrId));
if (filterKmwGt > 0) prd = prd.And(p => p.Kmw >= filterKmwGt);
if (filterKmwLt > 0) prd = prd.And(p => p.Kmw < filterKmwLt);
if (filterOeGt > 0) prd = prd.And(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt);
if (filterOeLt > 0) prd = prd.And(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt);
if (filterYearGt > 0 && filterYearLt > 0) {
filterNames.Insert(0, $"{filterYearGt}{filterYearLt - 1}");
@@ -537,7 +534,15 @@ namespace Elwig.Windows {
}
}
return (filterNames, dpq.Select(p => p.Delivery).Distinct().OrderBy(d => d.DateString).ThenBy(d => d.TimeString), dpq, filter);
IQueryable<DeliveryPart> dpq = deliveryQuery
.SelectMany(d => d.Parts)
.Where(prd)
.OrderBy(p => p.Delivery.DateString)
.ThenBy(p => p.Delivery.TimeString)
.ThenBy(p => p.Delivery.LsNr)
.ThenBy(p => p.DPNr);
return (filterNames, dpq.Select(p => p.Delivery).Distinct().OrderBy(d => d.DateString).ThenBy(d => d.TimeString), dpq, prd.Invoke, filter);
}
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
@@ -573,7 +578,7 @@ namespace Elwig.Windows {
}
private async Task RefreshDeliveryListQuery(bool updateSort = false) {
var (_, deliveryQuery, deliveryPartsQuery, filter) = await GetFilters();
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await GetFilters();
var deliveries = await deliveryQuery.ToListAsync();
deliveries.Reverse();
@@ -589,8 +594,10 @@ namespace Elwig.Windows {
.ToList();
}
deliveries.ForEach(d => { d.PartFilter = predicate; });
ControlUtils.RenewItemsSource(DeliveryList, deliveries, d => ((d as Delivery)?.Year, (d as Delivery)?.DId),
DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
await RefreshDeliveryParts();
var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList();
StatusMembers.Text = $"Mitglieder: {members.Count}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
@@ -760,7 +767,7 @@ namespace Elwig.Windows {
private async Task RefreshDeliveryParts() {
if (DeliveryList.SelectedItem is Delivery d) {
ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == d.Year).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId);
ControlUtils.RenewItemsSource(DeliveryPartList, d.Parts.OrderBy(p => p.DPNr).ToList(), i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId, (i as DeliveryPart)?.DPNr), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
ControlUtils.RenewItemsSource(DeliveryPartList, d.FilteredParts.OrderBy(p => p.DPNr).ToList(), i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId, (i as DeliveryPart)?.DPNr), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
} else {
ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == Utils.CurrentLastSeason).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId);
DeliveryPartList.ItemsSource = null;
@@ -1134,7 +1141,7 @@ namespace Elwig.Windows {
} else {
// switch to last delivery part
DeliveryPartList.IsEnabled = true;
DeliveryPartList.SelectedItem = d.Parts.Last();
DeliveryPartList.SelectedItem = d.FilteredParts.Last();
}
}
+1 -1
View File
@@ -13,7 +13,7 @@
<EmbeddedResource Include="Resources\*.sql" />
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Target Name="FetchResources" BeforeTargets="BeforeBuild">
<Exec Command="call fetch-resources.bat" />
</Target>