Compare commits

..

10 Commits

Author SHA1 Message Date
f5d3a04cb1 Bump version to 0.13.2
All checks were successful
Test / Run tests (push) Successful in 1m50s
Deploy / Build and Deploy (push) Successful in 2m6s
2024-10-13 19:08:20 +02:00
0675c45617 Elwig: Use ExecuteSql/FromSql instead of ExecuteSqlRaw/FromSqlRaw where possible
All checks were successful
Test / Run tests (push) Successful in 1m42s
2024-10-13 18:24:40 +02:00
d1f67dc57d BaseDataWindow: Fix WineAttr/WineCult Id updates in payment variant data
All checks were successful
Test / Run tests (push) Successful in 2m10s
2024-10-13 18:18:31 +02:00
3cbffdbf27 Documents: Add DeliveryDepreciationList
All checks were successful
Test / Run tests (push) Successful in 1m55s
2024-10-13 11:54:18 +02:00
e247925472 Controls: Fix blurry borders when system scaling is enabled
All checks were successful
Test / Run tests (push) Successful in 2m21s
2024-10-12 14:25:24 +02:00
a1b3cff624 [#11] Tests: Add DeliveryServiceTest
All checks were successful
Test / Run tests (push) Successful in 1m56s
2024-10-07 23:43:22 +02:00
65498dd18f App: Fix BranchLocation shortening
All checks were successful
Test / Run tests (push) Successful in 1m46s
2024-10-05 19:31:59 +02:00
27dc4f648f [#11] Tests: Add MemberServiceTest 2024-10-05 19:31:51 +02:00
86f7f693a0 Export/Bki: Format house nr that excel interprets it correctly
All checks were successful
Test / Run tests (push) Successful in 2m10s
2024-10-02 11:08:14 +02:00
8680e51052 Weighing: Fix scale L320 for Baden 2024-10-02 10:45:04 +02:00
46 changed files with 1913 additions and 128 deletions

View File

@ -3,6 +3,32 @@ Changelog
========= =========
[v0.13.2][v0.13.2] (2024-10-13) {#v0.13.2}
------------------------------------------
### Neue Funktionen {#0.13.2-features}
* Im Lieferungen-Fenster den Menüpunkt _Abwerteliste_ (`DeliveryDepreciationList`) hinzugefügt. (3cbffdbf27)
### Behobene Fehler {#0.13.2-bugfixes}
* Fehler im Waagenprotokoll `Avery-Async` (L320) behoben. (8680e51052)
* Hausnummern in der BKI Traubentransportscheinliste werden in Excel richtig angezeigt. (86f7f693a0)
* Beim Ändern der Identifikatoren von Attributen/Bewirtschaftungsarten wurden diese in Auszahlungsvarianten nicht aktualisiert. (d1f67dc57d)
### Sonstiges {#0.13.2-misc}
* Weitere automatisierte Tests hinzugefügt. ([#11][i11])
* Namenszusätze bei Gemeinden (z.B. an, bei, im, am) genauer angegeben. (65498dd18f)
* Bei einigen Eingabefeldern waren die Ränder unscharf. (e247925472)
* Wo leicht möglich wird `ExecuteSql`/`FromSql` statt `ExecuteSqlRaw`/`FromSqlRaw` verwendet. (0675c45617)
[v0.13.2]: https://git.necronda.net/winzer/elwig/releases/tag/v0.13.2
[i11]: https://git.necronda.net/winzer/elwig/issues/11
[v0.13.1][v0.13.1] (2024-09-29) {#v0.13.1} [v0.13.1][v0.13.1] (2024-09-29) {#v0.13.1}
------------------------------------------ ------------------------------------------

View File

@ -7,9 +7,6 @@ using Elwig.Helpers;
using Elwig.Helpers.Weighing; using Elwig.Helpers.Weighing;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Threading; using System.Windows.Threading;
using System.Globalization;
using System.Threading;
using System.Windows.Markup;
using System.Reflection; using System.Reflection;
using Elwig.Helpers.Printing; using Elwig.Helpers.Printing;
using Elwig.Windows; using Elwig.Windows;
@ -62,7 +59,7 @@ namespace Elwig {
MainDispatcher = Dispatcher; MainDispatcher = Dispatcher;
Scales = []; Scales = [];
CurrentApp = this; CurrentApp = this;
OverrideCulture(); Utils.OverrideCulture();
var args = Environment.GetCommandLineArgs(); var args = Environment.GetCommandLineArgs();
if (args.Length >= 2) { if (args.Length >= 2) {
@ -82,23 +79,6 @@ namespace Elwig {
MainDispatcher.BeginInvoke(HintContextChange); MainDispatcher.BeginInvoke(HintContextChange);
} }
private static void OverrideCulture() {
var locale = new CultureInfo("de-AT", false);
locale.NumberFormat.CurrencyGroupSeparator = Utils.GroupSeparator;
locale.NumberFormat.NumberGroupSeparator = Utils.GroupSeparator;
locale.NumberFormat.PercentGroupSeparator = Utils.GroupSeparator;
CultureInfo.CurrentCulture = locale;
CultureInfo.CurrentUICulture = locale;
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
CultureInfo.DefaultThreadCurrentCulture = locale;
CultureInfo.DefaultThreadCurrentUICulture = locale;
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.Name))
);
}
protected override async void OnStartup(StartupEventArgs evt) { protected override async void OnStartup(StartupEventArgs evt) {
Version = new Version(typeof(App).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split('+')[0] ?? "0.0.0"); Version = new Version(typeof(App).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split('+')[0] ?? "0.0.0");
@ -183,6 +163,9 @@ namespace Elwig {
} }
private async void Application_Exit(object sender, ExitEventArgs evt) { private async void Application_Exit(object sender, ExitEventArgs evt) {
foreach (var s in EventScales) {
s.Dispose();
}
await Pdf.Cleanup(); await Pdf.Cleanup();
} }
@ -194,7 +177,13 @@ namespace Elwig {
ZwstId = entry.Item1; ZwstId = entry.Item1;
BranchName = entry.Item2; BranchName = entry.Item2;
BranchPlz = entry.Item3; BranchPlz = entry.Item3;
BranchLocation = entry.Item4?.Split(" im ")[0].Split(" an ")[0].Split(" bei ")[0]; // FIXME BranchLocation = entry.Item4?
.Split(" in ")[0]
.Split(" im ")[0]
.Split(" an ")[0]
.Split(" am ")[0]
.Split(" bei ")[0]
.Split(" beim ")[0];
BranchAddress = entry.Item5; BranchAddress = entry.Item5;
BranchPhoneNr = entry.Item6; BranchPhoneNr = entry.Item6;
BranchFaxNr = entry.Item7; BranchFaxNr = entry.Item7;
@ -202,6 +191,7 @@ namespace Elwig {
} }
public static void HintContextChange() { public static void HintContextChange() {
if (CurrentApp == null) return;
var ch = CurrentLastWrite; var ch = CurrentLastWrite;
if (ch > CurrentApp.LastChanged) if (ch > CurrentApp.LastChanged)
CurrentApp.LastChanged = ch; CurrentApp.LastChanged = ch;

View File

@ -15,9 +15,8 @@
<ColumnDefinition Width="18"/> <ColumnDefinition Width="18"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border x:Name="Border" BorderThickness="1,1,0,1" <Border x:Name="Border" BorderThickness="1,1,0,1" Grid.RowSpan="2"
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
SnapsToDevicePixels="True" Grid.RowSpan="2">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center"/> <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center"/>
</Border> </Border>
@ -43,6 +42,8 @@
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="TextAlignment" Value="Right"/> <Setter Property="TextAlignment" Value="Right"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsEnabled" Value="False"> <Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Gray"/> <Setter Property="Foreground" Value="Gray"/>

View File

@ -7,8 +7,7 @@
<ControlTemplate TargetType="ctrl:UnitTextBox"> <ControlTemplate TargetType="ctrl:UnitTextBox">
<Border x:Name="Border" <Border x:Name="Border"
BorderThickness="{Binding Path=BorderThickness, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" BorderThickness="{Binding Path=BorderThickness, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
SnapsToDevicePixels="True">
<Grid Background="{Binding Path=Background, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"> <Grid Background="{Binding Path=Background, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Bottom"> <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Bottom">
<ScrollViewer.Margin> <ScrollViewer.Margin>
@ -32,6 +31,8 @@
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="TextAlignment" Value="Right"/> <Setter Property="TextAlignment" Value="Right"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsEnabled" Value="False"> <Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Gray"/> <Setter Property="Foreground" Value="Gray"/>

View File

@ -9,8 +9,8 @@
<table class="credit"> <table class="credit">
<colgroup> <colgroup>
<col style="width: 25mm;"/> <col style="width: 25mm;"/>
<col style="width: 5mm;"/> <col style="width: 6mm;"/>
<col style="width: 22mm;"/> <col style="width: 21mm;"/>
<col style="width: 15mm;"/> <col style="width: 15mm;"/>
<col style="width: 10mm;"/> <col style="width: 10mm;"/>
<col style="width: 10mm;"/> <col style="width: 10mm;"/>
@ -51,7 +51,7 @@
<tr class="@(i == 0 ? "first" : "") @(rows == i + 1 ? "last" : "")"> <tr class="@(i == 0 ? "first" : "") @(rows == i + 1 ? "last" : "")">
@if (i == 0) { @if (i == 0) {
<td rowspan="@rows">@p.LsNr</td> <td rowspan="@rows">@p.LsNr</td>
<td rowspan="@rows">@p.DPNr</td> <td rowspan="@rows" class="center narrow">@p.DPNr</td>
<td class="small">@p.Variety</td> <td class="small">@p.Variety</td>
<td class="small"> <td class="small">
@p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation @p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation

View File

@ -9,8 +9,8 @@
<table class="delivery-confirmation"> <table class="delivery-confirmation">
<colgroup> <colgroup>
<col style="width: 25mm;"/> <col style="width: 25mm;"/>
<col style="width: 5mm;"/> <col style="width: 6mm;"/>
<col style="width: 24mm;"/> <col style="width: 23mm;"/>
<col style="width: 16mm;"/> <col style="width: 16mm;"/>
<col style="width: 17mm;"/> <col style="width: 17mm;"/>
<col style="width: 10mm;"/> <col style="width: 10mm;"/>
@ -60,7 +60,7 @@
<tr class="@(first ? "first" : "") @(p.Variety != lastVariety && lastVariety != "" ? "new": "") @(rows > i + 1 ? "last" : "")"> <tr class="@(first ? "first" : "") @(p.Variety != lastVariety && lastVariety != "" ? "new": "") @(rows > i + 1 ? "last" : "")">
@if (first) { @if (first) {
<td rowspan="@rows">@p.LsNr</td> <td rowspan="@rows">@p.LsNr</td>
<td rowspan="@rows">@p.DPNr</td> <td rowspan="@rows" class="center narrow">@p.DPNr</td>
<td class="small">@p.Variety</td> <td class="small">@p.Variety</td>
<td class="small">@p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation</td> <td class="small">@p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation</td>
<td class="small">@p.QualityLevel</td> <td class="small">@p.QualityLevel</td>

View File

@ -0,0 +1,22 @@
using Elwig.Models.Dtos;
using System.Collections.Generic;
namespace Elwig.Documents {
public class DeliveryDepreciationList : Document {
public new static string Name => "Abwertungsliste";
public string Filter;
public IEnumerable<DeliveryJournalRow> Deliveries;
public DeliveryDepreciationList(string filter, IEnumerable<DeliveryJournalRow> deliveries) :
base($"{Name} {filter}") {
Filter = filter;
Deliveries = deliveries;
}
public DeliveryDepreciationList(string filter, DeliveryJournalData data) :
this(filter, data.Rows) {
}
}
}

View File

@ -0,0 +1,104 @@
@using RazorLight
@inherits TemplatePage<Elwig.Documents.DeliveryDepreciationList>
@model Elwig.Documents.DeliveryDepreciationList
@{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\DeliveryDepreciationList.css" />
<main>
<h1>Abwertungsliste</h1>
<h2>@Model.Filter</h2>
<table class="journal">
<colgroup>
<col style="width: 25mm;"/>
<col style="width: 6mm;"/>
<col style="width: 20mm;"/>
<col style="width: 15mm;"/>
<col style="width: 35mm;"/>
<col style="width: 30mm;"/>
<col style="width: 10mm;"/>
<col style="width: 10mm;"/>
<col style="width: 14mm;"/>
</colgroup>
<thead>
<tr>
<th rowspan="2" style="text-align: left;">Lieferschein-Nr.</th>
<th rowspan="2" class="narrow">Pos.</th>
<th rowspan="2">Datum</th>
<th rowspan="2">Zeit</th>
<th rowspan="2" style="text-align: left;">Sorte</th>
<th rowspan="2" style="text-align: left;">Attr./Bewirt.</th>
<th colspan="2">Gradation</th>
<th>Gewicht</th>
</tr>
<tr>
<th class="unit">[°Oe]</th>
<th class="unit narrow">[°KMW]</th>
<th class="unit">[kg]</th>
</tr>
</thead>
<tbody>
@{
int? lastMember = null;
}
@foreach (var p in Model.Deliveries) {
if (lastMember != p.MgNr) {
<tr class="subheading @(lastMember != null ? "new" : "")">
@{
var memberDeliveries = Model.Deliveries.Where(d => d.MgNr == p.MgNr).ToList();
var memberKmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(memberDeliveries);
var memberOe = Elwig.Helpers.Utils.KmwToOe(memberKmw);
}
<th colspan="5">
@($"{p.MgNr}, {p.AdministrativeName}")
</th>
<td>Teil-Lfrg.: <span style="float: right;">@($"{memberDeliveries.Count():N0}")</span></td>
<td class="center">@($"{memberOe:N0}")</td>
<td class="center">@($"{memberKmw:N1}")</td>
<td class="number">@($"{memberDeliveries.Sum(p => p.Weight):N0}")</td>
</tr>
}
<tr>
<td>@p.LsNr</td>
<td class="center narrow">@p.Pos</td>
<td>@($"{p.Date:dd.MM.yyyy}")</td>
<td>@($"{p.Time:HH:mm}")</td>
<td>@p.Variety</td>
<td>@p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation</td>
<td class="center">@($"{p.Oe:N0}")</td>
<td class="center">@($"{p.Kmw:N1}")</td>
<td class="number">@($"{p.Weight:N0}")</td>
</tr>
lastMember = p.MgNr;
}
@{
var branches = Model.Deliveries.Select(d => d.DeliveryBranch).Distinct().Order().ToArray();
if (branches.Length > 1) {
foreach (var b in branches) {
<tr class="@(branches[0] == b ? "sum" : "") bold">
@{
var branchDeliveries = Model.Deliveries.Where(d => d.DeliveryBranch == b).ToList();
var branchKmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(branchDeliveries);
var branchOe = Elwig.Helpers.Utils.KmwToOe(branchKmw);
}
<td colspan="2">@b:</td>
<td colspan="4">(Teil-)Lieferungen: @($"{branchDeliveries.DistinctBy(p => p.LsNr).Count():N0}") (@($"{branchDeliveries.Count():N0}"))</td>
<td class="center">@($"{branchOe:N0}")</td>
<td class="center">@($"{branchKmw:N1}")</td>
<td class="number">@($"{branchDeliveries.Sum(p => p.Weight):N0}")</td>
</tr>
}
}
}
<tr class="sum bold">
@{
var kmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(Model.Deliveries);
var oe = Elwig.Helpers.Utils.KmwToOe(kmw);
}
<td colspan="2">Gesamt:</td>
<td colspan="4">(Teil-)Lieferungen: @($"{Model.Deliveries.DistinctBy(p => p.LsNr).Count():N0}") (@($"{Model.Deliveries.Count():N0}"))</td>
<td class="center">@($"{oe:N0}")</td>
<td class="center">@($"{kmw:N1}")</td>
<td class="number">@($"{Model.Deliveries.Sum(p => p.Weight):N0}")</td>
</tr>
</tbody>
</table>
</main>

View File

@ -0,0 +1,13 @@
h1 {
text-align: center;
font-size: 24pt;
margin-top: 10mm;
margin-bottom: 2mm;
}
h2 {
text-align: center;
font-size: 14pt;
margin-top: 2mm;
}

View File

@ -9,7 +9,8 @@ namespace Elwig.Documents {
public string Filter; public string Filter;
public IEnumerable<DeliveryJournalRow> Deliveries; public IEnumerable<DeliveryJournalRow> Deliveries;
public DeliveryJournal(string filter, IEnumerable<DeliveryJournalRow> deliveries) : base($"{Name} {filter}") { public DeliveryJournal(string filter, IEnumerable<DeliveryJournalRow> deliveries) :
base($"{Name} {filter}") {
Filter = filter; Filter = filter;
Deliveries = deliveries; Deliveries = deliveries;
} }

View File

@ -9,10 +9,10 @@
<table class="journal"> <table class="journal">
<colgroup> <colgroup>
<col style="width: 25mm;"/> <col style="width: 25mm;"/>
<col style="width: 5mm;"/> <col style="width: 6mm;"/>
<col style="width: 15mm;"/> <col style="width: 15mm;"/>
<col style="width: 8mm;"/> <col style="width: 8mm;"/>
<col style="width: 12mm;"/> <col style="width: 11mm;"/>
<col style="width: 38mm;"/> <col style="width: 38mm;"/>
<col style="width: 28mm;"/> <col style="width: 28mm;"/>
<col style="width: 10mm;"/> <col style="width: 10mm;"/>
@ -41,7 +41,7 @@
@foreach (var p in Model.Deliveries) { @foreach (var p in Model.Deliveries) {
<tr> <tr>
<td>@p.LsNr</td> <td>@p.LsNr</td>
<td>@p.Pos</td> <td class="center narrow">@p.Pos</td>
<td class="small">@($"{p.Date:dd.MM.yyyy}")</td> <td class="small">@($"{p.Date:dd.MM.yyyy}")</td>
<td class="small">@($"{p.Time:HH:mm}")</td> <td class="small">@($"{p.Time:HH:mm}")</td>
<td class="number">@p.MgNr</td> <td class="number">@p.MgNr</td>
@ -52,6 +52,25 @@
<td class="number">@($"{p.Weight:N0}")</td> <td class="number">@($"{p.Weight:N0}")</td>
</tr> </tr>
} }
@{
var branches = Model.Deliveries.Select(d => d.DeliveryBranch).Distinct().Order().ToArray();
if (branches.Length > 1) {
foreach (var b in branches) {
<tr class="@(branches[0] == b ? "sum" : "") bold">
@{
var branchDeliveries = Model.Deliveries.Where(d => d.DeliveryBranch == b).ToList();
var branchKmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(branchDeliveries);
var branchOe = Elwig.Helpers.Utils.KmwToOe(branchKmw);
}
<td colspan="2">@b:</td>
<td colspan="5">(Teil-)Lieferungen: @($"{branchDeliveries.DistinctBy(p => p.LsNr).Count():N0}") (@($"{branchDeliveries.Count():N0}"))</td>
<td class="center">@($"{branchOe:N0}")</td>
<td class="center">@($"{branchKmw:N1}")</td>
<td class="number">@($"{branchDeliveries.Sum(p => p.Weight):N0}")</td>
</tr>
}
}
}
<tr class="sum bold"> <tr class="sum bold">
@{ @{
var kmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(Model.Deliveries); var kmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(Model.Deliveries);

View File

@ -78,6 +78,8 @@ namespace Elwig.Documents {
name = "CreditNote"; name = "CreditNote";
} else if (this is DeliveryJournal) { } else if (this is DeliveryJournal) {
name = "DeliveryJournal"; name = "DeliveryJournal";
} else if (this is DeliveryDepreciationList) {
name = "DeliveryDepreciationList";
} else if (this is Letterhead) { } else if (this is Letterhead) {
name = "Letterhead"; name = "Letterhead";
} else if (this is DeliveryConfirmation) { } else if (this is DeliveryConfirmation) {

View File

@ -7,7 +7,7 @@
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<PreserveCompilationContext>true</PreserveCompilationContext> <PreserveCompilationContext>true</PreserveCompilationContext>
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon> <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
<Version>0.13.1</Version> <Version>0.13.2</Version>
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>

View File

@ -22,7 +22,7 @@ namespace Elwig.Helpers.Export {
"""; """;
var c = App.Client; var c = App.Client;
var (a1, a2) = Utils.SplitAddress(c.Address); var (a1, a2) = Utils.SplitAddress(c.Address);
_clientData = $"{c.LfbisNr};{c.NameFull};;{a1};{a2};{c.Plz};{c.Ort}"; _clientData = $"{c.LfbisNr};{c.NameFull};;{a1};\t{a2};{c.Plz};{c.Ort}";
} }
public async Task ExportAsync(int year) { public async Task ExportAsync(int year) {
@ -35,7 +35,7 @@ namespace Elwig.Helpers.Export {
WHERE year = {year} WHERE year = {year}
"""; """;
var r = await cmd.ExecuteReaderAsync(); var r = await cmd.ExecuteReaderAsync();
List<Row> rows = new(); List<Row> rows = [];
while (await r.ReadAsync()) { while (await r.ReadAsync()) {
rows.Add(new( rows.Add(new(
(r.IsDBNull(0) ? null : r.GetString(0), r.IsDBNull(1) ? null : r.GetString(1), r.IsDBNull(2) ? null : r.GetString(2), r.IsDBNull(3) ? null : r.GetString(3), r.GetString(4), r.GetInt32(5), r.GetString(6), r.GetInt32(7)), (r.IsDBNull(0) ? null : r.GetString(0), r.IsDBNull(1) ? null : r.GetString(1), r.IsDBNull(2) ? null : r.GetString(2), r.IsDBNull(3) ? null : r.GetString(3), r.GetString(4), r.GetInt32(5), r.GetString(6), r.GetInt32(7)),
@ -57,7 +57,7 @@ namespace Elwig.Helpers.Export {
var (n1, n2) = billingName == null ? (familyName, name) : Utils.SplitName(billingName, familyName); var (n1, n2) = billingName == null ? (familyName, name) : Utils.SplitName(billingName, familyName);
var (a1, a2) = Utils.SplitAddress(address); var (a1, a2) = Utils.SplitAddress(address);
var memberData = $"{lfBisNr};{n1};{n2};{a1};{a2};{plz};{ort}"; var memberData = $"{lfBisNr};{n1};{n2};{a1};\t{a2};{plz};{ort}";
var deliveryData = $"{string.Join(".", date.Split("-").Reverse())};{weight};TB;{(type == "W" ? "J" : "")};{(type == "R" ? "J" : "")};{sortid};;;{qualid};{year};{hkid};{kmw:0.0};{oe:0}"; var deliveryData = $"{string.Join(".", date.Split("-").Reverse())};{weight};TB;{(type == "W" ? "J" : "")};{(type == "R" ? "J" : "")};{sortid};;;{qualid};{year};{hkid};{kmw:0.0};{oe:0}";
var vollData = $"N;;;{area / 10_000.0}"; var vollData = $"N;;;{area / 10_000.0}";

View File

@ -23,7 +23,7 @@ namespace Elwig.Helpers {
} }
public static string? ReadUntil(this StreamReader reader, char delimiter) { public static string? ReadUntil(this StreamReader reader, char delimiter) {
return ReadUntil(reader, new char[] { delimiter }); return ReadUntil(reader, [ delimiter ]);
} }
public static string? ReadUntil(this StreamReader reader, char[] delimiter) { public static string? ReadUntil(this StreamReader reader, char[] delimiter) {
@ -45,7 +45,7 @@ namespace Elwig.Helpers {
} }
public static Task<string?> ReadUntilAsync(this StreamReader reader, char delimiter) { public static Task<string?> ReadUntilAsync(this StreamReader reader, char delimiter) {
return ReadUntilAsync(reader, new char[] { delimiter }); return ReadUntilAsync(reader, [ delimiter ]);
} }
public static async Task<string?> ReadUntilAsync(this StreamReader reader, char[] delimiter) { public static async Task<string?> ReadUntilAsync(this StreamReader reader, char[] delimiter) {

View File

@ -28,6 +28,9 @@ using LinqKit;
using System.Linq.Expressions; using System.Linq.Expressions;
using Elwig.Models; using Elwig.Models;
using Microsoft.Win32; using Microsoft.Win32;
using System.Globalization;
using System.Threading;
using System.Windows.Markup;
namespace Elwig.Helpers { namespace Elwig.Helpers {
public static partial class Utils { public static partial class Utils {
@ -118,6 +121,23 @@ namespace Elwig.Helpers {
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
]; ];
public static void OverrideCulture() {
var locale = new CultureInfo("de-AT", false);
locale.NumberFormat.CurrencyGroupSeparator = Utils.GroupSeparator;
locale.NumberFormat.NumberGroupSeparator = Utils.GroupSeparator;
locale.NumberFormat.PercentGroupSeparator = Utils.GroupSeparator;
CultureInfo.CurrentCulture = locale;
CultureInfo.CurrentUICulture = locale;
Thread.CurrentThread.CurrentCulture = locale;
Thread.CurrentThread.CurrentUICulture = locale;
CultureInfo.DefaultThreadCurrentCulture = locale;
CultureInfo.DefaultThreadCurrentUICulture = locale;
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.Name))
);
}
public static SerialPort OpenSerialConnection(string connection) { public static SerialPort OpenSerialConnection(string connection) {
var m = SerialRegex.Match(connection); var m = SerialRegex.Match(connection);
if (!m.Success) if (!m.Success)

View File

@ -58,11 +58,19 @@ namespace Elwig.Helpers.Weighing {
} }
protected async Task<WeighingResult?> Receive() { protected async Task<WeighingResult?> Receive() {
var line = await Reader.ReadUntilAsync("\r\n"); var line = "";
while (line.Length < 33) {
var ch = Reader.Read();
if (ch == -1) {
return null;
} else if (line.Length > 0 || ch == ' ') {
line += char.ToString((char)ch);
}
}
if (LogPath != null) await File.AppendAllTextAsync(LogPath, line); if (LogPath != null) await File.AppendAllTextAsync(LogPath, line);
if (line == null || line == "") { if (line == null || line == "") {
return null; return null;
} else if (line.Length != 35 || line[0] != ' ' || line[9] != ' ' || line[15] != ' ' || line[20] != ' ' || line[32] != ' ') { } else if (line.Length != 33 || line[0] != ' ' || line[9] != ' ' || line[15] != ' ' || line[20] != ' ' || line[32] != ' ') {
throw new IOException($"Invalid event from scale: '{line}'"); throw new IOException($"Invalid event from scale: '{line}'");
} }

View File

@ -34,7 +34,7 @@ namespace Elwig.Models.Dtos {
} }
private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) { private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
return await table.FromSqlRaw($""" return await table.FromSql($"""
SELECT m.mgnr, m.name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,

View File

@ -49,7 +49,7 @@ namespace Elwig.Models.Dtos {
} }
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) { private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) {
return await table.FromSqlRaw($""" return await table.FromSql($"""
SELECT m.mgnr, m.name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,

View File

@ -36,7 +36,7 @@ namespace Elwig.Models.Dtos {
} }
private static async Task<IEnumerable<MemberDeliveryPerVariantRowSingle>> FromDbSet(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) { private static async Task<IEnumerable<MemberDeliveryPerVariantRowSingle>> FromDbSet(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) {
return await table.FromSqlRaw($""" return await table.FromSql($"""
SELECT m.mgnr, m.name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,

View File

@ -25,7 +25,7 @@ namespace Elwig.Models.Dtos {
} }
public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) { public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) {
var rows = await table.FromSqlRaw($""" var rows = await table.FromSql($"""
SELECT m.mgnr, m.name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,

View File

@ -49,7 +49,7 @@ namespace Elwig.Models.Dtos {
} }
private static async Task<IEnumerable<PaymentVariantSummaryRow>> FromDbSet(DbSet<PaymentVariantSummaryRow> table, int year, int avnr) { private static async Task<IEnumerable<PaymentVariantSummaryRow>> FromDbSet(DbSet<PaymentVariantSummaryRow> table, int year, int avnr) {
return await table.FromSqlRaw($""" return await table.FromSql($"""
SELECT v.type AS type, SELECT v.type AS type,
v.name AS variety, v.name AS variety,
a.name AS attribute, a.name AS attribute,

View File

@ -230,7 +230,7 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
if (oldDsNr != null && (oldYear != year || oldDsNr != dsnr || oldMgNr != newMgNr || oldSortId != newSortId)) { if (oldDsNr != null && (oldYear != year || oldDsNr != dsnr || oldMgNr != newMgNr || oldSortId != newSortId)) {
await ctx.Database.ExecuteSqlRawAsync($"UPDATE delivery_announcement SET year = {year}, dsnr = {dsnr}, mgnr = {newMgNr}, sortid = '{newSortId}' WHERE (year, dsnr, mgnr, sortid) = ({a.Year}, {a.DsNr}, {a.MgNr}, '{a.SortId}')"); await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_announcement SET year = {year}, dsnr = {dsnr}, mgnr = {newMgNr}, sortid = {newSortId} WHERE (year, dsnr, mgnr, sortid) = ({a.Year}, {a.DsNr}, {a.MgNr}, {a.SortId})");
} }
} }

View File

@ -24,7 +24,7 @@ namespace Elwig.Services {
public static class DeliveryService { public static class DeliveryService {
public enum ExportSubject { public enum ExportSubject {
FromFilters, FromToday, FromSeasonAndBranch, Selected, FromFilters, FromToday, FromSeason, FromSeasonAndBranch, Selected,
}; };
public static async Task<Member?> GetMemberAsync(int mgnr) { public static async Task<Member?> GetMemberAsync(int mgnr) {
@ -462,7 +462,7 @@ namespace Elwig.Services {
LNr = newLnr ?? oldDelivery!.LNr, LNr = newLnr ?? oldDelivery!.LNr,
ZwstId = vm.Branch!.ZwstId, ZwstId = vm.Branch!.ZwstId,
LsNr = newLsNr ?? vm.LsNr!, LsNr = newLsNr ?? vm.LsNr!,
MgNr = (int)vm.MgNr!, MgNr = vm.MgNr!.Value,
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment, Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
}; };
@ -474,7 +474,7 @@ namespace Elwig.Services {
SortId = vm.WineVar!.SortId, SortId = vm.WineVar!.SortId,
AttrId = vm.WineAttr?.AttrId, AttrId = vm.WineAttr?.AttrId,
CultId = vm.WineCult?.CultId, CultId = vm.WineCult?.CultId,
Kmw = (double)vm.GradationKmw!, Kmw = vm.GradationKmw!.Value,
QualId = vm.WineQualityLevel!.QualId, QualId = vm.WineQualityLevel!.QualId,
HkId = vm.WineOrigin!.HkId, HkId = vm.WineOrigin!.HkId,
KgNr = vm.WineKg?.KgNr, KgNr = vm.WineKg?.KgNr,
@ -488,7 +488,7 @@ namespace Elwig.Services {
Acid = vm.Acid, Acid = vm.Acid,
Comment = string.IsNullOrEmpty(vm.PartComment) ? null : vm.PartComment, Comment = string.IsNullOrEmpty(vm.PartComment) ? null : vm.PartComment,
Weight = (int)vm.Weight!, Weight = vm.Weight!.Value,
IsManualWeighing = vm.IsManualWeighing, IsManualWeighing = vm.IsManualWeighing,
ScaleId = vm.ScaleId, ScaleId = vm.ScaleId,
WeighingData = vm.WeighingData, WeighingData = vm.WeighingData,
@ -809,6 +809,71 @@ namespace Elwig.Services {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
public static async Task GenerateDeliveryDepreciationList(this DeliveryAdminViewModel vm, ExportSubject subject, ExportMode mode) {
using var ctx = new AppDbContext();
IQueryable<DeliveryPart> query;
List<string> filterNames = [];
if (subject == ExportSubject.FromFilters) {
var (f, _, q, _, _) = await vm.GetFilters(ctx);
query = q;
filterNames.AddRange(f);
} else if (subject == ExportSubject.FromSeason) {
var year = vm.FilterSeason ?? Utils.CurrentLastSeason;
query = ctx.DeliveryParts
.Where(p => p.Year == year);
filterNames.Add($"{year}");
} else {
throw new ArgumentException("Invalid value for ExportSubject");
}
query = query
.Where(p => p.QualId == "WEI")
.OrderBy(p => p.Delivery.MgNr)
.ThenBy(p => p.Delivery.DateString)
.ThenBy(p => p.Delivery.TimeString)
.ThenBy(p => p.Delivery.LsNr)
.ThenBy(p => p.DPNr);
filterNames.Remove("abgewertet");
if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() {
FileName = $"{DeliveryDepreciationList.Name}-{vm.FilterSeason ?? Utils.CurrentLastSeason}.ods",
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ods = new OdsFile(d.FileName);
var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames);
tblTotal.FullName = DeliveryDepreciationList.Name;
tblTotal.Name = "Gesamt";
await ods.AddTable(tblTotal);
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
tbl.FullName = DeliveryDepreciationList.Name;
tbl.Name = branch.Name;
await ods.AddTable(tbl);
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
}
} else {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
}
}
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) { private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
var tb = new TextBlock() { var tb = new TextBlock() {
Text = text, Text = text,
@ -971,5 +1036,13 @@ namespace Elwig.Services {
return (wGrid, gGrid); return (wGrid, gGrid);
} }
public static async Task DeleteDelivery(string lsnr) {
using (var ctx = new AppDbContext()) {
await ctx.Deliveries.Where(d => d.LsNr == lsnr).ExecuteDeleteAsync();
await ctx.SaveChangesAsync();
}
App.HintContextChange();
}
} }
} }

View File

@ -25,7 +25,7 @@ namespace Elwig.Services {
public static async Task InitInputs(this MemberAdminViewModel vm) { public static async Task InitInputs(this MemberAdminViewModel vm) {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
vm.MgNrString = $"{await ctx.NextMgNr()}"; vm.MgNr = await ctx.NextMgNr();
vm.EntryDate = DateTime.Now.ToString("dd.MM.yyyy"); vm.EntryDate = DateTime.Now.ToString("dd.MM.yyyy");
if (vm.BranchSource.Count() == 1) if (vm.BranchSource.Count() == 1)
vm.Branch = vm.BranchSource.First(); vm.Branch = vm.BranchSource.First();
@ -53,8 +53,8 @@ namespace Elwig.Services {
public static void FillInputs(this MemberAdminViewModel vm, Member m) { public static void FillInputs(this MemberAdminViewModel vm, Member m) {
vm.IsMemberSelected = true; vm.IsMemberSelected = true;
vm.MgNrString = $"{m.MgNr}"; vm.MgNr = m.MgNr;
vm.PredecessorMgNrString = $"{m.PredecessorMgNr}"; vm.PredecessorMgNr = m.PredecessorMgNr;
vm.IsJuridicalPerson = m.IsJuridicalPerson; vm.IsJuridicalPerson = m.IsJuridicalPerson;
vm.EnableMemberReferenceButton = m.PredecessorMgNr != null; vm.EnableMemberReferenceButton = m.PredecessorMgNr != null;
vm.Prefix = m.Prefix; vm.Prefix = m.Prefix;
@ -73,10 +73,10 @@ namespace Elwig.Services {
vm.IsDeceased = m.IsDeceased; vm.IsDeceased = m.IsDeceased;
vm.Address = m.Address; vm.Address = m.Address;
if (m.PostalDest.AtPlz is AT_PlzDest p) { if (m.PostalDest.AtPlz is AT_PlzDest p) {
vm.PlzString = $"{p.Plz}"; vm.Plz = p.Plz;
vm.Ort = ControlUtils.GetItemFromSource(vm.OrtSource, p); vm.Ort = ControlUtils.GetItemFromSource(vm.OrtSource, p);
} else { } else {
vm.PlzString = null; vm.Plz = null;
vm.Ort = null; vm.Ort = null;
} }
@ -114,19 +114,19 @@ namespace Elwig.Services {
vm.BillingName = billingAddr.FullName; vm.BillingName = billingAddr.FullName;
vm.BillingAddress = billingAddr.Address; vm.BillingAddress = billingAddr.Address;
if (billingAddr.PostalDest.AtPlz is AT_PlzDest b) { if (billingAddr.PostalDest.AtPlz is AT_PlzDest b) {
vm.BillingPlzString = $"{b.Plz}"; vm.BillingPlz = b.Plz;
vm.BillingOrt = ControlUtils.GetItemFromSource(vm.BillingOrtSource, b); vm.BillingOrt = ControlUtils.GetItemFromSource(vm.BillingOrtSource, b);
} }
} else { } else {
vm.BillingName = null; vm.BillingName = null;
vm.BillingAddress = null; vm.BillingAddress = null;
vm.BillingPlzString = null; vm.BillingPlz = null;
vm.BillingOrt = null; vm.BillingOrt = null;
} }
vm.EntryDate = (m.EntryDateString != null) ? string.Join(".", m.EntryDateString.Split("-").Reverse()) : null; vm.EntryDate = (m.EntryDateString != null) ? string.Join(".", m.EntryDateString.Split("-").Reverse()) : null;
vm.ExitDate = (m.ExitDateString != null) ? string.Join(".", m.ExitDateString.Split("-").Reverse()) : null; vm.ExitDate = (m.ExitDateString != null) ? string.Join(".", m.ExitDateString.Split("-").Reverse()) : null;
vm.BusinessSharesString = $"{m.BusinessShares}"; vm.BusinessShares = m.BusinessShares;
vm.AccountingNr = m.AccountingNr; vm.AccountingNr = m.AccountingNr;
vm.Branch = (Branch?)ControlUtils.GetItemFromSourceWithPk(vm.BranchSource, m.ZwstId); vm.Branch = (Branch?)ControlUtils.GetItemFromSourceWithPk(vm.BranchSource, m.ZwstId);
vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr); vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr);
@ -148,6 +148,8 @@ namespace Elwig.Services {
vm.StatusAreaCommitmentToolTip = null; vm.StatusAreaCommitmentToolTip = null;
Utils.RunBackground("Mitgliederdaten laden", async () => { Utils.RunBackground("Mitgliederdaten laden", async () => {
if (App.MainDispatcher == null)
return;
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var d1 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason - 1 && d.MgNr == m.MgNr); var d1 = ctx.Deliveries.Where(d => d.Year == Utils.CurrentLastSeason - 1 && d.MgNr == m.MgNr);
@ -652,5 +654,23 @@ namespace Elwig.Services {
return newMgNr; return newMgNr;
} }
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
using (var ctx = new AppDbContext()) {
var l = (await ctx.Members.FindAsync(mgnr))!;
if (deletePaymentData) {
ctx.RemoveRange(l.Credits);
}
if (deleteDeliveries) {
ctx.RemoveRange(l.Deliveries);
}
if (deleteAreaComs) {
ctx.RemoveRange(l.AreaCommitments);
}
ctx.Remove(l);
await ctx.SaveChangesAsync();
}
App.HintContextChange();
}
} }
} }

View File

@ -96,10 +96,16 @@ namespace Elwig.ViewModels {
private IEnumerable<object> _wineCultSource = []; private IEnumerable<object> _wineCultSource = [];
[ObservableProperty] [ObservableProperty]
private string? _gradationOeString; private string? _gradationOeString;
public double? GradationOe => double.TryParse(GradationOeString, out var oe) ? oe : null; public double? GradationOe {
get => double.TryParse(GradationOeString, out var oe) ? oe : null;
set => GradationOeString = $"{value:0}";
}
[ObservableProperty] [ObservableProperty]
private string? _gradationKmwString; private string? _gradationKmwString;
public double? GradationKmw => double.TryParse(GradationKmwString, out var kmw) ? kmw : null; public double? GradationKmw {
get => double.TryParse(GradationKmwString, out var kmw) ? kmw : null;
set => GradationKmwString = $"{value:0.0}";
}
[ObservableProperty] [ObservableProperty]
private WineQualLevel? _wineQualityLevel; private WineQualLevel? _wineQualityLevel;
[ObservableProperty] [ObservableProperty]
@ -152,10 +158,16 @@ namespace Elwig.ViewModels {
private string? _partComment; private string? _partComment;
[ObservableProperty] [ObservableProperty]
private string? _temperatureString; private string? _temperatureString;
public double? Temperature => double.TryParse(TemperatureString, out var t) ? t : null; public double? Temperature {
get => double.TryParse(TemperatureString, out var t) ? t : null;
set => TemperatureString = $"{value:0.0}";
}
[ObservableProperty] [ObservableProperty]
private string? _acidString; private string? _acidString;
public double? Acid => double.TryParse(AcidString, out var a) ? a : null; public double? Acid {
get => double.TryParse(AcidString, out var a) ? a : null;
set => AcidString = $"{value:0.0}";
}
[ObservableProperty] [ObservableProperty]
private bool _isLesewagen; private bool _isLesewagen;
[ObservableProperty] [ObservableProperty]

View File

@ -50,10 +50,16 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private string? _mgNrString; private string? _mgNrString;
public int? MgNr => int.TryParse(MgNrString, out var mgnr) ? mgnr : null; public int? MgNr {
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
set => MgNrString = $"{value}";
}
[ObservableProperty] [ObservableProperty]
private string? _predecessorMgNrString; private string? _predecessorMgNrString;
public int? PredecessorMgNr => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null; public int? PredecessorMgNr {
get => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null;
set => PredecessorMgNrString = $"{value}";
}
[ObservableProperty] [ObservableProperty]
private bool _isJuridicalPerson; private bool _isJuridicalPerson;
[ObservableProperty] [ObservableProperty]
@ -76,7 +82,10 @@ namespace Elwig.ViewModels {
private string? _address; private string? _address;
[ObservableProperty] [ObservableProperty]
private string? _plzString; private string? _plzString;
public int? Plz => int.TryParse(PlzString, out var plz) ? plz : null; public int? Plz {
get => int.TryParse(PlzString, out var plz) ? plz : null;
set => PlzString = $"{value}";
}
[ObservableProperty] [ObservableProperty]
private AT_PlzDest? _ort; private AT_PlzDest? _ort;
[ObservableProperty] [ObservableProperty]
@ -88,7 +97,10 @@ namespace Elwig.ViewModels {
private string? _billingAddress; private string? _billingAddress;
[ObservableProperty] [ObservableProperty]
private string? _billingPlzString; private string? _billingPlzString;
public int? BillingPlz => int.TryParse(BillingPlzString, out var plz) ? plz : null; public int? BillingPlz {
get => int.TryParse(BillingPlzString, out var plz) ? plz : null;
set => BillingPlzString = $"{value}";
}
[ObservableProperty] [ObservableProperty]
private AT_PlzDest? _billingOrt; private AT_PlzDest? _billingOrt;
[ObservableProperty] [ObservableProperty]
@ -114,7 +126,10 @@ namespace Elwig.ViewModels {
private string? _exitDate; private string? _exitDate;
[ObservableProperty] [ObservableProperty]
private string? _businessSharesString; private string? _businessSharesString;
public int? BusinessShares => int.TryParse(BusinessSharesString, out var bs) ? bs : null; public int? BusinessShares {
get => int.TryParse(BusinessSharesString, out var bs) ? bs : null;
set => BusinessSharesString = $"{value}";
}
[ObservableProperty] [ObservableProperty]
private string? _accountingNr; private string? _accountingNr;
[ObservableProperty] [ObservableProperty]
@ -147,6 +162,14 @@ namespace Elwig.ViewModels {
public string? _number = number; public string? _number = number;
[ObservableProperty] [ObservableProperty]
public string? _comment = comment; public string? _comment = comment;
public override bool Equals(object? obj) {
return obj is PhoneNr nr && Type == nr.Type && Number == nr.Number && Comment == nr.Comment;
}
public override int GetHashCode() {
return Type ^ (Number?.GetHashCode() ?? 0) ^ (Comment?.GetHashCode() ?? 0);
}
} }
public ObservableCollection<PhoneNr> PhoneNrs { get; private set; } = [new(), new(), new(), new(), new(), new(), new(), new(), new()]; public ObservableCollection<PhoneNr> PhoneNrs { get; private set; } = [new(), new(), new(), new(), new(), new(), new(), new(), new()];

View File

@ -58,6 +58,8 @@ namespace Elwig.Windows {
foreach (var (old, attrid) in _attrs.Where(a => a.Value != null)) { foreach (var (old, attrid) in _attrs.Where(a => a.Value != null)) {
await ctx.Database.ExecuteSqlAsync($"UPDATE wine_attribute SET attrid = {attrid} WHERE attrid = {old}"); await ctx.Database.ExecuteSqlAsync($"UPDATE wine_attribute SET attrid = {attrid} WHERE attrid = {old}");
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment_type SET vtrgid = (sortid || COALESCE(attrid, '') || COALESCE(disc, '')) WHERE attrid = {attrid}");
await ctx.Database.ExecuteSqlRawAsync($"UPDATE payment_variant SET data = REPLACE(REPLACE(data, '/{old}\"', '/{attrid}\"'), '/{old}-', '/{attrid}-')");
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();

View File

@ -58,6 +58,7 @@ namespace Elwig.Windows {
foreach (var (old, cultid) in _cults.Where(c => c.Value != null)) { foreach (var (old, cultid) in _cults.Where(c => c.Value != null)) {
await ctx.Database.ExecuteSqlAsync($"UPDATE wine_cultivation SET cultid = {cultid} WHERE cultid = {old}"); await ctx.Database.ExecuteSqlAsync($"UPDATE wine_cultivation SET cultid = {cultid} WHERE cultid = {old}");
await ctx.Database.ExecuteSqlRawAsync($"UPDATE payment_variant SET data = REPLACE(data, '-{old}\"', '-{cultid}\"')");
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();

View File

@ -120,6 +120,25 @@
<MenuItem x:Name="Menu_WineQualityStatistics_ModeKmw1" Header="...nach °KMW aufschlüsseln (ganze)" IsCheckable="True" <MenuItem x:Name="Menu_WineQualityStatistics_ModeKmw1" Header="...nach °KMW aufschlüsseln (ganze)" IsCheckable="True"
Click="Menu_WineQualityStatistics_Mode_Click"/> Click="Menu_WineQualityStatistics_Mode_Click"/>
</MenuItem> </MenuItem>
<MenuItem Header="Abwertungsliste" x:Name="Menu_DeliveryDepreciationList">
<MenuItem x:Name="Menu_DeliveryDepreciationList_SaveFilters" Header="...aus Filtern speichern... (Excel)"
Click="Menu_DeliveryDepreciationList_SaveFilters_Click"/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_ShowFilters" Header="...aus Filtern anzeigen (PDF)"
Click="Menu_DeliveryDepreciationList_ShowFilters_Click"/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_SavePdfFilters" Header="...aus Filtern speichern... (PDF)"
Click="Menu_DeliveryDepreciationList_SavePdfFilters_Click"/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_PrintFilters" Header="...aus Filtern drucken"
Click="Menu_DeliveryDepreciationList_PrintFilters_Click"/>
<Separator/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_SaveSeason" Header="...von Saison speichern... (Excel)"
Click="Menu_DeliveryDepreciationList_SaveSeason_Click"/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_ShowSeason" Header="...von Saison anzeigen (PDF)"
Click="Menu_DeliveryDepreciationList_ShowSeason_Click"/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_SavePdfSeason" Header="...von Saison speichern... (PDF)"
Click="Menu_DeliveryDepreciationList_SavePdfSeason_Click"/>
<MenuItem x:Name="Menu_DeliveryDepreciationList_PrintSeason" Header="...von Saison drucken"
Click="Menu_DeliveryDepreciationList_PrintSeason_Click"/>
</MenuItem>
<MenuItem Header="BKI"> <MenuItem Header="BKI">
<MenuItem x:Name="Menu_Bki_SaveList" Header="Traubentransportscheinliste speichern..."/> <MenuItem x:Name="Menu_Bki_SaveList" Header="Traubentransportscheinliste speichern..."/>
</MenuItem> </MenuItem>

View File

@ -172,9 +172,11 @@ namespace Elwig.Windows {
Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig" Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
using var file = new Bki(d.FileName); using var file = new Bki(d.FileName);
await file.ExportAsync(year); await file.ExportAsync(year);
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@ -250,6 +252,23 @@ namespace Elwig.Windows {
await App.Client.UpdateValues(); await App.Client.UpdateValues();
} }
private async void Menu_DeliveryDepreciationList_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
private async void Menu_DeliveryDepreciationList_ShowFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromFilters, ExportMode.Show);
private async void Menu_DeliveryDepreciationList_SavePdfFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromFilters, ExportMode.SavePdf);
private async void Menu_DeliveryDepreciationList_PrintFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromFilters, ExportMode.Print);
private async void Menu_DeliveryDepreciationList_SaveSeason_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromSeason, ExportMode.SaveList);
private async void Menu_DeliveryDepreciationList_ShowSeason_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromSeason, ExportMode.Show);
private async void Menu_DeliveryDepreciationList_SavePdfSeason_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromSeason, ExportMode.SavePdf);
private async void Menu_DeliveryDepreciationList_PrintSeason_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDepreciationList(DeliveryService.ExportSubject.FromSeason, ExportMode.Print);
private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) { private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) {
if (IsEditing || IsCreating) { if (IsEditing || IsCreating) {
DateInput.IsReadOnly = false; DateInput.IsReadOnly = false;
@ -933,12 +952,13 @@ namespace Elwig.Windows {
"Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.AppStarting;
using (var ctx = new AppDbContext()) { try {
ctx.Remove(d); await DeliveryService.DeleteDelivery(d.LsNr);
await ctx.SaveChangesAsync(); } 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, "Lieferung löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
await RefreshList();
await RefreshDeliveryParts();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }

View File

@ -360,21 +360,7 @@ namespace Elwig.Windows {
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.AppStarting;
try { try {
using (var ctx = new AppDbContext()) { await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
var l = (await ctx.Members.FindAsync(m.MgNr))!;
if (d.DeletePaymentData) {
ctx.RemoveRange(l.Credits);
}
if (d.DeleteDeliveries) {
ctx.RemoveRange(l.Deliveries);
}
if (d.DeleteAreaComs) {
ctx.RemoveRange(l.AreaCommitments);
}
ctx.Remove(l);
await ctx.SaveChangesAsync();
}
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; 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; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;

View File

@ -30,6 +30,11 @@ namespace Tests {
await BillingData.Init(); await BillingData.Init();
} }
[OneTimeSetUp]
public void Setup_4_Culture() {
Utils.OverrideCulture();
}
[OneTimeTearDown] [OneTimeTearDown]
public async Task TeardownDatabase() { public async Task TeardownDatabase() {
AppDbContext.ConnectionStringOverride = null; AppDbContext.ConnectionStringOverride = null;

View File

@ -29,9 +29,10 @@ namespace Tests.DocumentTests {
Assert.That(text, Contains.Substring("AT81 1234 5678 9012 3457")); Assert.That(text, Contains.Substring("AT81 1234 5678 9012 3457"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
20201001X001 1 Grüner Veltliner 73 15,0 ungeb.: 3 219 0,5000 - - 1 609,50 20201001X001 1 Grüner Veltliner 73 15,0 ungeb.: 3 219 0,5000 - - 1 609,50
20201001X003 1 Grüner Veltliner 75 15,4 ungeb.: 2 561 - - 20201001X003 1 Grüner Veltliner abgew. 75 15,4 ungeb.: 2 561 - -
20201001X003 2 Grüner Veltliner Kabinett 87 17,6 ungeb.: 3 129 - - 20201001X003 2 Grüner Veltliner Kabinett / abgew.
20201001X003 3 Grüner Veltliner 79 16,1 ungeb.: 1 280 - - 87 17,6 ungeb.: 3 129 - -
20201001X003 3 Grüner Veltliner abgew. 79 16,1 ungeb.: 1 280 - -
20201001X005 1 Welschriesling 84 17,0 ungeb.: 3 192 - - 20201001X005 1 Welschriesling 84 17,0 ungeb.: 3 192 - -
20201001X005 2 Welschriesling 84 17,1 ungeb.: 2 190 - - 20201001X005 2 Welschriesling 84 17,1 ungeb.: 2 190 - -
""")); """));

View File

@ -24,10 +24,10 @@ namespace Tests.DocumentTests {
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}")); Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
Assert.That(text, Contains.Substring("Anlieferungsbestätigung 2020")); Assert.That(text, Contains.Substring("Anlieferungsbestätigung 2020"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
20201001X003 2 Grüner Veltliner Kabinett Kabinett 87 17,6 ungeb.: 3 129 3 129
20201001X003 3 Grüner Veltliner Qualitätswein 79 16,1 ungeb.: 1 280 1 280
20201001X003 1 Grüner Veltliner Qualitätswein 75 15,4 ungeb.: 2 561 2 561
20201001X001 1 Grüner Veltliner Qualitätswein 73 15,0 ungeb.: 3 219 3 219 20201001X001 1 Grüner Veltliner Qualitätswein 73 15,0 ungeb.: 3 219 3 219
20201001X003 2 Grüner Veltliner Kabinett Wein 87 17,6 ungeb.: 3 129 3 129
20201001X003 3 Grüner Veltliner Wein 79 16,1 ungeb.: 1 280 1 280
20201001X003 1 Grüner Veltliner Wein 75 15,4 ungeb.: 2 561 2 561
20201001X005 2 Welschriesling Kabinett 84 17,1 ungeb.: 2 190 2 190 20201001X005 2 Welschriesling Kabinett 84 17,1 ungeb.: 2 190 2 190
20201001X005 1 Welschriesling Kabinett 84 17,0 ungeb.: 3 192 3 192 20201001X005 1 Welschriesling Kabinett 84 17,0 ungeb.: 3 192 3 192
""")); """));

View File

@ -0,0 +1,32 @@
using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Models.Dtos;
namespace Tests.DocumentTests {
[TestFixture]
public class DeliveryDepreciationListTest {
[Test]
public async Task Test_01_DepreciatedDeliveries2020() {
using var ctx = new AppDbContext();
var data = await DeliveryJournalData.FromQuery(ctx.Deliveries.Where(d => d.Year == 2020).SelectMany(d => d.Parts).Where(d => d.QualId == "WEI"), ["Saison 2020"]);
using var doc = new DeliveryDepreciationList("Saison 2020", data);
var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text);
Assert.Multiple(() => {
Assert.That(text, Contains.Substring("Abwertungsliste"));
Assert.That(text, Contains.Substring("Saison 2020"));
Assert.That(table, Is.EqualTo(new string[][] {
["101, MUSTERMANN Max", "Teil-Lfrg.:", "3", "81", "16,5", "6 970"],
["20201001X003 1 01.10.2020 10:24", "Grüner Veltliner", "75", "15,4", "2 561"],
["20201001X003 2 01.10.2020 10:24", "Grüner Veltliner", "Kabinett", "87", "17,6", "3 129"],
["20201001X003 3 01.10.2020 10:24", "Grüner Veltliner", "79", "16,1", "1 280"],
["103, MUSTERBAUER Matthäus", "Teil-Lfrg.:", "2", "79", "16,2", "6 099"],
["20201002X001 1 02.10.2020 09:13", "Grüner Veltliner", "Bio", "80", "16,3", "3 198"],
["20201002X002 1 02.10.2020 09:28", "Grüner Veltliner", "Bio", "78", "16,0", "2 901"],
["Gesamt:", "(Teil-)Lieferungen: 3 (5)", "80", "16,3", "13 069"],
}));
});
}
}
}

View File

@ -84,20 +84,20 @@ namespace Tests.DocumentTests {
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X003")); Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X003"));
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht")); Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
1 Grüner Veltliner Qualitätswein 75 15,4 2 561 1 Grüner Veltliner Wein 75 15,4 2 561
Herkunft: Österreich / Weinland / Niederösterreich Herkunft: Österreich
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf / Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
Waage: ?, ID: ? (gerebelt gewogen) Waage: ?, ID: ? (gerebelt gewogen)
""")); """));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
2 Grüner Veltliner Kabinett Kabinett 87 17,6 3 129 2 Grüner Veltliner Kabinett Wein 87 17,6 3 129
Herkunft: Österreich / Weinland / Niederösterreich Herkunft: Österreich
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf / Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
Waage: ?, ID: ? (gerebelt gewogen) Waage: ?, ID: ? (gerebelt gewogen)
""")); """));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
3 Grüner Veltliner Qualitätswein 79 16,1 1 280 3 Grüner Veltliner Wein 79 16,1 1 280
Herkunft: Österreich / Weinland / Niederösterreich Herkunft: Österreich
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf / Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
Waage: ?, ID: ? (gerebelt gewogen) Waage: ?, ID: ? (gerebelt gewogen)
""")); """));
@ -123,9 +123,9 @@ namespace Tests.DocumentTests {
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201002X001")); Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201002X001"));
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht")); Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
1 Grüner Veltliner Qualitätswein 80 16,3 3 198 1 Grüner Veltliner Wein 80 16,3 3 198
Bewirtschaftung: Bio (AT-BIO-302) Bewirtschaftung: Bio (AT-BIO-302)
Herkunft: Österreich / Weinland / Niederösterreich Herkunft: Österreich
/ Wolkersdorfer Hochleithen / Wolkersdorf im Weinviertel / KG Wolkersdorf / Wolkersdorfer Hochleithen / Wolkersdorf im Weinviertel / KG Wolkersdorf
Waage: ?, ID: ? (gerebelt gewogen) Waage: ?, ID: ? (gerebelt gewogen)
""")); """));

View File

@ -16,14 +16,19 @@ namespace Tests.DocumentTests {
Assert.That(text, Contains.Substring("Qualitätsstatistik")); Assert.That(text, Contains.Substring("Qualitätsstatistik"));
Assert.That(text, Contains.Substring("Saison 2020")); Assert.That(text, Contains.Substring("Saison 2020"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
Qualitätswein Wein
73 2 4 431 75 1 2 561
74 2 4 203
75 3 5 176
77 1 842
78 1 2 901 78 1 2 901
79 1 1 280 79 1 1 280
80 1 3 198 80 1 3 198
87 1 3 129
"""));
Assert.That(text, Contains.Substring("""
Qualitätswein
73 2 4 431
74 2 4 203
75 2 2 615
77 1 842
82 1 4 002 82 1 4 002
""")); """));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
@ -31,14 +36,14 @@ namespace Tests.DocumentTests {
84 3 8 960 84 3 8 960
85 3 11 181 85 3 11 181
86 1 2 987 86 1 2 987
87 2 5 002 87 1 1 873
89 2 4 723 89 2 4 723
""")); """));
Assert.That(text, Contains.Substring( Assert.That(text, Contains.Substring(
"80 5 " + "13 069 " +
"- 0 0 " + "- 0 0 " +
"- 0 0 " + "77 5 " + "11 568 " +
"77 12 " + "26 033 " + "85 6 " + "17 561"));
"86 11 " + "32 853"));
}); });
} }
} }

View File

@ -43,17 +43,17 @@ INSERT INTO delivery_part (year, did, dpnr, sortid, attrid, cultid, weight, kmw,
(2020, 1, 1, 'GV', NULL, NULL, 3219, 15.0, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, '1', '{"id":"321","nr":321,"gross_weight":3219,"tare_weight":0,"net_weight":3219,"date":"2020-10-01","time":"09:02:46"}', NULL), (2020, 1, 1, 'GV', NULL, NULL, 3219, 15.0, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, '1', '{"id":"321","nr":321,"gross_weight":3219,"tare_weight":0,"net_weight":3219,"date":"2020-10-01","time":"09:02:46"}', NULL),
(2020, 2, 1, 'GV', 'K', NULL, 2987, 17.5, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 2, 1, 'GV', 'K', NULL, 2987, 17.5, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 2, 2, 'GV', 'K', NULL, 1873, 17.7, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 2, 2, 'GV', 'K', NULL, 1873, 17.7, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 3, 1, 'GV', NULL, NULL, 2561, 15.4, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 3, 1, 'GV', NULL, NULL, 2561, 15.4, 'WEI', 'OEST', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 3, 2, 'GV', 'K', NULL, 3129, 17.6, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 3, 2, 'GV', 'K', NULL, 3129, 17.6, 'WEI', 'OEST', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 3, 3, 'GV', NULL, NULL, 1280, 16.1, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 3, 3, 'GV', NULL, NULL, 1280, 16.1, 'WEI', 'OEST', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 4, 1, 'GV', NULL, NULL, 4002, 16.7, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 4, 1, 'GV', NULL, NULL, 4002, 16.7, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 4, 2, 'GV', NULL, NULL, 481, 15.3, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 4, 2, 'GV', NULL, NULL, 481, 15.3, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 5, 1, 'WR', NULL, NULL, 3192, 17.0, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 5, 1, 'WR', NULL, NULL, 3192, 17.0, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 5, 2, 'WR', NULL, NULL, 2190, 17.1, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 5, 2, 'WR', NULL, NULL, 2190, 17.1, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 6, 1, 'GV', NULL, 'B', 1732, 15.2, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 6, 1, 'GV', NULL, 'B', 1732, 15.2, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 7, 1, 'GV', NULL, 'B', 3198, 16.3, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 7, 1, 'GV', NULL, 'B', 3198, 16.3, 'WEI', 'OEST', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 7, 2, 'GV', NULL, 'B', 2134, 15.4, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 7, 2, 'GV', NULL, 'B', 2134, 15.4, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 8, 1, 'GV', NULL, 'B', 2901, 16.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 8, 1, 'GV', NULL, 'B', 2901, 16.0, 'WEI', 'OEST', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 8, 2, 'GV', NULL, 'B', 3321, 17.3, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 8, 2, 'GV', NULL, 'B', 3321, 17.3, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 9, 1, 'WR', NULL, 'B', 3998, 17.2, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 9, 1, 'WR', NULL, 'B', 3998, 17.2, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2020, 10, 1, 'ZW', NULL, NULL, 1212, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL), (2020, 10, 1, 'ZW', NULL, NULL, 1212, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),

View File

@ -70,7 +70,7 @@ INSERT INTO member (mgnr, given_name, name, zwstid, volllieferant, buchführend,
(101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109, 'AT811234567890123457', '0123463', NULL ), (101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109, 'AT811234567890123457', '0123463', NULL ),
(102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684'), (102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684'),
(103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224, 'AT271234567890123459', '0123480', NULL ), (103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224, 'AT271234567890123459', '0123480', NULL ),
(104, 'Waltraud', 'Winzer', 'X', FALSE, FALSE, 40, 212005138, 'Wiener Straße 15', 15224, 'AT971234567890123460', '0123498', 'ATU12345693'); (104, 'Waltraud', 'Winzer', 'X', FALSE, TRUE , 40, 212005138, 'Wiener Straße 15', 15224, 'AT971234567890123460', '0123498', 'ATU12345693');
INSERT INTO member_billing_address (mgnr, name, country, postal_dest, address) VALUES INSERT INTO member_billing_address (mgnr, name, country, postal_dest, address) VALUES
(102, 'W&B Weinbauer GesbR', 40, 222303524, 'Winzerstraße 2'), (102, 'W&B Weinbauer GesbR', 40, 222303524, 'Winzerstraße 2'),

View File

@ -0,0 +1,11 @@
-- deletes for ServiceTests
DELETE FROM credit;
DELETE FROM payment_variant;
DELETE FROM delivery;
DELETE FROM season;
DELETE FROM area_commitment;
DELETE FROM area_commitment_type;
DELETE FROM member WHERE mgnr >= 200;
DELETE FROM wine_cultivation;
DELETE FROM wine_attribute;

View File

@ -0,0 +1,135 @@
-- inserts for ServiceTests
INSERT INTO wine_cultivation (cultid, name, description) VALUES
('B', 'Bio', 'AT-BIO-302');
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
('K', 'Kabinett', TRUE, NULL, FALSE, 0);
INSERT INTO member (mgnr, given_name, name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr, iban, lfbis_nr, ustid_nr) VALUES
(201, 'Theodor', 'Testbauer', 'X', FALSE, FALSE, 40, 222303524, 'Teststraße 1', 06109, 'AT811234567890123457', '0123463', NULL ),
(202, 'Thomas', 'Testmann', 'X', FALSE, FALSE, 40, 222303524, 'Teststraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684'),
(203, 'Tina', 'Testwinzer', 'X', FALSE, FALSE, 40, 212005138, 'Teststraße 3', 15224, 'AT271234567890123459', '0123480', NULL ),
(204, 'Trude', 'Testerin', 'X', FALSE, TRUE , 40, 212005138, 'Teststraße 4', 15224, 'AT971234567890123460', '0123498', 'ATU12345693');
INSERT INTO member_billing_address (mgnr, name, country, postal_dest, address) VALUES
(202, 'T&T Testmann GesbR', 40, 222303524, 'Teststraße 11'),
(203, 'Testwinzer GesbR', 40, 212005138, 'Teststraße 3' ),
(204, 'Trauben Trude GmbH', 40, 212205137, 'Teststraße 12');
INSERT INTO member_telephone_number (mgnr, nr, type, number, comment) VALUES
(203, 1, 'mobile', '+43 664 987654321', NULL),
(204, 1, 'mobile', '+43 664 123456789', NULL);
INSERT INTO member_email_address (mgnr, nr, address, comment) VALUES
(203, 1, 'tina@winzer.com', NULL),
(204, 1, 'trude@trauben.at', NULL);
INSERT INTO area_commitment_type (vtrgid, sortid, attrid, disc, min_kg_per_ha, penalty_per_kg, penalty_amount, penalty_none) VALUES
('GV', 'GV', NULL, NULL, 5000, 500, NULL, NULL);
INSERT INTO area_commitment (fbnr, mgnr, vtrgid, cultid, area, kgnr, gstnr, rdnr, year_from, year_to) VALUES
( 1, 203, 'GV', NULL, 10000, 15224, '321/9', NULL, NULL, NULL),
( 2, 204, 'GV', NULL, 10000, 15224, '123/1', NULL, 2000, 2019),
( 3, 204, 'GV', NULL, 10000, 15224, '123/2', NULL, 2025, 2030),
( 4, 204, 'GV', NULL, 10000, 15224, '123/3', NULL, 2021, 2031);
INSERT INTO season (year, currency, min_kg_per_bs, max_kg_per_bs, penalty_per_kg, penalty_amount, penalty_none, start_date, end_date) VALUES
(2021, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL),
(2022, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL),
(2023, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL);
INSERT INTO modifier (year, modid, ordering, name, abs, rel, active) VALUES
(2021, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, TRUE),
(2022, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, TRUE);
INSERT INTO delivery (mgnr, year, did, date, time, zwstid, lnr) VALUES
(203, 2021, 1, '2021-10-01', NULL, 'X', 1),
(204, 2021, 2, '2021-10-01', NULL, 'X', 2),
(101, 2022, 1, '2022-09-29', NULL, 'X', 1),
(101, 2022, 2, '2022-09-30', NULL, 'X', 1),
(101, 2023, 1, '2023-10-01', NULL, 'X', 1),
(101, 2023, 2, '2023-10-01', NULL, 'X', 2),
(101, 2023, 3, '2023-10-01', NULL, 'X', 3),
(101, 2023, 4, '2023-10-01', NULL, 'X', 4),
(101, 2023, 5, '2023-10-02', NULL, 'X', 1),
(101, 2023, 6, '2023-10-03', NULL, 'X', 1),
(101, 2023, 7, '2023-10-04', NULL, 'X', 1),
(101, 2023, 8, '2023-10-05', NULL, 'X', 1),
(101, 2023, 9, '2023-10-06', NULL, 'X', 1),
(101, 2023, 10, '2023-10-06', NULL, 'X', 2),
(101, 2023, 11, '2023-10-07', NULL, 'X', 1),
(101, 2023, 12, '2023-10-07', NULL, 'X', 2),
(101, 2023, 13, '2023-10-08', NULL, 'X', 1),
(101, 2023, 14, '2023-10-08', NULL, 'X', 2),
(101, 2023, 15, '2023-10-09', NULL, 'X', 1),
(101, 2023, 16, '2023-10-09', NULL, 'X', 2),
(101, 2023, 17, '2023-10-10', NULL, 'X', 1),
(101, 2023, 18, '2023-10-10', NULL, 'X', 2),
(101, 2023, 19, '2023-10-10', NULL, 'X', 3);
INSERT INTO delivery_part (year, did, dpnr, sortid, attrid, cultid, weight, kmw, qualid, hkid, kgnr, net_weight, manual_weighing, spl_check, scale_id, weighing_data, weighing_reason) VALUES
(2021, 1, 1, 'GV', NULL, NULL, 3500, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2021, 2, 1, 'GV', NULL, NULL, 4000, 17.0, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2021, 2, 2, 'GV', NULL, NULL, 4000, 16.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2022, 1, 1, 'GV', NULL, NULL, 3700, 16.5, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2022, 1, 2, 'GV', NULL, NULL, 3700, 16.5, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 1, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 1, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 1, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 2, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 2, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 2, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 3, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 3, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 3, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 4, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 4, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 4, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 5, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 5, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 5, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 6, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 6, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 6, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 7, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 7, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 7, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 8, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 8, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 8, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 9, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 9, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 9, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 10, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 11, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 11, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 11, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 12, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 13, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 13, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 13, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 14, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 15, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 15, 2, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 15, 3, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 16, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 17, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 18, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
(2023, 19, 1, 'GV', NULL, NULL, 1000, 15.0, 'QUW', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL);
INSERT INTO delivery_part_modifier (year, did, dpnr, modid) VALUES
(2021, 1, 1, 'S'),
(2021, 2, 2, 'S'),
(2022, 1, 2, 'S');
INSERT INTO payment_variant (year, avnr, name, date, transfer_date, test_variant, calc_time, comment, data) VALUES
(2021, 1, 'Probevariante', '2022-01-15', '2022-01-15', TRUE, NULL, NULL, '{"mode":"elwig","version":1,"payment":0.5,"curves":[]}');
INSERT INTO payment_member (year, avnr, mgnr, net_amount) VALUES
(2021, 1, 203, 10000000),
(2021, 1, 204, 10000000);
INSERT INTO credit (year, tgnr, mgnr, avnr, net_amount, prev_net_amount, vat, modifiers, prev_modifiers) VALUES
(2021, 1, 203, 1, 10000000, 0, 0.1, 0, 0),
(2021, 2, 204, 1, 10000000, 0, 0.1, 0, 0);

View File

@ -0,0 +1,847 @@
using Elwig.Helpers;
using Elwig.Models.Entities;
using Elwig.Services;
using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore;
namespace Tests.ServiceTests {
[TestFixture]
public class DeliveryServiceTest {
private static async Task InitViewModel(DeliveryAdminViewModel vm) {
using var ctx = new AppDbContext();
vm.MemberSource = await ctx.Members.ToListAsync();
vm.BranchSource = await ctx.Branches.ToListAsync();
vm.WineVarSource = await ctx.WineVarieties.ToListAsync();
List<object> attrs = (await ctx.WineAttributes.ToListAsync()).Cast<object>().ToList();
attrs.Insert(0, new NullItem());
vm.WineAttrSource = attrs;
List<object> cults = (await ctx.WineCultivations.ToListAsync()).Cast<object>().ToList();
cults.Insert(0, new NullItem());
vm.WineCultSource = cults;
vm.WineQualityLevelSource = await ctx.WineQualityLevels.ToListAsync();
vm.WineOriginSource = await ctx.WineOrigins.ToListAsync();
vm.WineKgSource = await ctx.Katastralgemeinden.ToListAsync();
vm.ModifiersSource = await ctx.Modifiers.Where(m => m.Year == 2022).ToListAsync();
}
private static async Task<Delivery?> GetDelivery(string lsnr) {
using var ctx = new AppDbContext();
return await ctx.Deliveries
.Where(d => d.LsNr == lsnr)
.Include(d => d.Parts)
.ThenInclude(p => p.PartModifiers)
.ThenInclude(m => m.Modifier)
.AsSplitQuery()
.FirstOrDefaultAsync();
}
private static DeliveryPart[] GetParts(Delivery d) {
return [.. d.Parts.OrderBy(p => p.DPNr)];
}
[Test]
public async Task TestCreate_01_Minimal() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
vm.Date = "01.10.2022";
vm.Branch = vm.BranchSource.First();
vm.MgNr = 101;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 15.0;
vm.GradationOe = 73;
vm.Weight = 1234;
vm.IsManualWeighing = true;
vm.IsNetWeight = false;
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "QUW");
vm.WineOrigin = vm.WineOriginSource.First(o => o.HkId == "WLNO");
var p1 = await vm.UpdateDeliveryPart(2022, null, null, false, false, true);
Assert.That(p1.Delivery.LsNr, Is.EqualTo("20221001X001"));
var d = await GetDelivery("20221001X001");
Assert.That(d, Is.Not.Null);
Assert.That(d.Parts, Has.Count.EqualTo(1));
var p = d.Parts.First();
Assert.That(p, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(d.LsNr, Is.EqualTo("20221001X001"));
Assert.That(d.Date, Is.EqualTo(new DateOnly(2022, 10, 1)));
Assert.That(d.ZwstId, Is.EqualTo("X"));
Assert.That(d.MgNr, Is.EqualTo(101));
Assert.That(p.SortId, Is.EqualTo("GV"));
Assert.That(p.AttrId, Is.Null);
Assert.That(p.CultId, Is.Null);
Assert.That(p.Kmw, Is.EqualTo(15.0));
Assert.That(p.Oe, Is.EqualTo(73));
Assert.That(p.QualId, Is.EqualTo("QUW"));
Assert.That(p.Weight, Is.EqualTo(1234));
Assert.That(p.IsNetWeight, Is.False);
Assert.That(p.IsManualWeighing, Is.True);
Assert.That(p.HkId, Is.EqualTo("WLNO"));
});
vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => {
vm.FillInputs(d);
vm.FillInputs(p);
});
Assert.Multiple(() => {
Assert.That(vm.LsNr, Is.EqualTo("20221001X001"));
Assert.That(vm.Date, Is.EqualTo("01.10.2022"));
Assert.That(vm.Branch?.ZwstId, Is.EqualTo("X"));
Assert.That(vm.MgNr, Is.EqualTo(101));
Assert.That(vm.SortId, Is.EqualTo("GV"));
Assert.That(vm.WineAttr?.AttrId, Is.Null);
Assert.That(vm.WineCult?.CultId, Is.Null);
Assert.That(vm.GradationKmw, Is.EqualTo(15.0));
Assert.That(vm.WineQualityLevel?.QualId, Is.EqualTo("QUW"));
Assert.That(vm.Weight, Is.EqualTo(1234));
Assert.That(vm.IsNetWeight, Is.False);
Assert.That(vm.IsManualWeighing, Is.True);
Assert.That(vm.WineOrigin?.HkId, Is.EqualTo("WLNO"));
});
}
[Test]
public async Task TestCreate_02_Advanced() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
vm.Date = "02.10.2022";
vm.Branch = vm.BranchSource.First();
vm.MgNr = 102;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
vm.SortId = "ZW";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.WineAttr = vm.WineAttrSource.Skip(1).First() as WineAttr;
vm.WineCult = vm.WineCultSource.Skip(1).First() as WineCult;
vm.GradationKmw = 15.9;
vm.GradationOe = 78;
vm.Weight = 3456;
vm.IsManualWeighing = false;
vm.IsNetWeight = true;
vm.WeighingData = "{}";
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "QUW");
vm.WineOrigin = vm.WineOriginSource.First(o => o.HkId == "WLNO");
vm.Modifiers.Add(vm.ModifiersSource.First());
var p1 = await vm.UpdateDeliveryPart(2022, null, null, false, false, true);
Assert.That(p1.Delivery.LsNr, Is.EqualTo("20221002X001"));
var d = await GetDelivery("20221002X001");
Assert.That(d, Is.Not.Null);
Assert.That(d.Parts, Has.Count.EqualTo(1));
var p = d.Parts.First();
Assert.That(p, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(d.LsNr, Is.EqualTo("20221002X001"));
Assert.That(d.Date, Is.EqualTo(new DateOnly(2022, 10, 2)));
Assert.That(d.ZwstId, Is.EqualTo("X"));
Assert.That(d.MgNr, Is.EqualTo(102));
Assert.That(p.SortId, Is.EqualTo("ZW"));
Assert.That(p.AttrId, Is.Not.Null);
Assert.That(p.CultId, Is.Not.Null);
Assert.That(p.Kmw, Is.EqualTo(15.9));
Assert.That(p.Oe, Is.EqualTo(78));
Assert.That(p.QualId, Is.EqualTo("QUW"));
Assert.That(p.Weight, Is.EqualTo(3456));
Assert.That(p.IsNetWeight, Is.True);
Assert.That(p.IsManualWeighing, Is.False);
Assert.That(p.WeighingData, Is.EqualTo("{}"));
Assert.That(p.HkId, Is.EqualTo("WLNO"));
Assert.That(p.Modifiers.Count(), Is.EqualTo(1));
});
vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => {
vm.FillInputs(d);
vm.FillInputs(p);
});
Assert.Multiple(() => {
Assert.That(vm.LsNr, Is.EqualTo("20221002X001"));
Assert.That(vm.Date, Is.EqualTo("02.10.2022"));
Assert.That(vm.Branch?.ZwstId, Is.EqualTo("X"));
Assert.That(vm.MgNr, Is.EqualTo(102));
Assert.That(vm.SortId, Is.EqualTo("ZW"));
Assert.That(vm.WineAttr?.AttrId, Is.Not.Null);
Assert.That(vm.WineCult?.CultId, Is.Not.Null);
Assert.That(vm.GradationKmw, Is.EqualTo(15.9));
Assert.That(vm.WineQualityLevel?.QualId, Is.EqualTo("QUW"));
Assert.That(vm.Weight, Is.EqualTo(3456));
Assert.That(vm.IsNetWeight, Is.True);
Assert.That(vm.IsManualWeighing, Is.False);
Assert.That(vm.WeighingData, Is.EqualTo("{}"));
Assert.That(vm.WineOrigin?.HkId, Is.EqualTo("WLNO"));
Assert.That(vm.Modifiers, Has.Count.EqualTo(1));
});
}
[Test]
public async Task TestCreate_03_TwoParts() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
vm.Date = "03.10.2022";
vm.Branch = vm.BranchSource.First();
vm.MgNr = 101;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 15.0;
vm.GradationOe = 73;
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "QUW");
vm.Weight = 1234;
vm.IsManualWeighing = true;
vm.IsNetWeight = true;
vm.WineOrigin = vm.WineOriginSource.First(o => o.HkId == "WLNO");
var p1 = await vm.UpdateDeliveryPart(2022, null, null, false, false, true);
Assert.That(p1.Delivery.LsNr, Is.EqualTo("20221003X001"));
vm.FillInputs(p1.Delivery);
vm.SortId = "WR";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 18.0;
vm.GradationOe = 89;
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "KAB");
vm.Weight = 2345;
var p2 = await vm.UpdateDeliveryPart(p1.Year, p1.DId, null, false, false, true);
Assert.That(p2.Delivery.LsNr, Is.EqualTo("20221003X001"));
var d = await GetDelivery("20221003X001");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(d.Parts, Has.Count.EqualTo(2));
Assert.That(d.MgNr, Is.EqualTo(101));
});
var p = d.Parts.First();
Assert.That(p, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(p.DPNr, Is.EqualTo(1));
Assert.That(p.SortId, Is.EqualTo("GV"));
});
p = d.Parts.Skip(1).First();
Assert.That(p, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(p.DPNr, Is.EqualTo(2));
Assert.That(p.SortId, Is.EqualTo("WR"));
});
}
[Test]
public async Task TestCreate_04_ChangeMember() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
vm.Date = "04.10.2022";
vm.Branch = vm.BranchSource.First();
vm.MgNr = 101;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 15.0;
vm.GradationOe = 73;
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "QUW");
vm.Weight = 1234;
vm.IsManualWeighing = true;
vm.IsNetWeight = true;
vm.WineOrigin = vm.WineOriginSource.First(o => o.HkId == "WLNO");
var p1 = await vm.UpdateDeliveryPart(2022, null, null, false, false, true);
Assert.That(p1.Delivery.LsNr, Is.EqualTo("20221004X001"));
vm.FillInputs(p1.Delivery);
vm.MgNr = 102;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 15.0;
vm.GradationOe = 73;
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "QUW");
vm.Weight = 1234;
vm.IsManualWeighing = true;
vm.IsNetWeight = true;
vm.WineOrigin = vm.WineOriginSource.First(o => o.HkId == "WLNO");
var p2 = await vm.UpdateDeliveryPart(p1.Year, p1.DId, null, false, false, true);
Assert.That(p2.Delivery.LsNr, Is.EqualTo("20221004X001"));
var d = await GetDelivery("20221004X001");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(d.Parts, Has.Count.EqualTo(2));
Assert.That(d.MgNr, Is.EqualTo(102));
});
}
[Test]
public async Task TestCreate_05_LNrChanged() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
vm.Date = "29.09.2022";
vm.Branch = vm.BranchSource.First();
vm.LsNr = "20220929X001"; // "old" LNr, simulated change in DB
vm.MgNr = 101;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 15.0;
vm.GradationOe = 73;
vm.WineQualityLevel = vm.WineQualityLevelSource.First(l => l.QualId == "QUW");
vm.Weight = 1234;
vm.IsManualWeighing = true;
vm.IsNetWeight = true;
vm.WineOrigin = vm.WineOriginSource.First(o => o.HkId == "WLNO");
var p1 = await vm.UpdateDeliveryPart(2022, null, null, false, false, true);
Assert.That(p1.Delivery.LsNr, Is.EqualTo("20220929X002"));
var d = GetDelivery("20220929X002");
Assert.That(d, Is.Not.Null);
}
[Test]
public async Task TestUpdate_01_Simple() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
var d = await GetDelivery("20231010X001");
Assert.That(d, Is.Not.Null);
var p = d.Parts.First();
Assert.That(p, Is.Not.Null);
Assert.DoesNotThrow(() => {
vm.FillInputs(d);
vm.FillInputs(p);
});
vm.SortId = "WR";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.GradationKmw = 15.9;
vm.GradationOe = 79;
Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, false, false, true));
d = await GetDelivery("20231010X001");
Assert.That(d, Is.Not.Null);
p = d.Parts.First();
Assert.That(p, Is.Not.Null);
vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => {
vm.FillInputs(d);
vm.FillInputs(p);
});
Assert.Multiple(() => {
Assert.That(vm.SortId, Is.EqualTo("WR"));
Assert.That(vm.GradationKmw, Is.EqualTo(15.9));
});
}
[Test]
public async Task TestUpdate_02_Member() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
var d = await GetDelivery("20231010X002");
Assert.That(d, Is.Not.Null);
var p = d.Parts.First();
Assert.That(p, Is.Not.Null);
Assert.DoesNotThrow(() => {
vm.FillInputs(d);
vm.FillInputs(p);
});
Assert.That(d.MgNr, Is.EqualTo(101));
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.MgNr = 102;
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, false, false, true));
d = await GetDelivery("20231010X002");
Assert.That(d, Is.Not.Null);
Assert.That(d.MgNr, Is.EqualTo(102));
}
[Test]
public async Task TestUpdate_03_DateAndTime() {
var vm = new DeliveryAdminViewModel();
await InitViewModel(vm);
var d = await GetDelivery("20231015X001");
Assert.That(d, Is.Null);
d = await GetDelivery("20231010X003");
Assert.That(d, Is.Not.Null);
var p = d.Parts.First();
Assert.That(p, Is.Not.Null);
Assert.DoesNotThrow(() => {
vm.FillInputs(d);
vm.FillInputs(p);
});
Assert.That(d.MgNr, Is.EqualTo(101));
vm.SortId = "GV";
vm.WineVar = vm.WineVarSource.First(v => v.SortId == vm.SortId);
vm.Date = "15.10.2023";
vm.Time = "12:00";
Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, true, true, false));
d = await GetDelivery("20231010X003");
Assert.That(d, Is.Null);
d = await GetDelivery("20231015X001");
Assert.That(d, Is.Not.Null);
}
[Test]
public async Task TestSplit_01_Depreciate_One() {
var d = await GetDelivery("20231001X001");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 0, 0]));
d = await GetDelivery("20231001X001");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
});
}
[Test]
public async Task TestSplit_02_Depreciate_Partial() {
var d = await GetDelivery("20231001X002");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [600, 0, 0]));
d = await GetDelivery("20231001X002");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(4));
Assert.That(ps[0].Weight, Is.EqualTo(400));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[3].Weight, Is.EqualTo(600));
Assert.That(ps[3].QualId, Is.EqualTo("WEI"));
});
}
[Test]
public async Task TestSplit_03_Depreciate_Mixed() {
var d = await GetDelivery("20231001X003");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].Weight, Is.EqualTo(1000));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 700, -5]));
d = await GetDelivery("20231001X003");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(4));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.EqualTo("WEI"));
Assert.That(ps[1].Weight, Is.EqualTo(300));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].Weight, Is.EqualTo(1000));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[3].Weight, Is.EqualTo(700));
Assert.That(ps[3].QualId, Is.EqualTo("WEI"));
});
}
[Test]
public async Task TestSplit_04_Depreciate_Complete() {
var d = await GetDelivery("20231001X004");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].Weight, Is.EqualTo(1000));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].Weight, Is.EqualTo(1000));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 1100, int.MaxValue]));
d = await GetDelivery("20231001X004");
Assert.That(d, Is.Not.Null);
Assert.Multiple(() => {
var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.EqualTo("WEI"));
Assert.That(ps[1].Weight, Is.EqualTo(1000));
Assert.That(ps[1].QualId, Is.EqualTo("WEI"));
Assert.That(ps[2].Weight, Is.EqualTo(1000));
Assert.That(ps[2].QualId, Is.EqualTo("WEI"));
});
}
[Test]
public async Task TestSplit_05_OtherMember_One() {
var d1 = await GetDelivery("20231002X001");
var d2 = await GetDelivery("20231002X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, 0, 0], 102));
d1 = await GetDelivery("20231002X001");
d2 = await GetDelivery("20231002X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(d2.MgNr, Is.EqualTo(102));
Assert.That(ps1, Has.Length.EqualTo(2));
Assert.That(ps1[0].DPNr, Is.EqualTo(2));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].DPNr, Is.EqualTo(3));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].DPNr, Is.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
});
}
[Test]
public async Task TestSplit_06_OtherMember_Partial() {
var d1 = await GetDelivery("20231003X001");
var d2 = await GetDelivery("20231003X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [400, -1, -2], 102));
d1 = await GetDelivery("20231003X001");
d2 = await GetDelivery("20231003X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(d2.MgNr, Is.EqualTo(102));
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(600));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(400));
});
}
[Test]
public async Task TestSplit_07_OtherMember_Mixed() {
var d1 = await GetDelivery("20231004X001");
var d2 = await GetDelivery("20231004X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [200, 1000, int.MinValue], 102));
d1 = await GetDelivery("20231004X001");
d2 = await GetDelivery("20231004X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(d2.MgNr, Is.EqualTo(102));
Assert.That(ps1, Has.Length.EqualTo(2));
Assert.That(ps1[0].DPNr, Is.EqualTo(1));
Assert.That(ps1[0].Weight, Is.EqualTo(800));
Assert.That(ps1[1].DPNr, Is.EqualTo(3));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(2));
Assert.That(ps2[0].DPNr, Is.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(200));
Assert.That(ps2[1].DPNr, Is.EqualTo(2));
Assert.That(ps2[1].Weight, Is.EqualTo(1000));
});
}
[Test]
public async Task TestSplit_08_OtherMember_Complete() {
var d1 = await GetDelivery("20231005X001");
var d2 = await GetDelivery("20231005X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, int.MaxValue, 1100], 102));
d1 = await GetDelivery("20231005X001");
d2 = await GetDelivery("20231005X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps2 = GetParts(d2);
Assert.That(d2.MgNr, Is.EqualTo(102));
Assert.That(ps2, Has.Length.EqualTo(3));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(1000));
Assert.That(ps2[2].Weight, Is.EqualTo(1000));
});
}
[Test]
public async Task TestSplit_09_OtherDelivery_One() {
var d1 = await GetDelivery("20231006X001");
var d2 = await GetDelivery("20231006X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 1000, -4], d2.LsNr));
d1 = await GetDelivery("20231006X001");
d2 = await GetDelivery("20231006X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(2));
Assert.That(ps1[0].DPNr, Is.EqualTo(1));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].DPNr, Is.EqualTo(3));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(2));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(1000));
});
}
[Test]
public async Task TestSplit_10_OtherDelivery_Partial() {
var d1 = await GetDelivery("20231007X001");
var d2 = await GetDelivery("20231007X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 300, int.MinValue], d2.LsNr));
d1 = await GetDelivery("20231007X001");
d2 = await GetDelivery("20231007X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(700));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(2));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(300));
});
}
[Test]
public async Task TestSplit_11_OtherDelivery_Mixed() {
var d1 = await GetDelivery("20231008X001");
var d2 = await GetDelivery("20231008X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [850, 1000, -4], d2.LsNr));
d1 = await GetDelivery("20231008X001");
d2 = await GetDelivery("20231008X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(2));
Assert.That(ps1[0].DPNr, Is.EqualTo(1));
Assert.That(ps1[0].Weight, Is.EqualTo(150));
Assert.That(ps1[1].DPNr, Is.EqualTo(3));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(3));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(850));
Assert.That(ps2[2].Weight, Is.EqualTo(1000));
});
}
[Test]
public async Task TestSplit_12_OtherDelivery_Complete() {
var d1 = await GetDelivery("20231009X001");
var d2 = await GetDelivery("20231009X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps1 = GetParts(d1);
var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
});
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [1200, int.MaxValue, 1000], d2.LsNr));
d1 = await GetDelivery("20231009X001");
d2 = await GetDelivery("20231009X002");
Assert.Multiple(() => {
Assert.That(d1, Is.Null);
Assert.That(d2, Is.Not.Null);
});
Assert.Multiple(() => {
var ps2 = GetParts(d2);
Assert.That(ps2, Has.Length.EqualTo(4));
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(1000));
Assert.That(ps2[2].Weight, Is.EqualTo(1000));
Assert.That(ps2[3].Weight, Is.EqualTo(1000));
});
}
[Test]
public async Task TestDelete_01_Normal() {
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Deliveries.FindAsync(2022, 2), Is.Not.Null);
}
Assert.DoesNotThrowAsync(async () => await DeliveryService.DeleteDelivery("20220930X001"));
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Deliveries.FindAsync(2022, 2), Is.Null);
}
}
}
}

