Compare commits

..

26 Commits

Author SHA1 Message Date
c933fa3423 Bump Version Number to 0.1.0 2023-09-04 02:13:50 +02:00
0958728418 BaseDataWindow: Add Season modifiers 2023-09-04 01:47:26 +02:00
cb8d405dcf Modifier: Nachkommastellen nach precision 2023-09-04 01:47:25 +02:00
6f4e3474b8 Add PaymentChartWindow 2023-09-04 00:52:18 +02:00
545622a2ab DeliveryNote: Fix forced page break 2023-09-03 01:21:46 +02:00
3a0736a73f AppDbContext: Fix UpdateDeliveryPart attributes and modifiers 2023-09-03 00:04:31 +02:00
048a7e0f13 DeliveryNote: Refine forced page break condition 2023-09-02 23:48:11 +02:00
cad475fc20 Windows: Set UstIdNrInput Width from 120 to 96 2023-09-02 22:25:44 +02:00
8b0f1e35c8 BaseDataWindow: implement client data saving 2023-09-02 22:23:12 +02:00
67dbf62eb7 DeliveryNote: Modifier names are now bold 2023-09-02 19:20:51 +02:00
9b59208373 ClientParameters: Fix parsing of VAT decimals 2023-09-01 17:30:05 +02:00
146560c796 Add BaseDataWindow 2023-09-01 17:21:29 +02:00
286e3515d4 Modifier: change Rel type from double to decimal 2023-09-01 17:18:52 +02:00
c1d3a9042d ClientParameters: remove NameShortened, add VAT 2023-09-01 17:09:59 +02:00
e656bde54d MemberAdminWindow: Small code cleanup 2023-09-01 17:02:29 +02:00
33d763d968 AdministrationWindow: finally fix boolean changing error 2023-09-01 13:11:42 +02:00
56a0eb794e AdministrationWindow: Fix default value change check 2023-09-01 12:57:09 +02:00
effc9f9230 Update DELIVERY_NOTE_TEXT to TEXT_DELIVERY_NOTE 2023-08-31 23:36:11 +02:00
4817a2aedc Fix CheckBox original value change check 2023-08-31 22:30:23 +02:00
b67628c566 Add Helpers.Billing 2023-08-31 10:24:15 +02:00
5aa8e45652 AdministrationWindow: Fix default value handling 2023-08-30 14:54:16 +02:00
1f377483a5 AdministrationWindow: Fix LostFocus Focus issue 2023-08-30 14:24:45 +02:00
9b84452b86 Add Gesamtlieferung to DeliveryNote 2023-08-30 14:18:43 +02:00
75e6c1bd5d MemberAdminWindow: Add Deceased Input 2023-08-29 17:13:20 +02:00
a96a05d3de Add Helpers/Export/ 2023-08-29 15:25:43 +02:00
3f09e62c74 Update Dependencies 2023-08-29 15:22:26 +02:00
35 changed files with 2331 additions and 111 deletions

View File

@@ -0,0 +1,53 @@
<Window x:Class="Elwig.Dialogs.LinearPriceIncreaseDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Elwig.Dialogs"
mc:Ignorable="d"
ResizeMode="NoResize"
ShowInTaskbar="False"
Topmost="True"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=PriceInput}"
Title="Linear wachsen" Height="140" Width="270">
<Window.Resources>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Padding" Value="2,4,2,4"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Height" Value="25"/>
<Setter Property="TextWrapping" Value="NoWrap"/>
</Style>
<Style TargetType="Button">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="25"/>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="55"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="Preis:" Margin="10,20,10,10"/>
<Grid Grid.Column="1" Width="145" Height="25" Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBox x:Name="PriceInput" TextAlignment="Right" Padding="2,2,30,2"
TextChanged="PriceInput_TextChanged"/>
<Label Content="€/kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10" Padding="2,4,2,4"/>
</Grid>
<Button x:Name="ConfirmButton" Content="Bestätigen" Margin="17,0,133,10" IsEnabled="False" IsDefault="True"
Click="ConfirmButton_Click" Grid.ColumnSpan="2" HorizontalAlignment="Stretch"/>
<Button x:Name="CancelButton" Content="Abbrechen" Margin="0,0,20,10" Grid.Column="1" IsCancel="True"/>
</Grid>
</Window>

View File

@@ -0,0 +1,30 @@
using Elwig.Helpers;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
namespace Elwig.Dialogs {
public partial class LinearPriceIncreaseDialog : Window {
public double Price = 0.0;
public LinearPriceIncreaseDialog() {
InitializeComponent();
}
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
DialogResult = true;
Price = double.Parse(PriceInput.Text.Replace("\u202f", ""));
Close();
}
private void UpdateButtons(ValidationResult res) {
ConfirmButton.IsEnabled = res.IsValid;
}
private void PriceInput_TextChanged(object sender, TextChangedEventArgs evt) {
var res = Validator.CheckDecimal(PriceInput, true, 2, 8);
UpdateButtons(res);
}
}
}

View File

@@ -5,16 +5,33 @@
<div class="date">@Model.Location, am @($"{Model.Date:dd.MM.yyyy}")</div>
<h1>@Model.Title</h1>
@{ var forcePageBreak = Model.Delivery.Parts.Count > 2; }
@if (forcePageBreak) {
<p>Siehe nächste Seite.</p>
if (Model.Delivery.Year == Model.CurrentNextSeason) {
<!-- TODO Gesamtlieferung -->
<p>Gesamtlieferung usw.</p>
<p>Flächenbindung-Lieferrecht/-pflicht usw.</p>
}
<hr class="page-break"/>
@{
bool displayStats = true; // Model.Delivery.Year == Model.CurrentNextSeason
}
<script>
document.addEventListener("DOMContentLoaded", () => {
const hidden = document.getElementsByClassName("hidden")[0];
const bottom = hidden.offsetTop + hidden.offsetHeight;
const cm = bottom * 2.54 / 96 * window.devicePixelRatio;
if (cm > 25.75) {
// force page break
const table = document.getElementsByClassName("delivery")[0];
const hr = document.createElement("hr");
hr.classList.add("page-break");
table.before(hr);
const stats = document.getElementById("delivery-stats");
stats.getElementsByTagName("table")[0].classList.add("expanded");
hr.before(stats);
const p = document.createElement("p");
p.innerText = "Siehe nächste Seite."
stats.before(p);
}
});
</script>
<table class="delivery">
<colgroup>
<col style="width: 1cm;"/>
@@ -57,7 +74,7 @@
@if (part.Modifiers.Count() > 0) {
var first = true;
foreach (var mod in part.Modifiers) {
<tr class="tight @(first ? "first" : "")"><td></td><td>@Raw(first ? "<i>Zu-/Abschläge:</i>" : "")</td><td colspan="3">@mod.Name</td><td style="white-space: pre;">@mod.ValueStr</td></tr>
<tr class="tight @(first ? "first" : "")"><td></td><td>@Raw(first ? "<i>Zu-/Abschläge:</i>" : "")</td><td colspan="3"><b>@mod.Name</b></td><td style="white-space: pre;">@mod.ValueStr</td></tr>
first = false;
}
}
@@ -84,8 +101,56 @@
@if (Model.Delivery.Comment != null) {
<p class="comment">Amerkung zur Lieferung: @Model.Delivery.Comment</p>
}
@if (!forcePageBreak && Model.Delivery.Year == Model.CurrentNextSeason) {
<p>Gesamtlieferung usw.</p>
@if (displayStats) {
<div id="delivery-stats">
<table class="delivery-stats">
<colgroup>
<col style="width: 100%;"/>
<col style="width: 2cm;"/>
<col style="width: 2cm;"/>
<col style="width: 2cm;"/>
<col style="width: 2cm;"/>
<col style="width: 2cm;"/>
<col style="width: 2cm;"/>
</colgroup>
<thead>
<tr>
<th><b>Gesamtlieferung</b> [kg]</th>
<th>Lieferpflicht</th>
<th>Lieferrecht</th>
<th>Unterliefert</th>
<th>Noch zu liefern</th>
<th>Überliefert</th>
<th>Geliefert</th>
</tr>
</thead>
<tbody>
@{
string FormatRow(int obligation, int right, int sum) {
return $"<td>{obligation:N0}</td>" +
$"<td>{right:N0}</td>" +
$"<td>{(sum < obligation ? $"{obligation - sum:N0}" : "-")}</td>" +
$"<td>{(sum >= obligation && sum <= right ? $"{right - sum:N0}" : "-")}</td>" +
$"<td>{(sum > right ? $"{sum - right:N0}" : "-")}</td>" +
$"<td>{sum:N0}</td>";
}
var sortids = Model.Delivery.Parts.Select(p => p.SortId).ToList();
}
<tr>
<th>Geschäftsanteile</th>
@Raw(FormatRow(Model.Member.DeliveryObligation, Model.Member.DeliveryRight, Model.Member.Deliveries.Where(d => d.Year == Model.Delivery.Year).Sum(d => d.Weight)))
</tr>
@foreach (var (id, name, right, obligation, sum) in Model.MemberBuckets.OrderBy(b => b.Item1)) {
if (right > 0 && obligation > 0) {
<tr class="@(sortids.Contains(id[..2]) ? "" : "optional")">
<th>@name</th>
@Raw(FormatRow(obligation, right, sum))
</tr>
}
}
</tbody>
</table>
</div>
}
@for (int i = 0; i < 2; i++) {
<div class="@(i == 0 ? "hidden" : "bottom")">

View File

@@ -1,12 +1,15 @@
using Elwig.Helpers;
using Elwig.Models;
using System.Collections.Generic;
namespace Elwig.Documents {
public class DeliveryNote : BusinessDocument {
public Delivery Delivery;
public string? Text;
public IEnumerable<(string, string, int, int, int)> MemberBuckets;
public DeliveryNote(Delivery d) : base($"Traubenübernahmeschein Nr. {d.LsNr}", d.Member) {
public DeliveryNote(Delivery d, AppDbContext ctx) : base($"Traubenübernahmeschein Nr. {d.LsNr}", d.Member) {
Delivery = d;
Aside = Aside.Replace("</table>", "") +
$"<thead><tr><th colspan='2'>Lieferung</th></tr></thead><tbody>" +
@@ -14,8 +17,9 @@ namespace Elwig.Documents {
$"<tr><th>Datum/Zeit</th><td>{d.Date:dd.MM.yyyy} / {d.Time:HH:mm}</td></tr>" +
$"<tr><th>Zweigstelle</th><td>{d.Branch.Name}</td></tr>" +
$"</tbody></table>";
Text = App.Client.DeliveryNoteText;
Text = App.Client.TextDeliveryNote;
DocumentId = d.LsNr;
MemberBuckets = ctx.GetMemberBuckets(d.Member, d.Year).GetAwaiter().GetResult();
}
}
}

View File

@@ -206,7 +206,7 @@ table {
}
table.delivery {
margin-bottom: 1cm;
margin-bottom: 5mm;
}
table.delivery th {
@@ -249,6 +249,48 @@ table.delivery tr.sum td {
padding-top: 1mm;
}
table.delivery-stats {
font-size: 8pt;
}
table.delivery-stats.expanded th,
table.delivery-stats.expanded td {
padding: 0.25mm 0;
}
table.delivery-stats:not(.expanded) th,
table.delivery-stats:not(.expanded) td {
padding: 0.125mm 0;
}
table.delivery-stats:not(.expanded) tr.optional {
display: none;
}
table.delivery-stats thead th {
font-weight: normal;
font-style: italic;
text-align: right;
}
table.delivery-stats thead th:first-child {
text-align: left;
}
table.delivery-stats.expanded tbody {
font-size: 10pt;
}
table.delivery-stats td {
text-align: right;
}
table.delivery-stats tbody th {
font-weight: normal;
font-style: italic;
text-align: left;
}
.hidden {
visibility: hidden;
}

View File

@@ -7,7 +7,7 @@
<UseWPF>true</UseWPF>
<PreserveCompilationContext>true</PreserveCompilationContext>
<ApplicationIcon>elwig.ico</ApplicationIcon>
<Version>0.0.1</Version>
<Version>0.1.0</Version>
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
</PropertyGroup>
@@ -21,10 +21,11 @@
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.21" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1901.177" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1938.49" />
<PackageReference Include="PdfSharp" Version="1.50.5147" />
<PackageReference Include="PuppeteerSharp" Version="11.0.2" />
<PackageReference Include="RazorLight" Version="2.3.1" />
<PackageReference Include="ScottPlot.WPF" Version="4.1.67" />
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
</ItemGroup>

View File

@@ -42,6 +42,7 @@ namespace Elwig.Helpers {
public DbSet<DeliveryPart> DeliveryParts { get; private set; }
public DbSet<DeliveryPartAttr> DeliveryPartAttributes { get; private set; }
public DbSet<DeliveryPartModifier> DeliveryPartModifiers { get; private set; }
public DbSet<PaymentVar> PaymentVariants { get; private set; }
private readonly StreamWriter? LogFile = null;
public static DateTime LastWriteTime => File.GetLastWriteTime(App.Config.DatabaseFile);
@@ -119,7 +120,7 @@ namespace Elwig.Helpers {
public async Task<int> NextMgNr() {
int c = await Members.Select(m => m.MgNr).MinAsync();
(await Members.OrderBy(m => m.MgNr).Select(m => m.MgNr).ToListAsync())
.ForEach(a => { if (a <= c + 100) c = a; });
.ForEach(a => { if (a <= c + 1000) c = a; });
return c + 1;
}
@@ -134,21 +135,21 @@ namespace Elwig.Helpers {
var dateStr = date.ToString("yyyy-MM-dd");
int c = 0;
(await Deliveries.Where(d => d.DateString == dateStr).Select(d => d.LNr).ToListAsync())
.ForEach(a => { if (a <= c + 10) c = a; });
.ForEach(a => { if (a <= c + 100) c = a; });
return c + 1;
}
public async Task<int> NextDId(int year) {
int c = 0;
(await Deliveries.Where(d => d.Year == year).Select(d => d.DId).ToListAsync())
.ForEach(a => { if (a <= c + 10) c = a; });
.ForEach(a => { if (a <= c + 100) c = a; });
return c + 1;
}
public async Task<int> NextDPNr(int year, int did) {
int c = 0;
(await DeliveryParts.Where(p => p.Year == year && p.DId == did).Select(d => d.DPNr).ToListAsync())
.ForEach(a => { if (a <= c + 10) c = a; });
.ForEach(a => { if (a <= c + 100) c = a; });
return c + 1;
}
@@ -160,7 +161,7 @@ namespace Elwig.Helpers {
}
public async Task UpdateDeliveryPartAttributes(DeliveryPart part, IEnumerable<WineAttr> attributes) {
foreach (var a in attributes) {
foreach (var a in WineAttributes) {
var attr = part.PartAttributes.Where(pa => pa.AttrId == a.AttrId).FirstOrDefault();
if (attributes.Contains(a)) {
DeliveryPartAttr dpa = attr ?? this.CreateProxy<DeliveryPartAttr>();
@@ -182,7 +183,7 @@ namespace Elwig.Helpers {
}
public async Task UpdateDeliveryPartModifiers(DeliveryPart part, IEnumerable<Modifier> modifiers) {
foreach (var m in modifiers) {
foreach (var m in Modifiers.Where(m => m.Year == part.Year)) {
var mod = part.PartModifiers.Where(pa => pa.ModId == m.ModId).FirstOrDefault();
if (modifiers.Contains(m)) {
DeliveryPartModifier dpm = mod ?? this.CreateProxy<DeliveryPartModifier>();
@@ -202,5 +203,27 @@ namespace Elwig.Helpers {
}
}
}
public async Task<IEnumerable<(string, string, int, int, int)>> GetMemberBuckets(Member m, int year) {
using var cnx = await ConnectAsync();
var (rights, obligations) = await Billing.Billing.GetMemberRightsObligations(m.MgNr, year, cnx);
var buckets = await Billing.Billing.GetMemberBucketWeights(m.MgNr, year, cnx);
var list = new List<(string, string, int, int, int)>();
foreach (var id in rights.Keys.Union(obligations.Keys).Union(buckets.Keys)) {
var s = await WineVarieties.FindAsync(id[..2]);
var attrIds = id[2..];
var a = await WineAttributes.Where(a => attrIds.Contains(a.AttrId)).ToListAsync();
var name = (s?.Name ?? "") + (a.Count > 0 ? $" ({string.Join(" / ", a.Select(a => a.Name))})" : "");
list.Add((
id, name,
rights.TryGetValue(id, out var v1) ? v1 : 0,
obligations.TryGetValue(id, out var v2) ? v2 : 0,
buckets.TryGetValue(id, out var v3) ? v3 : 0
));
}
return list;
}
}
}

View File

@@ -0,0 +1,130 @@
using Microsoft.Data.Sqlite;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Elwig.Helpers.Billing {
public class Billing {
private readonly int Year;
private readonly int AvNr;
private readonly AppDbContext Context;
private readonly Dictionary<string, string> Attributes;
private readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
private readonly Dictionary<string, (string, string?, string?, string?, int?, int?, decimal?)> AreaComTypes;
public Billing(int year, int avnr) {
Year = year;
AvNr = avnr;
Context = new AppDbContext();
Attributes = Context.WineAttributes.ToDictionary(a => a.AttrId, a => a.Name);
Modifiers = Context.Modifiers.Where(m => m.Year == Year).ToDictionary(m => m.ModId, m => (m.Abs, m.Rel));
AreaComTypes = Context.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId1, v.AttrId2, v.Discriminator, v.MinKgPerHa, v.MaxKgPerHa, v.PenaltyAmount));
}
protected async Task DeleteInDb() {
using var cnx = await AppDbContext.ConnectAsync();
using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"DELETE FROM payment_delivery_part WHERE (year, avnr) = ({Year}, {AvNr})";
await cmd.ExecuteNonQueryAsync();
}
using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"DELETE FROM payment_member WHERE (year, avnr) = ({Year}, {AvNr})";
await cmd.ExecuteNonQueryAsync();
}
}
public async Task Calculate() {
await DeleteInDb();
var tasks = new List<Task>();
foreach (var mgnr in Context.Members.Select(m => m.MgNr)) {
tasks.Add(Task.Run(() => CalculateMember(mgnr)));
}
await Task.WhenAll(tasks);
}
public static async Task<(Dictionary<string, int>, Dictionary<string, int>)> GetMemberRightsObligations(int mgnr, int year, SqliteConnection cnx) {
var rights = new Dictionary<string, int>();
var obligations = new Dictionary<string, int>();
using var cmd = cnx.CreateCommand();
cmd.CommandText = $"""
SELECT t.vtrgid,
SUM(COALESCE(area * min_kg_per_ha, 0)) / 10000 AS min_kg,
SUM(COALESCE(area * max_kg_per_ha, 0)) / 10000 AS max_kg
FROM area_commitment c
JOIN area_commitment_type t ON t.vtrgid = c.vtrgid
WHERE mgnr = {mgnr} AND (year_from IS NULL OR year_from <= {year}) AND (year_to IS NULL OR year_to >= {year})
GROUP BY t.vtrgid
ORDER BY LENGTH(t.vtrgid) DESC, t.vtrgid
""";
var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) {
var vtrgid = reader.GetString(0);
obligations[vtrgid] = reader.GetInt32(1);
rights[vtrgid] = reader.GetInt32(2);
}
return (rights, obligations);
}
public static async Task<Dictionary<string, int>> GetMemberBucketWeights(int mgnr, int year, SqliteConnection cnx) {
var buckets = new Dictionary<string, int>();
using var cmd = cnx.CreateCommand();
cmd.CommandText = $"""
SELECT bucket, weight
FROM v_bucket
WHERE (year, mgnr) = ({year}, {mgnr})
""";
var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) {
var bucket = reader.GetString(0);
buckets[bucket] = reader.GetInt32(1);
}
return buckets;
}
protected async Task CalculateMember(int mgnr) {
using var cnx = await AppDbContext.ConnectAsync();
var (rights, obligations) = await GetMemberRightsObligations(mgnr, Year, cnx);
var deliveries = new List<(int, int, string, int, double, string, string[], string[])>();
using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"""
SELECT did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers
FROM v_delivery
WHERE (year, mgnr) = ({Year}, {mgnr})
ORDER BY kmw DESC, weight DESC, did, dpnr
""";
var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) {
deliveries.Add((
reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2), reader.GetInt32(3),
reader.GetDouble(4), reader.GetString(5), reader.GetString(6).Split(","), reader.GetString(7).Split(",")
));
}
}
foreach (var (did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers) in deliveries) {
if (qualid == "WEI" || qualid == "RSW" || qualid == "LDW") {
// Nicht mindestens Qualitätswein (QUW)
using var cmd = cnx.CreateCommand();
// TODO
cmd.CommandText = $"""
INSERT INTO payment_delivery_part (year, did, dpnr, avnr, mod_abs, mod_rel, )
VALUES ({Year}, {did}, {dpnr}, {AvNr}, )
""";
await cmd.ExecuteNonQueryAsync();
continue;
}
// TODO
}
}
}
}

View File

@@ -1,6 +1,8 @@
using Elwig.Models;
using Microsoft.Data.Sqlite;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Elwig.Helpers {
public class ClientParameters {
@@ -12,7 +14,6 @@ namespace Elwig.Helpers {
public string NameToken;
public string NameShort;
public string NameShortened;
public string Name;
public string? NameSuffix;
public string NameType;
@@ -25,8 +26,8 @@ namespace Elwig.Helpers {
Ort = value.AtPlz.Ort.Name;
}
}
public int Plz { get; private set; }
public string Ort { get; private set; }
public int Plz;
public string Ort;
public string Address;
public string Sender1 => $"{NameShort} | {Address} | {Plz} {Ort}";
public string Sender2;
@@ -43,8 +44,11 @@ namespace Elwig.Helpers {
public int DeliveryObligation;
public int DeliveryRight;
public decimal VatNormal;
public decimal VatReduced;
public decimal VatFlatRate;
public string? DeliveryNoteText;
public string? TextDeliveryNote;
public ClientParameters(AppDbContext ctx) : this(ctx.ClientParameters.ToDictionary(e => e.Param, e => e.Value)) { }
@@ -53,7 +57,6 @@ namespace Elwig.Helpers {
NameToken = parameters["CLIENT_NAME_TOKEN"] ?? throw new KeyNotFoundException();
NameShort = parameters["CLIENT_NAME_SHORT"] ?? throw new KeyNotFoundException();
Name = parameters["CLIENT_NAME"] ?? throw new KeyNotFoundException();
NameShortened = parameters["CLIENT_NAME_SHORTENED"] ?? Name;
NameSuffix = parameters.GetValueOrDefault("CLIENT_NAME_SUFFIX");
NameType = parameters["CLIENT_NAME_TYPE"] ?? throw new KeyNotFoundException();
switch (Name) {
@@ -72,15 +75,65 @@ namespace Elwig.Helpers {
UstIdNr = parameters.GetValueOrDefault("CLIENT_USTIDNR");
Bic = parameters.GetValueOrDefault("CLIENT_BIC");
Iban = parameters.GetValueOrDefault("CLIENT_IBAN");
Sender2 = parameters.GetValueOrDefault("DOCUMENT_SENDER") ?? "";
DeliveryObligation = int.Parse(parameters["DELIVERY_OBLIGATION"] ?? "");
DeliveryRight = int.Parse(parameters["DELIVERY_RIGHT"] ?? "");
VatNormal = decimal.Parse((parameters["VAT_NORMAL"] ?? "").Replace(".", ","));
VatReduced = decimal.Parse((parameters["VAT_REDUCED"] ?? "").Replace(".", ","));
VatFlatRate = decimal.Parse((parameters["VAT_FLATRATE"] ?? "").Replace(".", ","));
DeliveryNoteText = parameters.GetValueOrDefault("DELIVERY_NOTE_TEXT");
Sender2 = parameters.GetValueOrDefault("DOCUMENT_SENDER") ?? "";
TextDeliveryNote = parameters.GetValueOrDefault("TEXT_DELIVERYNOTE");
} catch {
throw new KeyNotFoundException();
}
}
private IEnumerable<(string, string?)> GetParamValues() {
return new (string, string?)[] {
("CLIENT_NAME_TOKEN", NameToken),
("CLIENT_NAME_SHORT", NameShort),
("CLIENT_NAME", Name),
("CLIENT_NAME_SUFFIX", NameSuffix),
("CLIENT_NAME_TYPE", NameType),
("CLIENT_PLZ", Plz.ToString()),
("CLIENT_ORT", Ort),
("CLIENT_ADDRESS", Address),
("CLIENT_PHONE", PhoneNr),
("CLIENT_FAX", FaxNr),
("CLIENT_EMAIL", EmailAddress),
("CLIENT_WEBSITE", Website),
("CLIENT_LFBISNR", LfbisNr),
("CLIENT_USTIDNR", UstIdNr),
("CLIENT_BIC", Bic),
("CLIENT_IBAN", Iban),
("DELIVERY_OBLIGATION", DeliveryObligation.ToString()),
("DELIVERY_RIGHT", DeliveryRight.ToString()),
("VAT_NORMAL", VatNormal.ToString().Replace(",", ".")),
("VAT_REDUCED", VatReduced.ToString().Replace(",", ".")),
("VAT_FLATRATE", VatFlatRate.ToString().Replace(",", ".")),
("DOCUMENT_SENDER", Sender2),
("TEXT_DELIVERYNOTE", TextDeliveryNote),
};
}
public async Task UpdateValues() {
using var cnx = await AppDbContext.ConnectAsync();
using var cmd = cnx.CreateCommand();
var pv = GetParamValues();
cmd.CommandText = "INSERT INTO client_parameter (param, value) VALUES " +
string.Join(", ", pv.Select((pv, i) => $"(@p{i}, " + (pv.Item2 != null ? $"@v{i}" : "NULL") + ")")) +
" ON CONFLICT DO UPDATE SET value = excluded.value";
int i = 0;
foreach (var (p, v) in pv) {
cmd.Parameters.Add(new SqliteParameter($"@p{i}", p));
if (v != null)
cmd.Parameters.Add(new SqliteParameter($"@v{i}", v));
i++;
}
await cmd.ExecuteNonQueryAsync();
}
}
}

View File

@@ -203,5 +203,21 @@ namespace Elwig.Helpers {
public static void SelectCheckComboBoxItems(Xceed.Wpf.Toolkit.CheckComboBox ccb, IEnumerable<object>? items, Func<object?, object?> getId) {
SelectCheckComboBoxItems(ccb, getId, items?.Select(i => getId(i)));
}
public static object? GetInputValue(Control input) {
if (input is TextBox tb) {
return tb.Text;
} else if (input is ComboBox sb) {
return sb.SelectedItem;
} else if (input is Xceed.Wpf.Toolkit.CheckComboBox ccb) {
return ccb.SelectedItems.Cast<object>().ToArray();
} else if (input is CheckBox cb) {
return cb.IsChecked?.ToString();
} else if (input is RadioButton rb) {
return rb.IsChecked?.ToString();
} else {
return null;
}
}
}
}

View File

@@ -0,0 +1,4 @@
namespace Elwig.Helpers.Export {
public class Bki {
}
}

View File

@@ -0,0 +1,4 @@
namespace Elwig.Helpers.Export {
public class Csv {
}
}

View File

@@ -0,0 +1,15 @@
using Elwig.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public class Ebics : IBankingProvider {
public string FileExtension => "xml";
public Task Export(string filename, int avnr, IEnumerable<Member> members) {
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,15 @@
using Elwig.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public class Elba : IBankingProvider {
public string FileExtension => "elba";
public Task Export(string filename, int avnr, IEnumerable<Member> members) {
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,24 @@
using Elwig.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
/// <summary>
/// Interface for exporting banking data
/// </summary>
public interface IBankingProvider {
/// <summary>
/// The default file extension of the exported files to be used (whithout a preceding ".")
/// </summary>
string FileExtension { get; }
/// <summary>
/// Export the member payment data of the given payment variant to the given file.
/// (The amount of the last payed variant is deducted from the calculated amount.)
/// </summary>
/// <param name="filename">The file to export the data to</param>
/// <param name="avnr">The number of the payment variant to export</param>
/// <param name="members">The members whose data to include in the export</param>
Task Export(string filename, int avnr, IEnumerable<Member> members);
}
}

View File

@@ -223,6 +223,11 @@ namespace Elwig.Helpers {
return d.ShowDialog() == true ? d.Weight : null;
}
public static double? ShowLinearPriceIncreaseDialog() {
var d = new LinearPriceIncreaseDialog();
return d.ShowDialog() == true ? d.Price : null;
}
public static string? ShowDeliveryExtractionDialog(string lsnr, string name, bool single, IEnumerable<string> lsnrs) {
var d = new DeliveryExtractionDialog(lsnr, name, single, lsnrs);
return d.ShowDialog() == true ? d.AddTo : null;

123
Elwig/Models/Graph.cs Normal file
View File

@@ -0,0 +1,123 @@
using Newtonsoft.Json.Linq;
using ScottPlot;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
namespace Elwig.Models {
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[] DataY { get; set; }
public Graph(int num, int minX, int maxX) {
Type = "oe";
Num = num;
Contracts = "";
MinX = minX;
MaxX = maxX;
DataX = DataGen.Range(MinX, MaxX + 1);
DataY = DataGen.Zeros(MaxX - MinX + 1);
}
public Graph(string type, int num, JToken graphData, string contracts, int minX, int maxX) {
Type = type;
Num = num;
Contracts = contracts;
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) {
Type = type;
Num = num;
MinX = minX;
MaxX = maxX;
Contracts = contracts;
DataX = dataX;
DataY = dataY;
}
private void ParseGraphData(JToken graphData) {
var GraphPoints = graphData.Children().OfType<JProperty>().ToDictionary(p => int.Parse(p.Name[..^2]), p => (double)p.Value);
if (GraphPoints.Keys.Count < 1) {
return;
}
var minKey = GraphPoints.Keys.Order().First();
var maxKey = GraphPoints.Keys.OrderDescending().First();
if (!GraphPoints.ContainsKey(MinX)) {
GraphPoints.Add(MinX, GraphPoints.GetValueOrDefault(minKey));
}
if (!GraphPoints.ContainsKey(MaxX)) {
GraphPoints.Add(MaxX, GraphPoints.GetValueOrDefault(maxKey));
}
var keys = GraphPoints.Keys.Order().ToArray();
for (int i = 0; i < keys.Length; i++) {
double point1Value = GraphPoints[keys[i]];
if (i + 1 < keys.Length) {
double point2Value = GraphPoints[keys[i + 1]];
if (point1Value == point2Value) {
for (int j = keys[i] - MinX; j < keys[i + 1] - MinX; j++) {
DataY[j] = point1Value;
}
} else {
int steps = Math.Abs(keys[i + 1] - keys[i]);
double step = (point2Value - point1Value) / steps;
DataY[keys[i] - MinX] = point1Value;
DataY[keys[i + 1] - MinX] = point2Value;
for (int j = keys[i] - MinX; j < keys[i + 1] - MinX - 1; j++) {
DataY[j + 1] = Math.Round(DataY[j] + step, 4); // TODO richtig runden
}
}
}
else {
for (int j = keys[i] - MinX; j < DataX.Length; j++) {
DataY[j] = point1Value;
}
}
}
}
public JObject ToJson() {
JObject graph = new();
if (DataY[0] != DataY[1]) {
graph.Add(new JProperty(DataX[0] + Type.ToLower(), Math.Round(DataY[0], 4)));
}
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)) {
graph.Add(new JProperty(DataX[i] + Type.ToLower(), Math.Round(DataY[i], 4)));
}
}
if (DataY[^1] != DataY[^2]) {
graph.Add(new JProperty(DataX[^1] + Type.ToLower(), Math.Round(DataY[^1], 4)));
}
return graph;
}
public object Clone() {
return new Graph(Type, Num, MinX, MaxX, Contracts, (double[])DataX.Clone(), (double[])DataY.Clone());
}
}
}

View File

@@ -176,6 +176,9 @@ namespace Elwig.Models {
public string FullAddress => $"{Address}, {PostalDest.AtPlz.Plz} {PostalDest.AtPlz.Ort.Name}";
public int DeliveryRight => BusinessShares * App.Client.DeliveryRight;
public int DeliveryObligation => BusinessShares * App.Client.DeliveryObligation;
public int SearchScore(IEnumerable<string> keywords) {
return Utils.GetSearchScore(new string?[] {
MgNr.ToString(),

View File

@@ -2,6 +2,7 @@ using Elwig.Helpers;
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace Elwig.Models {
[Table("modifier"), PrimaryKey("Year", "ModId")]
@@ -23,16 +24,18 @@ namespace Elwig.Models {
[NotMapped]
public decimal? Abs {
get {
return AbsValue != null ? Season.DecFromDb(AbsValue.Value) : null;
}
set {
AbsValue = value != null ? Season.DecToDb(value.Value) : null;
}
get => AbsValue != null ? Season.DecFromDb(AbsValue.Value) : null;
set => AbsValue = value != null ? Season.DecToDb(value.Value) : null;
}
[Column("rel")]
public double? Rel { get; set; }
public double? RelValue { get; set; }
[NotMapped]
public decimal? Rel {
get => (decimal?)RelValue;
set => RelValue = (double?)value;
}
[Column("standard")]
public bool IsStandard { get; set; }
@@ -44,8 +47,8 @@ namespace Elwig.Models {
public virtual Season Season { get; private set; }
public string ValueStr =>
(Abs != null) ? $"{Utils.GetSign(Abs.Value)}{Math.Abs(Abs.Value)}\u00a0{Season.Currency.Symbol}/kg" :
(Rel != null) ? $"{Utils.GetSign(Rel.Value)}{(Math.Abs(Rel.Value) < 0.1 ? "\u2007" : "")}{Math.Abs(Rel.Value):0.00##\u00a0%}" :
(Abs != null) ? $"{Utils.GetSign(Abs.Value)}{Math.Abs(Abs.Value).ToString("0." + string.Concat(Enumerable.Repeat('0', Season.Precision)))}\u00a0{Season.Currency.Symbol}/kg" :
(Rel != null) ? $"{Utils.GetSign(Rel.Value)}{(Math.Abs(Rel.Value) < 0.1m ? "\u2007" : "")}{Math.Abs(Rel.Value):0.00##\u00a0%}" :
"";
public override string ToString() {

View File

@@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace Elwig.Models {
[Table("payment_variant"), PrimaryKey("Year", "AvNr")]
public class PaymentVar {
[Column("year")]
public int Year { get; set; }
[Column("avnr")]
public int AvNr { get; set; }
[Column("name")]
public string Name { get; set; }
[Column("date")]
public string DateString { get; set; }
[NotMapped]
public DateOnly Date {
get {
return DateOnly.ParseExact(DateString, "yyyy-MM-dd");
}
set {
DateString = value.ToString("yyyy-MM-dd");
}
}
[Column("test_variant")]
public bool TestVariant { get; set; }
[Column("calc_time")]
public int? CalcTime { get; set; }
[Column("bucket_1_name")]
public string? Bucket1Name { get; set; }
[Column("bucket_2_name")]
public string? Bucket2Name { get; set; }
[Column("bucket_3_name")]
public string? Bucket3Name { get; set; }
[Column("bucket_4_name")]
public string? Bucket4Name { get; set; }
[Column("bucket_5_name")]
public string? Bucket5Name { get; set; }
[Column("bucket_6_name")]
public string? Bucket6Name { get; set; }
[Column("bucket_7_name")]
public string? Bucket7Name { get; set; }
[Column("bucket_8_name")]
public string? Bucket8Name { get; set; }
[Column("bucket_9_name")]
public string? Bucket9Name { get; set; }
[Column("comment")]
public string? Comment { get; set; }
[Column("data")]
public string Data { get; set; }
}
}

View File

@@ -149,10 +149,8 @@ namespace Elwig.Windows {
}
protected void LockInputs() {
foreach (var tb in TextBoxInputs) {
foreach (var tb in TextBoxInputs)
tb.IsReadOnly = true;
tb.Focusable = false;
}
foreach (var cb in ComboBoxInputs)
cb.IsEnabled = false;
foreach (var ccb in CheckComboBoxInputs)
@@ -164,10 +162,8 @@ namespace Elwig.Windows {
}
protected void UnlockInputs() {
foreach (var tb in TextBoxInputs) {
foreach (var tb in TextBoxInputs)
tb.IsReadOnly = false;
tb.Focusable = true;
}
foreach (var cb in ComboBoxInputs)
cb.IsEnabled = true;
foreach (var ccb in CheckComboBoxInputs)
@@ -194,13 +190,13 @@ namespace Elwig.Windows {
foreach (var ccb in CheckComboBoxInputs)
OriginalValues[ccb] = ccb.SelectedItems.Cast<object>().ToArray();
foreach (var cb in CheckBoxInputs)
OriginalValues[cb] = (cb.IsChecked ?? false) ? bool.TrueString : null;
OriginalValues[cb] = cb.IsChecked?.ToString();
foreach (var rb in RadioButtonInputs)
OriginalValues[rb] = (rb.IsChecked ?? false) ? bool.TrueString : null;
OriginalValues[rb] = rb.IsChecked?.ToString();
}
protected void SetOriginalValue(Control input, object? value) {
OriginalValues[input] = value;
OriginalValues[input] = value is bool b ? b.ToString() : value;
if (InputHasChanged(input)) {
ControlUtils.SetInputChanged(input);
} else {
@@ -208,13 +204,17 @@ namespace Elwig.Windows {
}
}
protected void SetOriginalValue(Control input) {
SetOriginalValue(input, ControlUtils.GetInputValue(input));
}
protected void UnsetOriginalValue(Control input) {
OriginalValues.Remove(input);
ControlUtils.ClearInputState(input);
}
protected void SetDefaultValue(Control input, object? value) {
DefaultValues[input] = value;
DefaultValues[input] = value is bool b ? b.ToString() : value;
if (!InputHasChanged(input)) {
if (InputIsNotDefault(input)) {
ControlUtils.SetInputNotDefault(input);
@@ -224,6 +224,10 @@ namespace Elwig.Windows {
}
}
protected void SetDefaultValue(Control input) {
SetDefaultValue(input, ControlUtils.GetInputValue(input));
}
protected void UnsetDefaultValue(Control input) {
DefaultValues.Remove(input);
if (!InputHasChanged(input)) {
@@ -261,9 +265,9 @@ namespace Elwig.Windows {
} else if (input is CheckComboBox ccb) {
return !ccb.SelectedItems.Cast<object>().ToArray().SequenceEqual(((object[]?)OriginalValues[ccb]) ?? Array.Empty<object>());
} else if (input is CheckBox cb) {
return (OriginalValues[cb] != null) != (cb.IsChecked ?? false);
return (string?)OriginalValues[cb] != cb.IsChecked?.ToString();
} else if (input is RadioButton rb) {
return (OriginalValues[rb] != null) != (rb.IsChecked ?? false);
return (string?)OriginalValues[rb] != rb.IsChecked?.ToString();
} else {
return false;
}
@@ -279,9 +283,9 @@ namespace Elwig.Windows {
} else if (input is CheckComboBox ccb) {
return !ccb.SelectedItems.Cast<object>().ToArray().SequenceEqual(((object[]?)DefaultValues[ccb]) ?? Array.Empty<object>());
} else if (input is CheckBox cb) {
return (DefaultValues[cb] != null) != (cb.IsChecked ?? false);
return (string?)DefaultValues[cb] != cb.IsChecked?.ToString();
} else if (input is RadioButton rb) {
return (DefaultValues[rb] != null) != (rb.IsChecked ?? false);
return (string?)DefaultValues[rb] != rb.IsChecked?.ToString();
} else {
return false;
}
@@ -359,7 +363,7 @@ namespace Elwig.Windows {
}
protected bool InputLostFocus(TextBox input, ValidationResult res, string? msg = null) {
if (!res.IsValid && !IsClosing)
if (!res.IsValid && !IsClosing && (IsEditing || IsCreating))
System.Windows.MessageBox.Show(res.ErrorContent.ToString(), msg ?? res.ErrorContent.ToString(), MessageBoxButton.OK, MessageBoxImage.Warning);
return res.IsValid;
}
@@ -460,20 +464,22 @@ namespace Elwig.Windows {
protected void PlzInput_TextChanged(object sender, RoutedEventArgs evt) {
var plz = (TextBox)sender;
InputTextChanged(plz, Validator.CheckPlz);
UpdatePlz(plz, GetPlzOrtInput(plz));
if ("PLZ".Equals(plz.Tag))
UpdatePlz(plz, GetPlzOrtInput(plz));
}
protected void PlzInput_LostFocus(object sender, RoutedEventArgs evt) {
var plz = (TextBox)sender;
InputLostFocus(plz, Validator.CheckPlz);
UpdatePlz(plz, GetPlzOrtInput(plz));
if ("PLZ".Equals(plz.Tag))
UpdatePlz(plz, GetPlzOrtInput(plz));
}
protected void EmailInput_TextChanged(object sender, RoutedEventArgs evt) {
protected void EmailAddressInput_TextChanged(object sender, RoutedEventArgs evt) {
InputTextChanged((TextBox)sender, Validator.CheckEmailAddress);
}
protected void EmailInput_LostFocus(object sender, RoutedEventArgs evt) {
protected void EmailAddressInput_LostFocus(object sender, RoutedEventArgs evt) {
InputLostFocus((TextBox)sender, Validator.CheckEmailAddress);
}

View File

@@ -58,6 +58,7 @@ namespace Elwig.Windows {
EditAreaCommitmentButton.IsEnabled = false;
DeleteAreaCommitmentButton.IsEnabled = false;
ClearOriginalValues();
ClearDefaultValues();
ClearInputs(validate);
ClearInputStates();
}
@@ -66,6 +67,7 @@ namespace Elwig.Windows {
private void FillInputs(AreaCom a) {
ClearOriginalValues();
ClearDefaultValues();
FbNrInput.Text = a.FbNr.ToString();
MgNrInput.Text = a.MgNr.ToString();
@@ -84,9 +86,14 @@ namespace Elwig.Windows {
}
private async void InitInputs() {
ClearOriginalValues();
ClearDefaultValues();
FbNrInput.Text = (await Context.NextFbNr()).ToString();
MgNrInput.Text = Member.MgNr.ToString();
FinishInputFilling();
SetDefaultValue(FbNrInput);
ValidateRequiredInputs();
}
protected override async Task RenewContext() {

View File

@@ -0,0 +1,235 @@
<local:AdministrationWindow x:Class="Elwig.Windows.BaseDataWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Elwig.Windows"
mc:Ignorable="d"
Title="Stammdaten - Elwig" Height="500" MinHeight="400" Width="800" MinWidth="800"
Loaded="Window_Loaded">
<Window.Resources>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Padding" Value="2,4,2,4"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Height" Value="25"/>
<Setter Property="TextWrapping" Value="NoWrap"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="Height" Value="25"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="Button">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="9,3"/>
<Setter Property="Height" Value="27"/>
</Style>
</Window.Resources>
<Grid>
<TabControl Margin="10,10,10,42">
<TabItem Header="Mandant">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="Vollständiger Name:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,10,0,10"/>
<TextBox x:Name="ClientNameFull" IsEnabled="False"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Grid.ColumnSpan="3" Margin="0,10,10,10"/>
<Label Content="Name:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,40,0,10"/>
<TextBox x:Name="ClientNameInput"
TextChanged="ClientNames_TextChanged"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Grid.ColumnSpan="3" Margin="0,40,10,10"/>
<Label Content="Namenszusatz:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,70,0,10"/>
<TextBox x:Name="ClientNameSuffixInput"
TextChanged="ClientNames_TextChanged"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Grid.ColumnSpan="3" Margin="0,70,10,10"/>
<Label Content="Gesellschaftsform:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,100,0,10"/>
<TextBox x:Name="ClientNameTypeInput"
TextChanged="ClientNames_TextChanged"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Margin="0,100,10,10"/>
<Label Content="Kürzel/Kurzform:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,130,0,10"/>
<TextBox x:Name="ClientNameTokenInput"
TextChanged="TextBox_TextChanged"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="1" Margin="0,130,10,10" Width="70"/>
<TextBox x:Name="ClientNameShortInput"
TextChanged="TextBox_TextChanged"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Margin="75,130,10,10"/>
<Label Content="Adresse:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,160,0,10"/>
<TextBox x:Name="ClientAddressInput"
TextChanged="TextBox_TextChanged"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Margin="0,160,10,10"/>
<Label Content="PLZ/Ort:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,190,0,10"/>
<TextBox x:Name="ClientPlzInput"
Margin="0,190,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus"/>
<TextBox x:Name="ClientOrtInput" Margin="47,190,10,0" Grid.Column="1"
TextChanged="TextBox_TextChanged"/>
<Label Content="IBAN:" Margin="10,220,0,0" Grid.Column="0"/>
<TextBox x:Name="ClientIbanInput" Margin="0,220,10,0" Grid.Column="1"
TextChanged="IbanInput_TextChanged" LostFocus="IbanInput_LostFocus"/>
<Label Content="BIC:" Margin="10,250,0,0" Grid.Column="0"/>
<TextBox x:Name="ClientBicInput" Margin="0,250,10,0" Grid.Column="1"
TextChanged="BicInput_TextChanged" LostFocus="BicInput_LostFocus"/>
<Label Content="UID:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,100,0,10"/>
<TextBox x:Name="ClientUstIdNrInput"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="3" Margin="0,100,10,10" Width="96"
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
<Label Content="Betriebs-Nr.:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,130,0,10"/>
<TextBox x:Name="ClientLfbisNrInput"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="3" Margin="0,130,10,10" Width="64"
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
<Label Content="Telefon-Nr.:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,160,0,10"/>
<TextBox x:Name="ClientPhoneNrInput" Margin="0,160,10,10" Grid.Column="3"
TextChanged="PhoneNrInput_TextChanged" LostFocus="PhoneNrInput_LostFocus"/>
<Label Content="Fax-Nr.:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,190,0,10"/>
<TextBox x:Name="ClientFaxNrInput" Margin="0,190,10,10" Grid.Column="3"
TextChanged="PhoneNrInput_TextChanged" LostFocus="PhoneNrInput_LostFocus"/>
<Label Content="E-Mail-Adr.:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,220,0,10"/>
<TextBox x:Name="ClientEmailAddressInput" Margin="0,220,10,0" Grid.Column="3"
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
<Label Content="Website:"
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,250,0,10"/>
<TextBox x:Name="ClientWebsiteInput" Margin="0,250,10,0" Grid.Column="3"
TextChanged="TextBox_TextChanged"/>
</Grid>
</TabItem>
<TabItem Header="Zweigstellen">
</TabItem>
<TabItem Header="Sortenattribute">
</TabItem>
<TabItem Header="Bewirtschaftungsarten">
</TabItem>
<TabItem Header="Flächenbindungsverträge">
</TabItem>
<TabItem Header="Saisons">
<Grid>
<ListBox x:Name="SeasonList" HorizontalAlignment="Left" VerticalAlignment="Stretch" Width="150" Margin="10,10,10,10"
SelectionChanged="SeasonList_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Year}" Width="40"/>
<TextBlock Text="{Binding Currency.Name}" Width="60"/>
<TextBlock Text="{Binding Precision}" Width="10"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<GroupBox Header="Zu-/Abschläge" Margin="170,150,10,10" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="SeasonModifierList" SelectionChanged="SeasonModifierList_SelectionChanged"
HorizontalAlignment="Left" VerticalAlignment="Stretch" Width="350" Margin="10,10,10,10">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ModId}" Width="30"/>
<TextBlock Text="{Binding Name}" Width="200" Margin="0,0,10,0"/>
<TextBlock Text="{Binding ValueStr}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="SeasonModifierUpButton" Content="&#xE96D;" FontFamily="Segoe MDL2 Assets" FontSize="10" Padding="0,0,0,0" IsEnabled="False"
Click="SeasonModifierUpButton_Click"
VerticalAlignment="Center" HorizontalAlignment="Left" Width="25" Height="25" Margin="365,0,0,90"/>
<Button x:Name="SeasonModifierDownButton" Content="&#xE96E;" FontFamily="Segoe MDL2 Assets" FontSize="10" Padding="0,2,0,0" IsEnabled="False"
Click="SeasonModifierDownButton_Click"
VerticalAlignment="Center" HorizontalAlignment="Left" Width="25" Height="25" Margin="365,0,0,30"/>
<Button x:Name="SeasonModifierAddButton" Content="&#xF8AA;" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" IsEnabled="False"
Click="SeasonModifierAddButton_Click"
VerticalAlignment="Center" HorizontalAlignment="Left" Width="25" Height="25" Margin="365,30,0,0"/>
<Button x:Name="SeasonModifierDeleteButton" Content="&#xF8AB;" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" IsEnabled="False"
Click="SeasonModifierDeleteButton_Click"
VerticalAlignment="Center" HorizontalAlignment="Left" Width="25" Height="25" Margin="365,90,0,0"/>
<Label Content="ID:" Grid.Column="1" Margin="10,10,10,10"/>
<TextBox x:Name="SeasonModifierIdInput" Grid.Column="2" Margin="0,10,10,10" Width="50" HorizontalAlignment="Left"
TextChanged="SeasonModifierIdInput_TextChanged"/>
<Label Content="Name:" Grid.Column="1" Margin="10,40,10,10"/>
<TextBox x:Name="SeasonModifierNameInput" Grid.Column="2" Margin="0,40,10,10"
TextChanged="SeasonModifierNameInput_TextChanged"/>
<Label Content="Relativ:" Grid.Column="1" Margin="10,70,10,10"/>
<TextBox x:Name="SeasonModifierRelInput" Grid.Column="2" Margin="0,70,10,10"
TextChanged="SeasonModifierRelInput_TextChanged"/>
<Label Content="Absolut:" Grid.Column="1" Margin="10,100,10,10"/>
<TextBox x:Name="SeasonModifierAbsInput" Grid.Column="2" Margin="0,100,10,10"
TextChanged="SeasonModifierAbsInput_TextChanged"/>
</Grid>
</GroupBox>
</Grid>
</TabItem>
<TabItem Header="Parameter">
</TabItem>
<TabItem Header="Textelemente">
</TabItem>
</TabControl>
<Button x:Name="EditButton" Content="Bearbeiten"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,10" Width="120"
Click="EditButton_Click"/>
<Button x:Name="SaveButton" Content="Speichern" IsEnabled="False"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,250,10" Width="120"
Click="SaveButton_Click"/>
<Button x:Name="ResetButton" Content="Zurücksetzen" IsEnabled="False" Visibility="Hidden"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,10" Width="120"
Click="ResetButton_Click"/>
<Button x:Name="CancelButton" Content="Abbrechen" IsEnabled="False" IsCancel="True"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="250,0,0,10" Width="120"
Click="CancelButton_Click"/>
</Grid>
</local:AdministrationWindow>

View File

@@ -0,0 +1,343 @@
using Elwig.Helpers;
using Elwig.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Elwig.Windows {
public partial class BaseDataWindow : AdministrationWindow {
private Dictionary<string, string?>? Modifiers = null;
private Dictionary<Modifier, string>? ModifierIds = null;
private ObservableCollection<Modifier>? ModifierList = null;
private bool ModifiersChanged = false;
private bool ModifierUpdate = false;
public BaseDataWindow() {
InitializeComponent();
RequiredInputs = new Control[] {
ClientNameInput, ClientNameTypeInput, ClientNameTokenInput, ClientNameShortInput,
ClientAddressInput, ClientPlzInput, ClientOrtInput,
};
ExemptInputs = new Control[] {
ClientNameFull,
SeasonModifierIdInput, SeasonModifierNameInput, SeasonModifierRelInput, SeasonModifierAbsInput,
};
}
new protected void LockInputs() {
base.LockInputs();
SeasonModifierIdInput.IsReadOnly = true;
SeasonModifierNameInput.IsReadOnly = true;
SeasonModifierRelInput.IsReadOnly = true;
SeasonModifierAbsInput.IsReadOnly = true;
}
new protected void UnlockInputs() {
base.UnlockInputs();
SeasonModifierIdInput.IsReadOnly = false;
SeasonModifierNameInput.IsReadOnly = false;
SeasonModifierRelInput.IsReadOnly = false;
SeasonModifierAbsInput.IsReadOnly = false;
}
private void Window_Loaded(object sender, RoutedEventArgs evt) {
LockInputs();
FillInputs(App.Client);
}
protected override async Task RenewContext() {
await base.RenewContext();
ControlUtils.RenewItemsSource(SeasonList, await Context.Seasons.OrderByDescending(s => s.Year).ToListAsync(), s => (s as Season)?.Year, null, ControlUtils.RenewSourceDefault.First);
var year = (SeasonList.SelectedItem as Season)?.Year;
ControlUtils.RenewItemsSource(SeasonModifierList, await Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToListAsync(), m => (m as Modifier)?.ModId);
}
protected override void UpdateButtons() {
if (!IsEditing && !IsCreating) return;
bool ch = ModifiersChanged || HasChanged, v = IsValid;
CancelButton.IsEnabled = true;
ResetButton.IsEnabled = ch;
SaveButton.IsEnabled = ch && v;
SeasonModifierUpButton.IsEnabled = SeasonModifierList.SelectedIndex >= 1;
SeasonModifierDownButton.IsEnabled = SeasonModifierList.SelectedIndex != -1 && SeasonModifierList.SelectedIndex < (ModifierList?.Count - 1 ?? 0);
SeasonModifierAddButton.IsEnabled = true;
SeasonModifierDeleteButton.IsEnabled = SeasonModifierList.SelectedIndex != -1;
}
private void ModifiersInitEditing() {
var year = (SeasonList.SelectedItem as Season)?.Year;
Context.ChangeTracker.Clear();
ModifierList = new(Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToList());
Modifiers = ModifierList.ToDictionary(m => m.ModId, m => m.ModId);
ModifierIds = ModifierList.ToDictionary(m => m, m => m.ModId);
ControlUtils.RenewItemsSource(SeasonModifierList, ModifierList, m => (m as Modifier)?.ModId);
}
private void ModifiersFinishEditing() {
var year = (SeasonList.SelectedItem as Season)?.Year;
ControlUtils.RenewItemsSource(SeasonModifierList, Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToList(), m => (m as Modifier)?.ModId);
ModifierList = null;
Modifiers = null;
ModifierIds = null;
ModifiersChanged = false;
SeasonModifierUpButton.IsEnabled = false;
SeasonModifierDownButton.IsEnabled = false;
SeasonModifierAddButton.IsEnabled = false;
SeasonModifierDeleteButton.IsEnabled = false;
}
private async Task ModifiersSave() {
if (!ModifiersChanged || ModifierList == null || Modifiers == null || ModifierIds == null) return;
int i = 0;
foreach (var mod in ModifierList) mod.Ordering = ++i;
var year = (SeasonList.SelectedItem as Season)?.Year;
foreach (var (modid, _) in Modifiers.Where(m => m.Value == null)) {
Context.Remove(Context.Modifiers.Find(new object?[] { year, modid }));
}
foreach (var (mod, old) in ModifierIds) {
mod.ModId = old;
}
foreach (var (old, modid) in Modifiers.Where(m => m.Value != null)) {
Context.Update(Context.Modifiers.Find(new object?[] { year, old }));
}
await Context.SaveChangesAsync();
foreach (var (old, modid) in Modifiers.Where(m => m.Value != null)) {
await Context.Database.ExecuteSqlAsync($"UPDATE modifier SET modid = {modid} WHERE (year, modid) = ({year}, {old})");
}
await Context.SaveChangesAsync();
foreach (var mod in ModifierList.Where(m => !ModifierIds.ContainsKey(m))) {
await Context.AddAsync(mod);
}
await Context.SaveChangesAsync();
}
private void EditButton_Click(object sender, RoutedEventArgs evt) {
IsEditing = true;
EditButton.Visibility = Visibility.Hidden;
ResetButton.Visibility = Visibility.Visible;
ModifiersInitEditing();
UnlockInputs();
UpdateButtons();
}
private void CancelButton_Click(object sender, RoutedEventArgs evt) {
IsEditing = false;
IsCreating = false;
EditButton.Visibility = Visibility.Visible;
ResetButton.Visibility = Visibility.Hidden;
CancelButton.IsEnabled = false;
SaveButton.IsEnabled = false;
ResetButton.IsEnabled = false;
ModifiersFinishEditing();
ClearInputStates();
FillInputs(App.Client);
LockInputs();
}
private void ResetButton_Click(object sender, RoutedEventArgs evt) {
ModifiersChanged = false;
ModifiersInitEditing();
ClearInputStates();
FillInputs(App.Client);
UpdateButtons();
}
private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
try {
await UpdateClientParameters(App.Client);
await ModifiersSave();
} catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Stammdaten aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
}
IsEditing = false;
IsCreating = false;
EditButton.Visibility = Visibility.Visible;
ResetButton.Visibility = Visibility.Hidden;
CancelButton.IsEnabled = false;
SaveButton.IsEnabled = false;
ResetButton.IsEnabled = false;
ModifiersFinishEditing();
ClearInputStates();
FillInputs(App.Client);
LockInputs();
}
private void FillInputs(ClientParameters p) {
ClearOriginalValues();
ClearDefaultValues();
ClientNameInput.Text = p.Name;
ClientNameSuffixInput.Text = p.NameSuffix;
ClientNameTypeInput.Text = p.NameType;
ClientNameTokenInput.Text = p.NameToken;
ClientNameShortInput.Text = p.NameShort;
ClientAddressInput.Text = p.Address;
ClientPlzInput.Text = p.Plz.ToString();
ClientOrtInput.Text = p.Ort;
ClientIbanInput.Text = p.Iban;
ClientBicInput.Text = p.Bic;
ClientUstIdNrInput.Text = p.UstIdNr;
ClientLfbisNrInput.Text = p.LfbisNr;
ClientPhoneNrInput.Text = p.PhoneNr;
ClientFaxNrInput.Text = p.FaxNr;
ClientEmailAddressInput.Text = p.EmailAddress;
ClientWebsiteInput.Text = p.Website;
FinishInputFilling();
}
private async Task UpdateClientParameters(ClientParameters p) {
p.Name = ClientNameInput.Text;
p.NameSuffix = ClientNameSuffixInput.Text.Length > 0 ? ClientNameSuffixInput.Text : null;
p.NameType = ClientNameTypeInput.Text;
p.NameToken = ClientNameTokenInput.Text;
p.NameShort = ClientNameShortInput.Text;
p.Address = ClientAddressInput.Text;
p.Plz = int.Parse(ClientPlzInput.Text);
p.Ort = ClientOrtInput.Text;
p.Iban = ClientIbanInput.Text.Length > 0 ? ClientIbanInput.Text.Replace(" ", "") : null;
p.Bic = ClientBicInput.Text.Length > 0 ? ClientBicInput.Text : null;
p.UstIdNr = ClientUstIdNrInput.Text.Length > 0 ? ClientUstIdNrInput.Text : null;
p.LfbisNr = ClientLfbisNrInput.Text.Length > 0 ? ClientLfbisNrInput.Text : null;
p.PhoneNr = ClientPhoneNrInput.Text.Length > 0 ? ClientPhoneNrInput.Text : null;
p.FaxNr = ClientFaxNrInput.Text.Length > 0 ? ClientFaxNrInput.Text : null;
p.EmailAddress = ClientEmailAddressInput.Text.Length > 0 ? ClientEmailAddressInput.Text : null;
p.Website = ClientWebsiteInput.Text.Length > 0 ? ClientWebsiteInput.Text : null;
await p.UpdateValues();
}
private void SeasonModifierUpButton_Click(object sender, RoutedEventArgs evt) {
if (ModifierList == null) return;
ModifiersChanged = true;
var idx = SeasonModifierList.SelectedIndex;
var item = ModifierList[idx];
ModifierList.RemoveAt(idx);
idx--;
ModifierList.Insert(idx, item);
SeasonModifierList.SelectedIndex = idx;
UpdateButtons();
}
private void SeasonModifierDownButton_Click(object sender, RoutedEventArgs evt) {
if (ModifierList == null) return;
ModifiersChanged = true;
var idx = SeasonModifierList.SelectedIndex;
var item = ModifierList[idx];
ModifierList.RemoveAt(idx);
idx++;
ModifierList.Insert(idx, item);
SeasonModifierList.SelectedIndex = idx;
UpdateButtons();
}
private void SeasonModifierAddButton_Click(object sender, RoutedEventArgs evt) {
if (ModifierList == null || SeasonList.SelectedItem is not Season s) return;
ModifiersChanged = true;
var idx = (SeasonModifierList.SelectedIndex != -1) ? SeasonModifierList.SelectedIndex + 1 : ModifierList.Count;
var item = Context.CreateProxy<Modifier>();
item.Year = s.Year;
ModifierList.Insert(idx, item);
SeasonModifierList.SelectedIndex = idx;
UpdateButtons();
}
private void SeasonModifierDeleteButton_Click(object sender, RoutedEventArgs evt) {
if (ModifierList == null || Modifiers == null) return;
ModifiersChanged = true;
var idx = SeasonModifierList.SelectedIndex;
var item = ModifierList[idx];
Modifiers[item.ModId] = null;
ModifierList.RemoveAt(idx);
SeasonModifierList.SelectedIndex = idx < ModifierList.Count ? idx : idx - 1;
UpdateButtons();
}
private void ClientNames_TextChanged(object sender, TextChangedEventArgs evt) {
var suffix = ClientNameSuffixInput.Text.Length > 0 ? ClientNameSuffixInput.Text : null;
ClientNameFull.Text = $"{ClientNameInput.Text}{(suffix != null ? $", {suffix}," : "")} {ClientNameTypeInput.Text}";
TextBox_TextChanged(sender, evt);
}
private async void SeasonList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
var year = (SeasonList.SelectedItem as Season)?.Year;
SeasonModifierList.ItemsSource = await Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToListAsync();
}
private void SeasonModifierList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
UpdateButtons();
ModifierUpdate = true;
if (SeasonModifierList.SelectedItem is not Modifier mod) {
SeasonModifierIdInput.Text = "";
SeasonModifierNameInput.Text = "";
SeasonModifierRelInput.Text = "";
SeasonModifierAbsInput.Text = "";
} else {
SeasonModifierIdInput.Text = mod.ModId;
SeasonModifierNameInput.Text = mod.Name;
SeasonModifierRelInput.Text = (mod.Rel * 100)?.ToString();
SeasonModifierAbsInput.Text = mod.Abs?.ToString();
}
ModifierUpdate = false;
}
private void SeasonModifierIdInput_TextChanged(object sender, TextChangedEventArgs evt) {
if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod || Modifiers == null || ModifierIds == null) return;
ModifiersChanged = ModifiersChanged || (SeasonModifierIdInput.Text ?? "") != ((SeasonModifierList.SelectedItem as Modifier)?.ModId ?? "");
if (ModifierUpdate) return;
var old = ModifierIds.GetValueOrDefault(mod);
var id = SeasonModifierIdInput.Text ?? "";
if (old != null) Modifiers[old] = id;
mod.ModId = id;
CollectionViewSource.GetDefaultView(ModifierList).Refresh();
UpdateButtons();
}
private void SeasonModifierNameInput_TextChanged(object sender, TextChangedEventArgs evt) {
if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod) return;
ModifiersChanged = ModifiersChanged || (SeasonModifierNameInput.Text ?? "") != ((SeasonModifierList.SelectedItem as Modifier)?.Name ?? "");
if (ModifierUpdate) return;
mod.Name = SeasonModifierNameInput.Text ?? "";
CollectionViewSource.GetDefaultView(ModifierList).Refresh();
UpdateButtons();
}
private void SeasonModifierRelInput_TextChanged(object sender, TextChangedEventArgs evt) {
if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod) return;
ModifiersChanged = ModifiersChanged || (SeasonModifierRelInput.Text ?? "") != ((SeasonModifierList.SelectedItem as Modifier)?.Rel?.ToString() ?? "");
if (ModifierUpdate) return;
mod.Rel = decimal.TryParse(SeasonModifierRelInput.Text, out var v) ? v / 100 : null;
if (mod.Rel != null) SeasonModifierAbsInput.Text = "";
CollectionViewSource.GetDefaultView(ModifierList).Refresh();
UpdateButtons();
}
private void SeasonModifierAbsInput_TextChanged(object sender, TextChangedEventArgs evt) {
if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod) return;
ModifiersChanged = ModifiersChanged || (SeasonModifierAbsInput.Text ?? "") != ((SeasonModifierList.SelectedItem as Modifier)?.Abs?.ToString() ?? "");
if (ModifierUpdate) return;
mod.Abs = decimal.TryParse(SeasonModifierAbsInput.Text, out var v) ? v : null;
if (mod.Abs != null) SeasonModifierRelInput.Text = "";
CollectionViewSource.GetDefaultView(ModifierList).Refresh();
UpdateButtons();
}
}
}

View File

@@ -0,0 +1,188 @@
<local:AdministrationWindow x:Class="Elwig.Windows.ChartWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:ScottPlot="clr-namespace:ScottPlot;assembly=ScottPlot.WPF"
mc:Ignorable="d"
Title="Auszahlung - Elwig" Height="700" Width="1500"
Loaded="Window_Loaded">
<Window.Resources>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Padding" Value="2,4,2,4"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="Height" Value="25"/>
<Setter Property="TextWrapping" Value="NoWrap"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="Height" Value="25"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="Button">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="9,3"/>
<Setter Property="Height" Value="27"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="330"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Margin="5,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="42"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</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"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2"
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"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2"
Click="SaveButton_Click"/>
<Button x:Name="ResetButton" Content="Zurücksetzen" IsEnabled="False" Visibility="Hidden"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2"
Click="ResetButton_Click"/>
<Button x:Name="CancelButton" Content="Abbrechen" IsEnabled="False" Visibility="Hidden" IsCancel="True"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2"
Click="CancelButton_Click"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="1">
<ScottPlot:WpfPlot x:Name="OechslePricePlot" MouseMove="OechslePricePlot_MouseMove" MouseDown="OechslePricePlot_MouseDown" IsEnabled="False"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="2" Margin="0,0,5,0">
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="120"/>
<RowDefinition Height="210"/>
<RowDefinition Height="110"/>
<RowDefinition Height="42"/>
</Grid.RowDefinitions>
<GroupBox Header="Graph" 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.ColumnDefinitions>
<ColumnDefinition Width="85"/>
<ColumnDefinition Width="*"/>
</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"/>
<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"/>
</Grid>
</GroupBox>
<GroupBox Header="Aktionen" Grid.Row="2" Margin="0,5,5,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="LeftFlatButton" Content="Links flach" Click="LeftFlatButton_Click" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,10,10,10"/>
<Button x:Name="RightFlatButton" Content="Rechts flach" Click="RightFlatButton_Click" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,50,10,10"/>
<Button x:Name="InterpolateButton" Content="Interpolieren" Click="InterpolateButton_Click" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,90,10,10"/>
<Button x:Name="LinearIncreaseButton" Content="Linear wachsen" Click="LinearIncreaseButton_Click" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,130,10,10"/>
</Grid>
</GroupBox>
<GroupBox Header="Optionen" Grid.Row="3" Margin="0,5,5,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="FreeZoomInput" Content="Freier Zoom" IsEnabled="False"
Checked="FreeZoomInput_Changed" Unchecked="FreeZoomInput_Changed"
HorizontalAlignment="Left" Margin="10,10,10,0" VerticalAlignment="Top"/>
<CheckBox x:Name="GradationLinesInput" Content="Gradationslinien anzeigen" IsEnabled="False"
Checked="GradationLinesInput_Changed" Unchecked="GradationLinesInput_Changed"
HorizontalAlignment="Left" Margin="10,30,10,0" VerticalAlignment="Top" IsChecked="True"/>
<CheckBox x:Name="TooltipInput" Content="Tooltips anzeigen" IsEnabled="False"
HorizontalAlignment="Left" Margin="10,50,10,0" VerticalAlignment="Top" IsChecked="True"/>
</Grid>
</GroupBox>
</Grid>
</Grid>
</local:AdministrationWindow>

View File

@@ -0,0 +1,750 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using Elwig.Helpers;
using Elwig.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Newtonsoft.Json.Linq;
using ScottPlot;
using ScottPlot.Plottable;
namespace Elwig.Windows {
public partial class ChartWindow : AdministrationWindow {
private readonly int Year = 2021;
private readonly int AvNr = 2;
private ScatterPlot OechslePricePlotScatter;
private MarkerPlot HighlightedPoint;
private MarkerPlot PrimaryMarkedPoint;
private MarkerPlot SecondaryMarkedPoint;
private Tooltip Tooltip;
private int LastHighlightedIndex = -1;
private int HighlightedIndex = -1;
private int PrimaryMarkedPointIndex = -1;
private int SecondaryMarkedPointIndex = -1;
private bool HoverChanged = false;
private bool HoverActive = false;
private const int MinOechsle = 50;
private const int MaxOechsle = 140;
private Graph? Graph;
public ChartWindow() {
InitializeComponent();
ExemptInputs = new Control[] {
GraphList, OechsleInput, PriceInput, FreeZoomInput, GradationLinesInput, TooltipInput
};
}
private void Window_Loaded(object sender, RoutedEventArgs evt) {
LockInputs();
OechslePricePlot.IsEnabled = false;
}
private async Task RefreshGraphList() {
await Context.PaymentVariants.LoadAsync();
await RefreshGraphListQuery();
}
private async Task RefreshGraphListQuery(bool updateSort = false) {
List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync();
if (paymentVars.Count != 1) {
return;
}
PaymentVar paymentVar = paymentVars[0];
var data = JToken.Parse(paymentVar.Data);
var auszahlungsSorten = data["AuszahlungSorten"];
if (auszahlungsSorten == null) {
return;
}
var Graphs = auszahlungsSorten["Kurven"];
if (Graphs == null) {
return;
}
List<Graph> GraphsList = new();
int i = 1;
foreach (var graph in Graphs) {
GraphsList.Add(new Graph("Oe", i, graph, ParseContracts(auszahlungsSorten, i - 1), 50, 140));
i++;
}
ControlUtils.RenewItemsSource(GraphList, GraphsList, g => (g as Graph)?.Num);
if (GraphsList.Count == 1) {
GraphList.SelectedIndex = 0;
}
RefreshInputs();
}
private String ParseContracts(JToken auszahlungsSorten, int num) {
List<string> contracts = new();
foreach (var sorte in auszahlungsSorten.Children().OfType<JToken>()) {
if (((JProperty)sorte).Name == "Kurven") {
continue;
}
foreach (var attribut in sorte.Values().OfType<JToken>()) {
foreach (var bindung in attribut.Values().OfType<JProperty>()) {
if ((int)(bindung).Value == num) {
contracts.Add($"{((JProperty)sorte).Name}/{((JProperty)attribut).Name}/{bindung.Name}");
}
}
}
}
return string.Join("\n", contracts.ToArray());
}
private async Task<bool> RemoveGraph(int num) {
List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync();
if (paymentVars.Count != 1) {
return false;
}
PaymentVar paymentVar = paymentVars[0];
var data = JToken.Parse(paymentVar.Data);
var auszahlungsSorten = data["AuszahlungSorten"];
if (auszahlungsSorten == null) {
return false;
}
var Graphs = auszahlungsSorten["Kurven"];
if (Graphs == null) {
return false;
}
int i = 1;
foreach (var graph in Graphs) {
if (i == num) {
graph.Remove();
break;
}
i++;
}
foreach (var sorte in auszahlungsSorten.Children().OfType<JToken>()) {
if (((JProperty)sorte).Name == "Kurven") {
continue;
}
foreach (var attribut in sorte.Values().OfType<JToken>()) {
List<JProperty> itemsToRemove = new();
foreach (var bindung in attribut.Values().OfType<JProperty>()) {
if ((int)bindung.Value == num - 1) {
itemsToRemove.Add(bindung);
} else if ((int)bindung.Value > num - 1) {
bindung.Value = (int)bindung.Value - 1;
}
}
itemsToRemove.ForEach(i => i.Remove());
}
}
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) {
ResetPlot();
ClearInputStates();
if (GraphList.SelectedItem is Graph g) {
EditButton.IsEnabled = true;
DeleteButton.IsEnabled = true;
EnableOptionButtons();
FillInputs(g);
} else {
EditButton.IsEnabled = false;
DeleteButton.IsEnabled = false;
DisableOptionButtons();
ClearOriginalValues();
ClearInputs(validate);
ClearInputStates();
}
GC.Collect();
}
private void FillInputs(Graph g) {
ClearOriginalValues();
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();
OechslePricePlot.IsEnabled = true;
FinishInputFilling();
}
private void InitInputs() {
GraphNumberInput.Text = (GraphList.Items.Count + 1).ToString();
OechsleGraphType_Input.IsChecked = true;
FinishInputFilling();
}
protected override async Task RenewContext() {
await base.RenewContext();
await RefreshGraphList();
}
private void InitPlot() {
OechslePricePlotScatter = OechslePricePlot.Plot.AddScatter(Graph.DataX, Graph.DataY);
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);
OechslePricePlot.Plot.Layout(padding: 0);
OechslePricePlot.Plot.XAxis2.Layout(padding: 0);
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;
PrimaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
PrimaryMarkedPoint.Color = Color.Red;
PrimaryMarkedPoint.MarkerSize = 6;
PrimaryMarkedPoint.MarkerShape = MarkerShape.filledCircle;
PrimaryMarkedPoint.IsVisible = false;
SecondaryMarkedPoint = OechslePricePlot.Plot.AddPoint(0, 0);
SecondaryMarkedPoint.Color = Color.Red;
SecondaryMarkedPoint.MarkerSize = 6;
SecondaryMarkedPoint.MarkerShape = MarkerShape.filledCircle;
SecondaryMarkedPoint.IsVisible = false;
OechslePricePlot.Refresh();
RefreshFreeZoom();
RefreshGradationLines();
}
private void ResetPlot() {
Graph = null;
PrimaryMarkedPointIndex = -1;
OechslePricePlot.Plot.Remove(OechslePricePlotScatter);
OechslePricePlot.Plot.Clear();
OechslePricePlot.Reset();
OechslePricePlot.Refresh();
}
private void ChangeMarker(MarkerPlot point, bool visible, double x = 0, double y = 0) {
point.X = x;
point.Y = y;
point.IsVisible = visible;
}
private void FlattenGraph(int begin, int end, double value) {
for (int i = begin; i <= end; i++) {
Graph.DataY[i] = value;
}
OechslePricePlot.Render();
}
private void LinearIncreaseGraph(int begin, int end, double inc) {
for (int i = begin; i < end; i++) {
Graph.DataY[i + 1] = Graph.DataY[i] + inc;
}
OechslePricePlot.Render();
}
private void EnableActionButtons() {
LeftFlatButton.IsEnabled = true;
RightFlatButton.IsEnabled = true;
LinearIncreaseButton.IsEnabled = true;
}
private void DisableActionButtons() {
LeftFlatButton.IsEnabled = false;
RightFlatButton.IsEnabled = false;
InterpolateButton.IsEnabled = false;
LinearIncreaseButton.IsEnabled = false;
}
private void FreeZoomInput_Changed(object sender, RoutedEventArgs evt) {
RefreshFreeZoom();
}
private void RefreshFreeZoom() {
if (FreeZoomInput.IsChecked == true) {
UnlockZoom();
} else {
LockZoom();
}
OechslePricePlot.Refresh();
}
private void LockZoom() {
OechslePricePlot.Plot.XAxis.SetBoundary(MinOechsle - 1, MaxOechsle + 1);
OechslePricePlot.Plot.YAxis.SetBoundary(-0.1, 2);
OechslePricePlot.Plot.XAxis.SetZoomOutLimit(MaxOechsle - MinOechsle + 2);
OechslePricePlot.Plot.YAxis.SetZoomOutLimit(2.1);
OechslePricePlot.Plot.SetAxisLimits(MinOechsle - 1, MaxOechsle + 1, -0.1, 2);
}
private void UnlockZoom() {
OechslePricePlot.Plot.XAxis.SetBoundary();
OechslePricePlot.Plot.YAxis.SetBoundary();
OechslePricePlot.Plot.XAxis.SetZoomOutLimit((MaxOechsle - MinOechsle) * 1.5);
OechslePricePlot.Plot.YAxis.SetZoomOutLimit(3.5);
}
private void EnableOptionButtons() {
FreeZoomInput.IsEnabled = true;
GradationLinesInput.IsEnabled = true;
TooltipInput.IsEnabled = true;
}
private void DisableOptionButtons() {
FreeZoomInput.IsEnabled = false;
GradationLinesInput.IsEnabled = false;
TooltipInput.IsEnabled = false;
}
private void GradationLinesInput_Changed(object sender, RoutedEventArgs evt) {
RefreshGradationLines();
}
private void RefreshGradationLines() {
if (GradationLinesInput.IsChecked == true) {
ShowGradationLines();
ShowLegend();
} else {
HideGradationLines();
HideLegend();
}
OechslePricePlot.Refresh();
}
private void ShowGradationLines() {
OechslePricePlot.Plot.AddVerticalLine(68, Color.Red, 2, label: "68 Oechsle (LDW)");
OechslePricePlot.Plot.AddVerticalLine(73, Color.Orange, 2, label: "73 Oechsle (QUW)");
OechslePricePlot.Plot.AddVerticalLine(84, Color.Green, 2, label: "84 Oechsle (KAB)");
}
private void HideGradationLines() {
OechslePricePlot.Plot.Clear(typeof(VLine));
}
private void ShowLegend() {
OechslePricePlot.Plot.Legend(true, Alignment.UpperRight);
}
private void HideLegend() {
OechslePricePlot.Plot.Legend(false, Alignment.UpperRight);
}
private void OechsleInput_TextChanged(object sender, RoutedEventArgs evt) {
IntegerInput_TextChanged(sender, evt);
bool success = int.TryParse(OechsleInput.Text, out int oechsle);
SecondaryMarkedPointIndex = -1;
ChangeMarker(SecondaryMarkedPoint, false);
if (success) {
if (oechsle >= MinOechsle && oechsle <= MaxOechsle) {
PrimaryMarkedPointIndex = oechsle - MinOechsle;
ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]);
PriceInput.Text = Graph.DataY[PrimaryMarkedPointIndex].ToString();
EnableActionButtons();
OechslePricePlot.Render();
return;
}
}
PrimaryMarkedPointIndex = -1;
ChangeMarker(PrimaryMarkedPoint, false);
DisableActionButtons();
PriceInput.Text = "";
OechslePricePlot.Render();
}
private void PriceInput_TextChanged(object sender, RoutedEventArgs evt) {
if (PrimaryMarkedPointIndex != -1) {
bool success = Double.TryParse(PriceInput.Text, out double price);
if (success) {
Graph.DataY[PrimaryMarkedPointIndex] = price;
PrimaryMarkedPoint.Y = price;
SaveButton.IsEnabled = true;
ResetButton.IsEnabled = true;
OechslePricePlot.Refresh();
}
}
}
private void LeftFlatButton_Click(object sender, RoutedEventArgs evt) {
if (PrimaryMarkedPointIndex == -1) {
return;
}
FlattenGraph(0, PrimaryMarkedPointIndex, Graph.DataY[PrimaryMarkedPointIndex]);
}
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
if (PrimaryMarkedPointIndex == -1) {
return;
}
FlattenGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, Graph.DataY[PrimaryMarkedPointIndex]);
}
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
int steps = Math.Abs(PrimaryMarkedPointIndex - SecondaryMarkedPointIndex);
if (PrimaryMarkedPointIndex == -1 || SecondaryMarkedPointIndex == -1 || steps < 2) {
return;
}
var (lowIndex, highIndex) = PrimaryMarkedPointIndex < SecondaryMarkedPointIndex ? (PrimaryMarkedPointIndex, SecondaryMarkedPointIndex): (SecondaryMarkedPointIndex, PrimaryMarkedPointIndex);
double step = (Graph.DataY[highIndex] - Graph.DataY[lowIndex]) / steps;
for (int i = lowIndex; i < highIndex - 1; i++) {
Graph.DataY[i + 1] = Math.Round(Graph.DataY[i] + step, 4); // TODO richtig runden
}
}
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
if (PrimaryMarkedPointIndex == -1) {
return;
}
double? priceIncrease = Utils.ShowLinearPriceIncreaseDialog();
if (priceIncrease == null) {
return;
}
LinearIncreaseGraph(PrimaryMarkedPointIndex, Graph.DataY.Length - 1, priceIncrease.Value);
}
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
if (!IsCreating && GraphList.SelectedItem == null) {
return;
}
if (HoverActive) {
if ((IsEditing || IsCreating) && Keyboard.IsKeyDown(Key.LeftCtrl)) {
if (PrimaryMarkedPointIndex == -1) {
return;
}
SecondaryMarkedPointIndex = HighlightedIndex;
ChangeMarker(SecondaryMarkedPoint, true, Graph.DataX[SecondaryMarkedPointIndex], Graph.DataY[SecondaryMarkedPointIndex]);
InterpolateButton.IsEnabled = true;
return;
}
PrimaryMarkedPointIndex = HighlightedIndex;
ChangeMarker(PrimaryMarkedPoint, true, Graph.DataX[PrimaryMarkedPointIndex], Graph.DataY[PrimaryMarkedPointIndex]);
OechsleInput.Text = Graph.DataX[HighlightedIndex].ToString();
PriceInput.Text = Graph.DataY[HighlightedIndex].ToString();
if (IsEditing || IsCreating) {
EnableActionButtons();
}
} else {
PrimaryMarkedPointIndex = -1;
SecondaryMarkedPointIndex = -1;
ChangeMarker(PrimaryMarkedPoint, false);
ChangeMarker(SecondaryMarkedPoint, false);
OechsleInput.Text = "";
PriceInput.Text = "";
DisableActionButtons();
}
}
private void OechslePricePlot_MouseMove(object sender, MouseEventArgs e) {
if (!IsCreating && 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 mousePixelX, double mousePixelY) = OechslePricePlot.GetMousePixel();
(double pointPixelX, double pointPixelY) = OechslePricePlot.Plot.GetPixel(pointX, pointY);
HighlightedIndex = LastHighlightedIndex;
if (Math.Abs(mousePixelX - pointPixelX) < 3 && Math.Abs(mousePixelY - pointPixelY) < 3) {
ChangeMarker(HighlightedPoint, true, pointX, pointY);
HighlightedPoint.IsVisible = true;
HoverChanged = true ^ HoverActive;
HoverActive = true;
} else {
ChangeMarker(HighlightedPoint, false);
HoverChanged= false ^ HoverActive;
HoverActive= false;
OechslePricePlot.Plot.Remove(Tooltip);
OechslePricePlot.Render();
}
if (LastHighlightedIndex != HighlightedIndex || HoverChanged) {
OechslePricePlot.Plot.Remove(Tooltip);
if (TooltipInput.IsChecked == true) {
Tooltip = OechslePricePlot.Plot.AddTooltip($"Oechsle: {pointX:N2}, Preis: {Math.Round(pointY, 4)})", pointX, pointY);
}
LastHighlightedIndex = pointIndex;
HoverChanged = false;
OechslePricePlot.Render();
}
}
override protected void UpdateButtons() {
if (!IsEditing && !IsCreating) return;
bool ch = HasChanged, v = IsValid;
}
private void DisableNewEditDeleteButtons() {
NewButton.IsEnabled = false;
EditButton.IsEnabled = false;
DeleteButton.IsEnabled = false;
}
private void EnableNewEditDeleteButtons() {
NewButton.IsEnabled = true;
EditButton.IsEnabled = GraphList.SelectedItem != null;
DeleteButton.IsEnabled = GraphList.SelectedItem != null;
}
private void ShowSaveResetCancelButtons() {
SaveButton.IsEnabled = false;
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(
$"Soll der Graph {g.Num} (verwendet in folgenden Verträgen: {g.Contracts}) wirklich unwiderruflich gelöscht werden?",
"Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (r == MessageBoxResult.Yes) {
bool success = await RemoveGraph(g.Num);
if (!success) {
MessageBox.Show("Der Graph konnte nicht gelöscht werden", "Graph löschen", MessageBoxButton.OK, MessageBoxImage.Error);
}
await RefreshGraphList();
}
}
private async void SaveButton_Click(object sender, RoutedEventArgs e) {
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) {
List<PaymentVar> paymentVars = await Context.PaymentVariants.Where(p => p.Year == Year && p.AvNr == AvNr).ToListAsync();
if (paymentVars.Count != 1) {
return null;
}
PaymentVar paymentVar = paymentVars[0];
var data = JToken.Parse(paymentVar.Data);
var auszahlungsSorten = data["AuszahlungSorten"];
if (auszahlungsSorten == null) {
return null;
}
var Graphs = auszahlungsSorten["Kurven"];
if (Graphs == null) {
return null;
}
if (IsEditing) {
((JArray)Graphs)[g.Num - 1] = g.ToJson();
} else if(IsCreating) {
((JArray)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();
//var x = OechslePricePlot.Plot.GetPlottables().OfType<ScatterPlot>();
//MessageBox.Show($"SelectionChanged\nLength: {x.ToList().Count}, Ys: {string.Join(", ", ((ScatterPlot)x.First()).Ys)}");
}
private void PriceInput_LostFocus(object sender, RoutedEventArgs e) {
}
private void OechsleInput_LostFocus(object sender, RoutedEventArgs e) {
}
private void GraphNumberInput_TextChanged(object sender, TextChangedEventArgs e) {
}
private void GraphNumberInput_LostFocus(object sender, RoutedEventArgs e) {
}
}
}

View File

@@ -1,12 +0,0 @@
<local:AdministrationWindow x:Class="Elwig.Windows.ClientParamWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Elwig.Windows"
mc:Ignorable="d"
Title="ClientParamWindow" Height="450" Width="800">
<Grid>
</Grid>
</local:AdministrationWindow>

View File

@@ -1,18 +0,0 @@
using System.Threading.Tasks;
namespace Elwig.Windows {
public partial class ClientParamWindow : AdministrationWindow {
public ClientParamWindow() {
InitializeComponent();
}
protected override void UpdateButtons() {
}
protected override async Task RenewContext() {
}
}
}

View File

@@ -78,10 +78,6 @@ namespace Elwig.Windows {
WeighingCButton.Visibility = Visibility.Hidden;
WeighingDButton.Visibility = Visibility.Hidden;
}
if (App.Client.IsMatzen) {
SetDefaultValue(GerebeltGewogenInput, true);
}
}
public DeliveryAdminWindow(int mgnr) : this() {
@@ -106,14 +102,14 @@ namespace Elwig.Windows {
private async void Menu_Print_ShowDeliveryNote_Click(object sender, RoutedEventArgs evt) {
if (DeliveryList.SelectedItem is not Delivery d) return;
using var doc = new DeliveryNote(d);
using var doc = new DeliveryNote(d, Context);
await doc.Generate();
doc.Show();
}
private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) {
if (DeliveryList.SelectedItem is not Delivery d) return;
using var doc = new DeliveryNote(d);
using var doc = new DeliveryNote(d, Context);
await doc.Generate();
await doc.Print();
}
@@ -131,17 +127,21 @@ namespace Elwig.Windows {
}
private void InitialInputs() {
ClearOriginalValues();
ClearDefaultValues();
HandPickedInput.IsChecked = null;
SetDefaultValue(HandPickedInput, null);
if (App.Client.IsMatzen) {
GerebeltGewogenInput.IsChecked = true;
GerebeltGewogenInput.IsEnabled = false;
SetDefaultValue(GerebeltGewogenInput);
} else {
GerebeltGewogenInput.IsChecked = false;
UnsetDefaultValue(GerebeltGewogenInput);
GerebeltGewogenInput.IsEnabled = true;
UnsetDefaultValue(GerebeltGewogenInput);
}
ClearOriginalValues();
SetDefaultValue(HandPickedInput);
ValidateRequiredInputs();
}
@@ -426,6 +426,7 @@ namespace Elwig.Windows {
FillInputs(d);
} else {
ClearOriginalValues();
ClearDefaultValues();
ClearInputs(validate);
ClearInputStates();
}
@@ -434,6 +435,7 @@ namespace Elwig.Windows {
private void FillInputs(Delivery d) {
ClearOriginalValues();
ClearDefaultValues();
MgNrInput.Text = d.MgNr.ToString();
ControlUtils.SelectComboBoxItem(BranchInput, i => (i as Branch)?.ZwstId, d.ZwstId);
@@ -456,6 +458,7 @@ namespace Elwig.Windows {
private void FillInputs(DeliveryPart p) {
FillInputs(p.Delivery);
ClearOriginalValues();
ClearDefaultValues();
SortIdInput.Text = p?.SortId ?? "";
ControlUtils.SelectCheckComboBoxItems(AttributesInput, p?.Attributes, i => (i as WineAttr)?.AttrId);
@@ -714,7 +717,7 @@ namespace Elwig.Windows {
await RefreshDeliveryList();
await RefreshDeliveryParts();
if (p?.Delivery != null) {
using var doc = new DeliveryNote(p.Delivery);
using var doc = new DeliveryNote(p.Delivery, Context);
await doc.Generate();
doc.Show();
//await doc.Print(2);

View File

@@ -49,11 +49,15 @@
<Button x:Name="DeliveryListButton" Content="Lieferungungen" Click="DeliveryListButton_Click" IsEnabled="False"
Margin="50,320,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Button x:Name="PdfButton" Content="PDF Erzeugen" Click="PdfButton_Click" Tag="Print"
<Button x:Name="BaseDataButton" Content="Stammdaten" Click="BaseDataButton_Click"
Margin="260,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Button x:Name="TestWindowButton" Content="Test Fenster" Click="TestWindowButton_Click"
<Button x:Name="PdfButton" Content="PDF Erzeugen" Click="PdfButton_Click" Tag="Print"
Margin="260,200,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Button x:Name="QueryWindowButton" Content="Datenbankabfragen" Click="QueryWindowButton_Click"
<Button x:Name="TestWindowButton" Content="Test Fenster" Click="TestWindowButton_Click"
Margin="260,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Button x:Name="QueryWindowButton" Content="Datenbankabfragen" Click="QueryWindowButton_Click"
Margin="260,280,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Button x:Name="PaymentWindowButton" Content="Auszahlung" Click="PaymentWindowButton_Click"
Margin="260,320,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>
</Window>

View File

@@ -41,7 +41,7 @@ namespace Elwig.Windows {
private void PdfButton_Click(object sender, RoutedEventArgs evt) {
Utils.RunBackground("PDF Generation", async () => {
using var ctx = new AppDbContext();
using var doc = new DeliveryNote(ctx.Deliveries.OrderBy(d => d.Parts.Count).ThenBy(d => d.Year).ThenBy(d => d.DId).Last());
using var doc = new DeliveryNote(ctx.Deliveries.OrderBy(d => d.Parts.Count).ThenBy(d => d.Year).ThenBy(d => d.DId).Last(), ctx);
await doc.Generate();
doc.Show();
});
@@ -56,5 +56,15 @@ namespace Elwig.Windows {
var w = new QueryWindow();
w.Show();
}
private void BaseDataButton_Click(object sender, RoutedEventArgs evt) {
var w = new BaseDataWindow();
w.Show();
}
private void PaymentWindowButton_Click(object sender, RoutedEventArgs e) {
var w = new ChartWindow();
w.Show();
}
}
}

View File

@@ -155,6 +155,10 @@
<Label Content="Alter:" Margin="85,100,0,0" Grid.Column="1" Grid.ColumnSpan="3"/>
<TextBlock x:Name="Age" Text="-" Margin="119,104,0,0" Grid.Column="1" Grid.ColumnSpan="3" TextWrapping="NoWrap" VerticalAlignment="Top"/>
<CheckBox x:Name="DeceasedInput" Content="Verstorben" IsEnabled="False"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
Grid.Column="3" HorizontalAlignment="Left" Margin="0,105,0,0" VerticalAlignment="Top" IsChecked="False"/>
<Label Content="Adresse:" Margin="10,130,0,0"/>
<TextBox x:Name="AddressInput" Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="3"
TextChanged="TextBox_TextChanged"/>
@@ -175,8 +179,8 @@
</Grid.ColumnDefinitions>
<Label Content="E-Mail-Adresse:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="EmailInput" Margin="0,10,10,0" Grid.Column="1" Grid.ColumnSpan="2"
TextChanged="EmailInput_TextChanged" LostFocus="EmailInput_LostFocus"/>
<TextBox x:Name="EmailAddressInput" Margin="0,10,10,0" Grid.Column="1" Grid.ColumnSpan="2"
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
<ComboBox x:Name="PhoneNr1TypeInput" DisplayMemberPath="Value" Margin="6,40,5,0" FontSize="12" Padding="6,4,4,4"/>
<TextBox x:Name="PhoneNr1Input" Margin="0,40,5,0" Grid.Column="1"
@@ -258,10 +262,10 @@
</Grid.ColumnDefinitions>
<Label Content="UID:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="UstIdNrInput" Margin="0,10,10,0" Grid.Column="1" Width="120" HorizontalAlignment="Left"
<TextBox x:Name="UstIdNrInput" Margin="0,10,10,0" Grid.Column="1" Width="96" HorizontalAlignment="Left"
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
<Label Content="BetriebsNr.:" Margin="10,40,0,0" Grid.Column="0"/>
<Label Content="Betriebs-Nr.:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="LfbisNrInput" Margin="0,40,10,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
@@ -328,7 +332,7 @@
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
Grid.Column="2" HorizontalAlignment="Left" Margin="10,75,0,0" VerticalAlignment="Top" IsChecked="False"/>
<Label Content="StammZwst.:" Margin="10,130,0,0" Grid.Column="0"/>
<Label Content="Stamm-Zwst.:" Margin="10,130,0,0" Grid.Column="0"/>
<ComboBox x:Name="BranchInput" DisplayMemberPath="Name" TextSearch.TextPath="Name"
Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="2"/>

View File

@@ -106,6 +106,7 @@ namespace Elwig.Windows {
AreaCommitmentButton.IsEnabled = false;
DeliveryButton.IsEnabled = false;
ClearOriginalValues();
ClearDefaultValues();
ClearInputs(validate);
ClearInputStates();
}
@@ -113,13 +114,20 @@ namespace Elwig.Windows {
}
private async void InitInputs() {
ClearOriginalValues();
ClearDefaultValues();
MgNrInput.Text = (await Context.NextMgNr()).ToString();
EntryDateInput.Text = DateTime.Now.ToString("dd.MM.yyyy");
if (Context.Branches.Count() == 1)
BranchInput.SelectedItem = Context.Branches.First();
ActiveInput.IsChecked = true;
ContactPostalInput.IsChecked = true;
FinishInputFilling();
SetDefaultValue(MgNrInput);
SetDefaultValue(EntryDateInput);
SetDefaultValue(ActiveInput);
ValidateRequiredInputs();
}
protected override async Task RenewContext() {
@@ -335,11 +343,12 @@ namespace Elwig.Windows {
m.FamilyName = FamilyNameInput.Text;
m.Suffix = (SuffixInput.Text == "") ? null : SuffixInput.Text;
m.Birthday = (BirthdayInput.Text == "") ? null : string.Join("-", BirthdayInput.Text.Split(".").Reverse());
m.IsDeceased = DeceasedInput.IsChecked ?? false;
m.CountryNum = 40; // Austria AT AUT
m.PostalDestId = ((AT_PlzDest)OrtInput.SelectedItem).Id;
m.Address = AddressInput.Text;
m.Email = (EmailInput.Text == "") ? null : EmailInput.Text;
m.Email = (EmailAddressInput.Text == "") ? null : EmailAddressInput.Text;
m.Iban = (IbanInput.Text == "") ? null : IbanInput.Text.Replace(" ", "");
m.Bic = (BicInput.Text == "") ? null : BicInput.Text;
@@ -438,6 +447,7 @@ namespace Elwig.Windows {
private void FillInputs(Member m) {
ClearOriginalValues();
ClearDefaultValues();
MgNrInput.Text = m.MgNr.ToString();
PredecessorMgNrInput.Text = m.PredecessorMgNr.ToString();
@@ -453,6 +463,7 @@ namespace Elwig.Windows {
} else {
Age.Text = "-";
}
DeceasedInput.IsChecked = m.IsDeceased;
AddressInput.Text = m.Address;
AT_PlzDest? p = m.PostalDest.AtPlz;
if (p != null) {
@@ -463,7 +474,7 @@ namespace Elwig.Windows {
OrtInput.SelectedItem = null;
}
EmailInput.Text = m.Email;
EmailAddressInput.Text = m.Email;
var phoneNrs = m.TelephoneNumbers.OrderBy(p => p.Nr).ToList();
for (int i = 0; i < PhoneNrInputs.Length; i++) {
if (i < phoneNrs.Count) {

View File

@@ -16,5 +16,7 @@
<Button x:Name="WeighingButton1" Click="WeighingButton1_Click" Height="30" Content="Aktuelles Gewicht" Width="110" Margin="515,246,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Button x:Name="WeighingButton2" Click="WeighingButton2_Click" Height="30" Content="Wiegen" Width="110" Margin="515,285,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock x:Name="Output" Height="20" Width="200" Margin="470,329,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click"
Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>
</Window>

View File

@@ -34,5 +34,10 @@ namespace Elwig.Windows {
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void ChartButton_Click(object sender, RoutedEventArgs evt) {
var w = new ChartWindow();
w.Show();
}
}
}