View File

@ -0,0 +1,361 @@
using Elwig.Helpers;
using Elwig.Models.Entities;
using Elwig.Services;
using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore;
namespace Tests.ServiceTests {
[TestFixture]
public class MemberServiceTest {
private static async Task InitViewModel(MemberAdminViewModel vm) {
using var ctx = new AppDbContext();
vm.BranchSource = await ctx.Branches.ToListAsync();
vm.DefaultKgSource = await ctx.Katastralgemeinden.ToListAsync();
vm.OrtSource = await ctx.PlzDestinations.Include(p => p.Ort).ToListAsync();
vm.BillingOrtSource = await ctx.PlzDestinations.Include(p => p.Ort).ToListAsync();
}
[Test]
public async Task TestCreate_01_Minimal() {
var vm = new MemberAdminViewModel();
await InitViewModel(vm);
await vm.InitInputs();
vm.Name = "Neuling";
vm.GivenName = "Nadine";
vm.Address = "Neubaugasse 1";
vm.Plz = 2120;
vm.Ort = vm.OrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel");
vm.BusinessShares = 1;
vm.DefaultKg = vm.DefaultKgSource.First(k => k.Name == "Wolkersdorf");
Assert.That(vm.MgNr, Is.EqualTo(205));
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Members.FindAsync(205), Is.Null);
}
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
Member? m;
using (var ctx = new AppDbContext()) {
m = await ctx.Members
.Where(m => m.MgNr == vm.MgNr)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.AsSplitQuery()
.FirstOrDefaultAsync();
}
Assert.That(m, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(m.MgNr, Is.EqualTo(205));
Assert.That(m.Name, Is.EqualTo("Neuling"));
Assert.That(m.GivenName, Is.EqualTo("Nadine"));
Assert.That(m.Address, Is.EqualTo("Neubaugasse 1"));
Assert.That(m.PostalDest.AtPlz?.Plz, Is.EqualTo(2120));
Assert.That(m.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(m.BusinessShares, Is.EqualTo(1));
Assert.That(m.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
});
vm = new MemberAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => {
Assert.That(vm.MgNr, Is.EqualTo(205));
Assert.That(vm.Name, Is.EqualTo("Neuling"));
Assert.That(vm.GivenName, Is.EqualTo("Nadine"));
Assert.That(vm.Address, Is.EqualTo("Neubaugasse 1"));
Assert.That(vm.Plz, Is.EqualTo(2120));
Assert.That(vm.Ort?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(vm.BusinessShares, Is.EqualTo(1));
Assert.That(vm.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
});
}
[Test]
public async Task TestCreate_02_Full() {
var vm = new MemberAdminViewModel();
await InitViewModel(vm);
await vm.InitInputs();
vm.MgNr = 999;
vm.IsJuridicalPerson = true;
vm.Name = "Neue GmbH";
vm.ForTheAttentionOf = "Norbert Neuling";
vm.Address = "Neuegasse 2";
vm.Plz = 2120;
vm.Ort = vm.OrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel");
vm.EmailAddresses[0] = "neue.gmbh@mail.com";
vm.EmailAddresses[1] = "norbert.neuling@mail.com";
vm.PhoneNrs[0] = new(0, "+43 2245 9876", "Büro");
vm.PhoneNrs[1] = new(1, "+43 664 123456789", "Hr. Neuling");
vm.PhoneNrs[2] = new(2, "+43 2245 9876-2", null);
vm.Iban = "AT97 1234 5678 9012 3460";
vm.Bic = "RLNWATWWWDF";
vm.UstIdNr = "ATU12345693";
vm.LfbisNr = "0123498";
vm.IsBuchführend = true;
vm.IsOrganic = true;
vm.BillingName = "Neue Holding AG";
vm.BillingAddress = "Neuegasse 3";
vm.BillingPlz = 2120;
vm.BillingOrt = vm.BillingOrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel");
vm.BusinessShares = 10;
vm.AccountingNr = "330999";
vm.DefaultKg = vm.DefaultKgSource.First(k => k.Name == "Wolkersdorf");
vm.Comment = "Ich bin eine Anmerkung";
vm.ContactViaPost = true;
vm.ContactViaEmail = true;
vm.IsVollLieferant = true;
vm.IsFunktionär = true;
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Members.FindAsync(999), Is.Null);
}
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
Member? m;
using (var ctx = new AppDbContext()) {
m = await ctx.Members
.Where(m => m.MgNr == vm.MgNr)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.AsSplitQuery()
.FirstOrDefaultAsync();
}
Assert.That(m, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(m.MgNr, Is.EqualTo(999));
Assert.That(m.IsJuridicalPerson, Is.True);
Assert.That(m.Name, Is.EqualTo("Neue GmbH"));
Assert.That(m.ForTheAttentionOf, Is.EqualTo("Norbert Neuling"));
Assert.That(m.Address, Is.EqualTo("Neuegasse 2"));
Assert.That(m.PostalDest.AtPlz?.Plz, Is.EqualTo(2120));
Assert.That(m.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(m.EmailAddresses.Select(a => (a.Nr, a.Address)), Is.EquivalentTo(new (int, string)[] {
(1, "neue.gmbh@mail.com"),
(2, "norbert.neuling@mail.com"),
}));
Assert.That(m.TelephoneNumbers.Select(n => (n.Nr, n.Type, n.Number, n.Comment)), Is.EquivalentTo(new (int, string, string, string?)[] {
(1, "landline", "+43 2245 9876", "Büro"),
(2, "mobile", "+43 664 123456789", "Hr. Neuling"),
(3, "fax", "+43 2245 9876-2", null),
}));
Assert.That(m.Iban, Is.EqualTo("AT971234567890123460"));
Assert.That(m.Bic, Is.EqualTo("RLNWATWWWDF"));
Assert.That(m.UstIdNr, Is.EqualTo("ATU12345693"));
Assert.That(m.LfbisNr, Is.EqualTo("0123498"));
Assert.That(m.IsBuchführend, Is.True);
Assert.That(m.IsOrganic, Is.True);
Assert.That(m.BillingAddress, Is.Not.Null);
Assert.That(m.BillingAddress?.FullName, Is.EqualTo("Neue Holding AG"));
Assert.That(m.BillingAddress?.Address, Is.EqualTo("Neuegasse 3"));
Assert.That(m.BillingAddress?.PostalDest.AtPlz?.Plz, Is.EqualTo(2120));
Assert.That(m.BillingAddress?.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(m.BusinessShares, Is.EqualTo(10));
Assert.That(m.AccountingNr, Is.EqualTo("330999"));
Assert.That(m.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
Assert.That(m.Comment, Is.EqualTo("Ich bin eine Anmerkung"));
Assert.That(m.ContactViaPost, Is.True);
Assert.That(m.ContactViaEmail, Is.True);
Assert.That(m.IsVollLieferant, Is.True);
Assert.That(m.IsFunktionär, Is.True);
});
vm = new MemberAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => {
Assert.That(vm.MgNr, Is.EqualTo(999));
Assert.That(vm.IsJuridicalPerson, Is.True);
Assert.That(vm.Name, Is.EqualTo("Neue GmbH"));
Assert.That(vm.ForTheAttentionOf, Is.EqualTo("Norbert Neuling"));
Assert.That(vm.Address, Is.EqualTo("Neuegasse 2"));
Assert.That(vm.Plz, Is.EqualTo(2120));
Assert.That(vm.Ort?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(vm.EmailAddresses, Is.EquivalentTo(new string?[] {
"neue.gmbh@mail.com",
"norbert.neuling@mail.com",
null, null, null, null, null, null, null
}));
Assert.That(vm.PhoneNrs, Is.EquivalentTo(new MemberAdminViewModel.PhoneNr?[] {
new(0, "+43 2245 9876", "Büro"),
new(1, "+43 664 123456789", "Hr. Neuling"),
new(2, "+43 2245 9876-2", null),
new(), new(), new(), new(), new(), new()
}));
Assert.That(vm.Iban, Is.EqualTo("AT971234567890123460"));
Assert.That(vm.Bic, Is.EqualTo("RLNWATWWWDF"));
Assert.That(vm.UstIdNr, Is.EqualTo("ATU12345693"));
Assert.That(vm.LfbisNr, Is.EqualTo("0123498"));
Assert.That(vm.IsBuchführend, Is.True);
Assert.That(vm.IsOrganic, Is.True);
Assert.That(vm.BillingName, Is.EqualTo("Neue Holding AG"));
Assert.That(vm.BillingAddress, Is.EqualTo("Neuegasse 3"));
Assert.That(vm.BillingPlz, Is.EqualTo(2120));
Assert.That(vm.BillingOrt?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(vm.BusinessShares, Is.EqualTo(10));
Assert.That(vm.AccountingNr, Is.EqualTo("330999"));
Assert.That(vm.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
Assert.That(vm.Comment, Is.EqualTo("Ich bin eine Anmerkung"));
Assert.That(vm.ContactViaPost, Is.True);
Assert.That(vm.ContactViaEmail, Is.True);
Assert.That(vm.IsVollLieferant, Is.True);
Assert.That(vm.IsFunktionär, Is.True);
});
}
[Test]
public async Task TestUpdate_01_Inactive() {
var vm = new MemberAdminViewModel();
await InitViewModel(vm);
using (var ctx = new AppDbContext()) {
vm.FillInputs(await ctx.Members
.Where(m => m.MgNr == 202)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.AsSplitQuery()
.FirstAsync());
}
Assert.That(vm.IsActive, Is.True);
var exitDate = DateTime.Now;
vm.IsActive = false;
vm.ExitDate = $"{exitDate:dd.MM.yyyy}";
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(202));
Member? m;
using (var ctx = new AppDbContext()) {
m = await ctx.Members
.Where(m => m.MgNr == 202)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.AsSplitQuery()
.FirstOrDefaultAsync();
}
Assert.That(m, Is.Not.Null);
Assert.Multiple(() => {
Assert.That(m.IsActive, Is.False);
Assert.That(m.ExitDateString, Is.EqualTo($"{exitDate:yyyy-MM-dd}"));
});
vm = new MemberAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => {
Assert.That(vm.IsActive, Is.False);
Assert.That(vm.ExitDate, Is.EqualTo($"{exitDate:dd.MM.yyyy}"));
});
}
[Test]
public async Task TestUpdate_02_MgNr() {
var vm = new MemberAdminViewModel();
await InitViewModel(vm);
using (var ctx = new AppDbContext()) {
vm.FillInputs(await ctx.Members
.Where(m => m.MgNr == 203)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.AsSplitQuery()
.FirstAsync());
}
Assert.Multiple(() => {
Assert.That(vm.MgNr, Is.EqualTo(203));
Assert.That(vm.EmailAddresses[0], Is.Not.Null);
Assert.That(vm.PhoneNrs[0], Is.Not.Null);
Assert.That(vm.BillingName, Is.Not.Null);
});
vm.MgNr = 210;
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
Member? m;
using (var ctx = new AppDbContext()) {
m = await ctx.Members
.Where(m => m.MgNr == 210)
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
.Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg)
.Include(m => m.EmailAddresses)
.Include(m => m.TelephoneNumbers)
.AsSplitQuery()
.FirstOrDefaultAsync();
}
Assert.That(m, Is.Not.Null);
vm = new MemberAdminViewModel();
await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => {
Assert.That(vm.MgNr, Is.EqualTo(210));
Assert.That(vm.EmailAddresses[0], Is.Not.Null);
Assert.That(vm.PhoneNrs[0], Is.Not.Null);
Assert.That(vm.BillingName, Is.Not.Null);
});
}
[Test]
public async Task TestDelete_01_NoReferences() {
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Members.FindAsync(201), Is.Not.Null);
}
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false));
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Members.FindAsync(201), Is.Null);
}
}
[Test]
public async Task TestDelete_02_AllReferences() {
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Members.FindAsync(204), Is.Not.Null);
}
for (int i = 0; i < 7; i++) {
Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0));
using var ctx = new AppDbContext();
Assert.That(await ctx.Members.FindAsync(204), Is.Not.Null);
}
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true));
using (var ctx = new AppDbContext()) {
Assert.That(await ctx.Members.FindAsync(204), Is.Null);
}
}
}
}

View File

@ -0,0 +1,25 @@
using Elwig.Helpers;
using System.Reflection;
using Microsoft.Data.Sqlite;
namespace Tests.ServiceTests {
[SetUpFixture]
public class Setup {
private SqliteConnection? Connection;
[OneTimeSetUp]
public async Task SetupDatabase() {
Connection = await AppDbContext.ConnectAsync();
await AppDbContext.ExecuteEmbeddedScript(Connection, Assembly.GetExecutingAssembly(), "Tests.Resources.Sql.ServiceInsert.sql");
}
[OneTimeTearDown]
public async Task TeardownDatabase() {
if (Connection == null) return;
await AppDbContext.ExecuteEmbeddedScript(Connection, Assembly.GetExecutingAssembly(), "Tests.Resources.Sql.ServiceDelete.sql");
await Connection.DisposeAsync();
Connection = null;
}
}
}

View File

@ -171,11 +171,11 @@ namespace Tests.WeighingTests {
Thread.Sleep(100); Thread.Sleep(100);
if (invalid) { if (invalid) {
return ("abcd\r\n", false); return ("abcd", false);
} }
bool incr = true; bool incr = true;
return ($" {new DateTime(2020, 9, 28, 9, 8, 0):dd.MM.yy HH:mm} {identNr,4} {weight,9}{(unit ? "lb" : "kg")} \r\n", incr); return ($" {new DateTime(2020, 9, 28, 9, 8, 0):dd.MM.yy HH:mm} {identNr,4} {weight,9}{(unit ? "lb" : "kg")} ", incr);
} }
} }
} }