Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 360856585a | |||
| cc6e31a006 | |||
| ce1a55df86 | |||
| 07d93dd384 | |||
| f6e9d429d5 | |||
| 7b78f9d6b9 | |||
| 22fbb0772f | |||
| 0a9c800116 | |||
| 278d79429b | |||
| e5e5e10cd7 | |||
| d051a2bfcf | |||
| 9c39a2f820 | |||
| 4460de9975 | |||
| f96ebdcf60 | |||
| e593175e72 | |||
| 1f4fe2129d | |||
| cdb4b0a2bd | |||
| ddfc86197d | |||
| ae0a082421 | |||
| 3c52156b7e | |||
| 982a6616e1 | |||
| b1075d1e69 | |||
| cc018ded10 | |||
| 0aefab5d63 | |||
| 149f455256 |
@@ -23,6 +23,16 @@ jobs:
|
|||||||
echo "No files with BOM found"
|
echo "No files with BOM found"
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
- name: Check for code smells
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
git grep -IEn "\.(Single|First|Min|Max|Any)(OrDefault)?Async\([^)]|^using System.Data.Entity;"
|
||||||
|
if ( $lastexitcode -ne 1 ) {
|
||||||
|
exit 1
|
||||||
|
} else {
|
||||||
|
echo "No files with code smells found"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
- name: Setup MSBuild
|
- name: Setup MSBuild
|
||||||
uses: microsoft/setup-msbuild@v1.1
|
uses: microsoft/setup-msbuild@v1.1
|
||||||
- name: Setup NuGet
|
- name: Setup NuGet
|
||||||
|
|||||||
66
CHANGELOG.md
66
CHANGELOG.md
@@ -2,6 +2,72 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
[v1.0.5.0][v1.0.5.0] (2026-04-08) {#v1.0.5.0}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Neue Funktionen {#v1.0.5.0-features}
|
||||||
|
|
||||||
|
* Flächenbindungen werden nun in _Verträgen_ zusammengefasst um bessere Übersicht und historische Nachvollziehbarkeit zu gewährleisten. ([#77][i77])
|
||||||
|
|
||||||
|
### Sonstiges {#v1.0.5.0-misc}
|
||||||
|
|
||||||
|
* Erhebliche Verbesserung der Leistung/Geschwindigkeit. ([#79][i79], e5e5e10cd7, 22fbb0772f)
|
||||||
|
* Am Stammdatenblatt (`MemberDataSheet`) wird nun als Datum das Datum der letzten Bearbeitung angegeben. (e5e5e10cd7)
|
||||||
|
* Abhängigkeiten aktualisiert. (07d93dd384, ce1a55df86, cc6e31a006)
|
||||||
|
|
||||||
|
[v1.0.5.0]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.5.0
|
||||||
|
[i77]: https://git.necronda.net/winzer/elwig/issues/77
|
||||||
|
[i79]: https://git.necronda.net/winzer/elwig/issues/79
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[v1.0.4.1][v1.0.4.1] (2026-03-27) {#v1.0.4.1}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.4.1-bugfixes}
|
||||||
|
|
||||||
|
* In der Anlieferungsbestätigung (`DeliveryConfirmation`) war in einer Spalte der Text nicht rechtsbündig. (0aefab5d63)
|
||||||
|
* Die zweite Zeile des Absenders wurde nicht mehr abgedruckt und der Briefkopf (`Letterhead`) beinhaltete zu viele Informationen. (3c52156b7e)
|
||||||
|
|
||||||
|
### Sonstiges {#v1.0.4.1-misc}
|
||||||
|
|
||||||
|
* Evtl. wurden bei Änderungen in der Datenbank unnötigerweise einige Daten in Elwig doppelt angefordert. (cc018ded10)
|
||||||
|
* Massenaktionen im Lieferungen-Fenster (`DeliveryAdminWindow`) sind nun nicht mehr während dem Bearbeiten oder Erstellen möglich. (b1075d1e69)
|
||||||
|
* Das Datum auf Lieferscheinen (`DeliveryNote`) ist nun statt des heutigen, das Datum der letzten Änderung der Lieferung. (982a6616e1)
|
||||||
|
* Sollte es im Rundschreiben-Fenster (`MailWindow`) zu einem Fehler während dem Bereinigen der Dokumenten kommen wird dieser ignoriert. (ae0a082421)
|
||||||
|
* Abhängigkeiten aktualisiert. (ddfc86197d, cdb4b0a2bd)
|
||||||
|
|
||||||
|
[v1.0.4.1]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.4.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[v1.0.4.0][v1.0.4.0] (2026-03-16) {#v1.0.4.0}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Neue Funktionen {#v1.0.4.0-features}
|
||||||
|
|
||||||
|
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) gibt es nun über die Menü-Leiste die Möglichkeit _Massenaktionen_ für mehrere Lieferungen durchzuführen (z.B. Attribut oder Zu-/Abschlag setzen). ([#78][i78])
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.4.0-bugfixes}
|
||||||
|
|
||||||
|
* Waagen mit Netzwerkschnittstelle versuchen die Verbindung nun wieder neu aufzubauen, sollte diese unterbrochen werden. ([#74][i74])
|
||||||
|
|
||||||
|
### Sonstiges {#v1.0.4.0-misc}
|
||||||
|
|
||||||
|
* Die bisher verwendeten Programm-Bibliotheken zum Erstellen von PDF-Dokumente wurden vollständig durch [iText](https://itextpdf.com/) ersetzt.
|
||||||
|
Das ermöglicht ein schnelleres, effizienteres, und stabileres Erstellen der PDF-Dokumente.
|
||||||
|
Außerdem konnte so die Größe der Installations-Datei von ~138 MB auf ~98 MB um ca. 30 % reduziert werden. (d8c967b2f2, 8054a024f4)
|
||||||
|
* Abhängigkeiten aktualisiert. (af73226c90, f4fddd111f)
|
||||||
|
|
||||||
|
[v1.0.4.0]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.4.0
|
||||||
|
[i74]: https://git.necronda.net/winzer/elwig/issues/74
|
||||||
|
[i78]: https://git.necronda.net/winzer/elwig/issues/78
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[v1.0.3.4][v1.0.3.4] (2026-02-19) {#v1.0.3.4}
|
[v1.0.3.4][v1.0.3.4] (2026-02-19) {#v1.0.3.4}
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Elwig.Helpers.Printing;
|
|||||||
using Elwig.Helpers.Weighing;
|
using Elwig.Helpers.Weighing;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Windows;
|
using Elwig.Windows;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
@@ -104,7 +105,9 @@ namespace Elwig {
|
|||||||
|
|
||||||
Dictionary<string, (string, string, int?, string?, string?, string?, string?, string?)> branches = [];
|
Dictionary<string, (string, string, int?, string?, string?, string?, string?, string?)> branches = [];
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
branches = ctx.Branches.ToDictionary(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr));
|
branches = ctx.FetchBranches()
|
||||||
|
.ToDictionaryAsync(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr))
|
||||||
|
.GetAwaiter().GetResult();
|
||||||
try {
|
try {
|
||||||
Client = new(ctx);
|
Client = new(ctx);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,7 +221,8 @@ namespace Elwig {
|
|||||||
MainDispatcher.Invoke(() => {
|
MainDispatcher.Invoke(() => {
|
||||||
foreach (Window w in CurrentApp.Windows) {
|
foreach (Window w in CurrentApp.Windows) {
|
||||||
if (w is not ContextWindow c) continue;
|
if (w is not ContextWindow c) continue;
|
||||||
MainDispatcher.BeginInvoke(c.HintContextChange);
|
MainDispatcher.Invoke(c.HintContextChange);
|
||||||
|
MainDispatcher.BeginInvoke(c.TryContextReload);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,13 +41,21 @@ namespace Elwig.Controls {
|
|||||||
incButton!.Click += IncrementButton_Click;
|
incButton!.Click += IncrementButton_Click;
|
||||||
decButton!.Click += DecrementButton_Click;
|
decButton!.Click += DecrementButton_Click;
|
||||||
base.OnApplyTemplate();
|
base.OnApplyTemplate();
|
||||||
|
UpdateButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateButtons() {
|
||||||
|
var incButton = GetTemplateChild("IncrementButton") as RepeatButton;
|
||||||
|
var decButton = GetTemplateChild("DecrementButton") as RepeatButton;
|
||||||
|
incButton?.IsEnabled = Maximum == null || Value < Maximum;
|
||||||
|
decButton?.IsEnabled = Minimum == null || Value > Minimum;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IntegerUpDown_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void IntegerUpDown_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
var idx = CaretIndex;
|
var idx = CaretIndex;
|
||||||
Text = new string(Text.Where(char.IsAsciiDigit).Take(4).ToArray());
|
Text = new string([.. Text.Where(char.IsAsciiDigit).Take(4)]);
|
||||||
CaretIndex = idx;
|
CaretIndex = idx;
|
||||||
evt.Handled = !(Value >= Minimum && Value <= Maximum);
|
evt.Handled = !((!Minimum.HasValue || Value >= Minimum) && (!Maximum.HasValue || Value <= Maximum));
|
||||||
if (idx >= 4) {
|
if (idx >= 4) {
|
||||||
if (Value < Minimum) {
|
if (Value < Minimum) {
|
||||||
Value = Minimum;
|
Value = Minimum;
|
||||||
@@ -56,6 +64,7 @@ namespace Elwig.Controls {
|
|||||||
}
|
}
|
||||||
CaretIndex = 4;
|
CaretIndex = 4;
|
||||||
}
|
}
|
||||||
|
UpdateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IntegerUpDown_LostFocus(object sender, RoutedEventArgs evt) {
|
private void IntegerUpDown_LostFocus(object sender, RoutedEventArgs evt) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
@@ -12,23 +13,27 @@ namespace Elwig.Dialogs {
|
|||||||
public string OrigYearTo { get; set; }
|
public string OrigYearTo { get; set; }
|
||||||
public string Area { get; set; }
|
public string Area { get; set; }
|
||||||
|
|
||||||
public AreaComModifyDialog(int? yearFrom, int? yearTo, int area, bool delete) {
|
public AreaComModifyDialog(int? yearFrom, int? yearTo, int area, bool delete, bool forceRetroactive = false) {
|
||||||
Area = $"{area:N0}";
|
Area = $"{area:N0}";
|
||||||
OrigYearFrom = $"{yearFrom}";
|
OrigYearFrom = $"{yearFrom}";
|
||||||
OrigYearTo = $"{yearTo}";
|
OrigYearTo = $"{yearTo}";
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Title = delete ? "Flächenbindung löschen" : "Flächenbindung bearbeiten";
|
Title = delete ? "Flächenbindung löschen" : "Flächenbindung bearbeiten";
|
||||||
RetroactiveInput.Content = delete ? "Rückwirkend löschen" : "Rückwirkend bearbeiten";
|
RetroactiveInput.Content = delete ? "Rückwirkend löschen" : "Rückwirkend bearbeiten";
|
||||||
|
forceRetroactive = forceRetroactive || yearFrom.HasValue && yearTo.HasValue && yearFrom.Value == yearTo.Value;
|
||||||
|
RetroactiveInput.IsEnabled = !forceRetroactive;
|
||||||
if (delete) {
|
if (delete) {
|
||||||
QuestionBlock1.Visibility = Visibility.Hidden;
|
QuestionBlock1.Visibility = Visibility.Hidden;
|
||||||
QuestionBlock2.Visibility = Visibility.Visible;
|
QuestionBlock2.Visibility = Visibility.Visible;
|
||||||
DescBlock1.Visibility = Visibility.Hidden;
|
DescBlock1.Visibility = Visibility.Hidden;
|
||||||
DescBlock2.Visibility = Visibility.Visible;
|
DescBlock2.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
if ((yearTo.HasValue && yearTo < Utils.CurrentNextSeason) || (yearFrom.HasValue && yearFrom >= Utils.CurrentNextSeason)) {
|
SeasonInput.Minimum = yearFrom.HasValue ? yearFrom + 1 : null;
|
||||||
|
SeasonInput.Maximum = yearTo.HasValue ? yearTo : null;
|
||||||
|
if (forceRetroactive || (yearTo.HasValue && yearTo < Utils.CurrentYear) || (yearFrom.HasValue && yearFrom >= Utils.CurrentYear)) {
|
||||||
RetroactiveInput.IsChecked = true;
|
RetroactiveInput.IsChecked = true;
|
||||||
} else {
|
} else {
|
||||||
SeasonInput.Text = $"{Utils.CurrentNextSeason}";
|
SeasonInput.Text = $"{Utils.CurrentYear}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +53,7 @@ namespace Elwig.Dialogs {
|
|||||||
DescBlock2.Visibility = Visibility.Hidden;
|
DescBlock2.Visibility = Visibility.Hidden;
|
||||||
} else {
|
} else {
|
||||||
SeasonInput.IsEnabled = true;
|
SeasonInput.IsEnabled = true;
|
||||||
SeasonInput.Text = $"{Utils.CurrentNextSeason}";
|
SeasonInput.Text = $"{Math.Max(SeasonInput.Minimum ?? Utils.CurrentYear, Utils.CurrentYear)}";
|
||||||
DescBlock1.Visibility = QuestionBlock1.Visibility;
|
DescBlock1.Visibility = QuestionBlock1.Visibility;
|
||||||
DescBlock2.Visibility = QuestionBlock2.Visibility;
|
DescBlock2.Visibility = QuestionBlock2.Visibility;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
DataContext="{Binding RelativeSource={RelativeSource Self}}"
|
DataContext="{Binding RelativeSource={RelativeSource Self}}"
|
||||||
Title="Flächenbindungen übertragen" Height="260" Width="450">
|
Title="Flächenbindungen übertragen" Height="240" Width="450">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Label">
|
<Style TargetType="Label">
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
@@ -48,12 +48,8 @@
|
|||||||
Minimum="1900" Maximum="9999"
|
Minimum="1900" Maximum="9999"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||||
TextChanged="SeasonInput_TextChanged"/>
|
TextChanged="SeasonInput_TextChanged"/>
|
||||||
<CheckBox x:Name="CopyYearToInput" Content="Beginn der Laufzeit von Vorgänger übernehmen" Margin="0,80,0,0"
|
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
|
||||||
Checked="CopyYearToInput_Changed" Unchecked="CopyYearToInput_Changed"
|
|
||||||
IsChecked="{Binding MaintainYearFrom}"/>
|
|
||||||
|
|
||||||
<TextBlock x:Name="DescBlock1" Margin="0,105,0,0" TextAlignment="Center"
|
<TextBlock x:Name="DescBlock1" Margin="0,90,0,0" TextAlignment="Center"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||||
Die Flächenbindungen beim <Bold>Vorgänger</Bold> sind bis inkl. Saison <Bold><Run x:Name="CancelSeason1"/></Bold> gültig,<LineBreak/>
|
Die Flächenbindungen beim <Bold>Vorgänger</Bold> sind bis inkl. Saison <Bold><Run x:Name="CancelSeason1"/></Bold> gültig,<LineBreak/>
|
||||||
und werden beim <Bold>Nachfolger</Bold> ab <Run x:Name="DescBlock1Season" Text="inkl. Saison "/><Bold><Run x:Name="TransferSeason"/></Bold> übernommen.
|
und werden beim <Bold>Nachfolger</Bold> ab <Run x:Name="DescBlock1Season" Text="inkl. Saison "/><Bold><Run x:Name="TransferSeason"/></Bold> übernommen.
|
||||||
|
|||||||
@@ -5,51 +5,51 @@ using System.Windows.Controls;
|
|||||||
namespace Elwig.Dialogs {
|
namespace Elwig.Dialogs {
|
||||||
public partial class AreaComTransferDialog : Window {
|
public partial class AreaComTransferDialog : Window {
|
||||||
|
|
||||||
public int CancelSeason { get; set; }
|
public int CancelSeason => SuccessorSeason - 1;
|
||||||
public int SuccessorSeason => CancelSeason + 1;
|
public int SuccessorSeason { get; set; }
|
||||||
public bool MaintainYearFrom { get; set; }
|
|
||||||
|
|
||||||
public string AreaComNum { get; set; }
|
public string AreaComNum { get; set; }
|
||||||
public string Area { get; set; }
|
public string Area { get; set; }
|
||||||
|
|
||||||
public AreaComTransferDialog(string name, int areaComNum, int area) {
|
public AreaComTransferDialog(string name, int areaComNum, int area) {
|
||||||
CancelSeason = Utils.FollowingSeason - 1;
|
SuccessorSeason = Utils.FollowingSeason;
|
||||||
AreaComNum = $"{areaComNum:N0}";
|
AreaComNum = $"{areaComNum:N0}";
|
||||||
Area = $"{area:N0}";
|
Area = $"{area:N0}";
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SeasonInput.Text = $"{CancelSeason}";
|
SeasonInput.Text = $"{SuccessorSeason}";
|
||||||
|
SeasonInput.Minimum = Utils.CurrentLastSeason;
|
||||||
Title = $"Aktive Flächenbindungen kündigen - {name}";
|
Title = $"Aktive Flächenbindungen kündigen - {name}";
|
||||||
QuestionBlock1.Visibility = Visibility.Hidden;
|
QuestionBlock1.Visibility = Visibility.Hidden;
|
||||||
QuestionBlock2.Visibility = Visibility.Visible;
|
QuestionBlock2.Visibility = Visibility.Visible;
|
||||||
DescBlock1.Visibility = Visibility.Hidden;
|
DescBlock1.Visibility = Visibility.Hidden;
|
||||||
DescBlock2.Visibility = Visibility.Visible;
|
DescBlock2.Visibility = Visibility.Visible;
|
||||||
CopyYearToInput.Visibility = Visibility.Hidden;
|
|
||||||
Height = 240;
|
Height = 240;
|
||||||
SeasonInput.Margin = new(0, 40, 0, 0);
|
SeasonInput.Margin = new(0, 40, 0, 0);
|
||||||
SeasonLabel.Margin = new(0, 40, 100, 0);
|
SeasonLabel.Margin = new(0, 40, 100, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AreaComTransferDialog(string name, string successorName, int areaComNum, int area) {
|
public AreaComTransferDialog(string name, string successorName, int areaComNum, int area) {
|
||||||
CancelSeason = Utils.FollowingSeason - 1;
|
SuccessorSeason = Utils.FollowingSeason;
|
||||||
AreaComNum = $"{areaComNum:N0}";
|
AreaComNum = $"{areaComNum:N0}";
|
||||||
Area = $"{area:N0}";
|
Area = $"{area:N0}";
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SeasonInput.Text = $"{CancelSeason}";
|
SeasonInput.Text = $"{SuccessorSeason}";
|
||||||
|
SeasonInput.Minimum = Utils.CurrentLastSeason;
|
||||||
Title = $"Aktive Flächenbindungen übertragen - {name} - {successorName}";
|
Title = $"Aktive Flächenbindungen übertragen - {name} - {successorName}";
|
||||||
InfoBlock.Visibility = Visibility.Hidden;
|
InfoBlock.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
CancelSeason = (int)SeasonInput.Value!;
|
SuccessorSeason = (int)SeasonInput.Value!;
|
||||||
CancelSeason1.Text = $"{CancelSeason}";
|
CancelSeason1.Text = $"{CancelSeason}";
|
||||||
CancelSeason2.Text = $"{CancelSeason}";
|
CancelSeason2.Text = $"{CancelSeason}";
|
||||||
TransferSeason.Text = MaintainYearFrom ? "" : $"{SuccessorSeason}";
|
TransferSeason.Text = $"{SuccessorSeason}";
|
||||||
DescBlock1Season.Text = MaintainYearFrom ? "dem originalen Beginn der FB" : "inkl. Saison ";
|
DescBlock1Season.Text = "inkl. Saison ";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CopyYearToInput_Changed(object sender, RoutedEventArgs evt) {
|
private void CopyYearToInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
TransferSeason.Text = MaintainYearFrom ? "" : $"{SuccessorSeason}";
|
TransferSeason.Text = $"{SuccessorSeason}";
|
||||||
DescBlock1Season.Text = MaintainYearFrom ? "dem originalen Beginn der FB" : "inkl. Saison ";
|
DescBlock1Season.Text = "inkl. Saison ";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
|||||||
@@ -44,15 +44,10 @@ namespace Elwig.Dialogs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers().ToListAsync());
|
||||||
.Where(m => m.IsActive)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ToListAsync());
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryInput, await ctx.Deliveries
|
ControlUtils.RenewItemsSource(DeliveryInput, await ctx.Deliveries
|
||||||
.Where(d => d.DateString == $"{_delivery.Date:yyyy-MM-dd}" && d.ZwstId == _delivery.ZwstId)
|
.Where(d => d.DateString == $"{_delivery.Date:yyyy-MM-dd}" && d.ZwstId == _delivery.ZwstId)
|
||||||
.OrderBy(d => d.LsNr)
|
.OrderBy(d => d.LsNr)
|
||||||
.Include(d => d.Member)
|
|
||||||
.Include(d => d.Parts)
|
.Include(d => d.Parts)
|
||||||
.ToListAsync());
|
.ToListAsync());
|
||||||
if (DeliveryInput.SelectedItem == null)
|
if (DeliveryInput.SelectedItem == null)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Elwig.Helpers;
|
|||||||
using Elwig.Models;
|
using Elwig.Models;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using iText.Kernel.Colors;
|
using iText.Kernel.Colors;
|
||||||
|
using iText.Kernel.Geom;
|
||||||
using iText.Kernel.Pdf;
|
using iText.Kernel.Pdf;
|
||||||
using iText.Kernel.Pdf.Action;
|
using iText.Kernel.Pdf.Action;
|
||||||
using iText.Kernel.Pdf.Canvas;
|
using iText.Kernel.Pdf.Canvas;
|
||||||
@@ -21,6 +22,7 @@ namespace Elwig.Documents {
|
|||||||
public bool IncludeSender = false;
|
public bool IncludeSender = false;
|
||||||
public bool UseBillingAddress = false;
|
public bool UseBillingAddress = false;
|
||||||
public bool ShowDateAndLocation = false;
|
public bool ShowDateAndLocation = false;
|
||||||
|
public DateOnly? DateFrom;
|
||||||
protected Table? Aside;
|
protected Table? Aside;
|
||||||
|
|
||||||
public string Address {
|
public string Address {
|
||||||
@@ -46,16 +48,16 @@ namespace Elwig.Documents {
|
|||||||
return NewAsideCell(new KernedParagraph(text, 10), colspan, isName);
|
return NewAsideCell(new KernedParagraph(text, 10), colspan, isName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BusinessDocument(string title, Member m, bool includeSender = false) :
|
public BusinessDocument(string title, Member m, DateOnly? dateFrom, bool includeSender = false) :
|
||||||
base(title) {
|
base(title) {
|
||||||
Member = m;
|
Member = m;
|
||||||
Location = App.BranchLocation;
|
Location = App.BranchLocation;
|
||||||
IncludeSender = includeSender;
|
IncludeSender = includeSender;
|
||||||
|
DateFrom = dateFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.RenderHeader(doc, pdf);
|
base.BeforeRenderBody(doc, pdf);
|
||||||
|
|
||||||
var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10);
|
var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10);
|
||||||
if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)"));
|
if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)"));
|
||||||
Aside = new Table(ColsMM(22.5, 42.5))
|
Aside = new Table(ColsMM(22.5, 42.5))
|
||||||
@@ -68,6 +70,20 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void RenderAddress(Canvas canvas, Rectangle pageSize) {
|
||||||
|
canvas.Add(new Div()
|
||||||
|
.SetFixedPositionMM(25, 50, 80, 45, pageSize)
|
||||||
|
.SetFont(NF)
|
||||||
|
.Add(new KernedParagraph(IncludeSender ? $"{App.Client.Sender1}\n{App.Client.Sender2}" : "", 8).SetMargins(8, 0, 8, 0).SetHeight(16.0625f))
|
||||||
|
.Add(new KernedParagraph(Address, 12).SetMargin(0).SetHeight(12 * 5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void RenderAside(Table aside, Canvas canvas, Rectangle pageSize) {
|
||||||
|
canvas.Add(new Div()
|
||||||
|
.SetFixedPositionMM(125, 50, 65, 50, pageSize)
|
||||||
|
.Add(aside));
|
||||||
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.RenderBody(doc, pdf);
|
base.RenderBody(doc, pdf);
|
||||||
|
|
||||||
@@ -84,20 +100,14 @@ namespace Elwig.Documents {
|
|||||||
header.Add(new KernedParagraph(App.Client.NameTypeFull, 12).SetFont(NF).SetMargin(0));
|
header.Add(new KernedParagraph(App.Client.NameTypeFull, 12).SetFont(NF).SetMargin(0));
|
||||||
canvas.Add(header);
|
canvas.Add(header);
|
||||||
// address
|
// address
|
||||||
canvas.Add(new Div()
|
RenderAddress(canvas, pageSize);
|
||||||
.SetFixedPositionMM(25, 50, 80, 45, pageSize)
|
|
||||||
.SetFont(NF)
|
|
||||||
.Add(new KernedParagraph(IncludeSender ? $"{App.Client.Sender1}\n{App.Client.Sender2}" : "", 8).SetMargin(0).SetHeight(16).SetPaddings(8, 0, 8, 0))
|
|
||||||
.Add(new KernedParagraph(Address, 12).SetMargin(0).SetHeight(12 * 5)));
|
|
||||||
// aside
|
// aside
|
||||||
if (Aside != null) {
|
if (Aside != null) {
|
||||||
canvas.Add(new Div()
|
RenderAside(Aside, canvas, pageSize);
|
||||||
.SetFixedPositionMM(125, 50, 65, 50, pageSize)
|
|
||||||
.Add(Aside));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.Add(new KernedParagraph(ShowDateAndLocation ? $"{Location}, am {Date:dd.MM.yyyy}" : "", 12).SetTextAlignment(TextAlignment.RIGHT).SetVerticalAlignment(VerticalAlignment.MIDDLE).SetHeight(24).SetMargin(0));
|
doc.Add(new KernedParagraph(ShowDateAndLocation ? $"{Location}, am {DateFrom ?? Date:dd.MM.yyyy}" : "", 12).SetTextAlignment(TextAlignment.RIGHT).SetVerticalAlignment(VerticalAlignment.MIDDLE).SetHeight(24).SetMargin(0));
|
||||||
doc.Add(new KernedParagraph(Title, 12).SetFont(BF).SetMargins(0, 0, 12, 0));
|
doc.Add(new KernedParagraph(Title, 12).SetFont(BF).SetMargins(0, 0, 12, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +263,7 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewBucketTable(
|
protected Table NewBucketTable(
|
||||||
Season season, Dictionary<string, MemberBucket> buckets,
|
Season season, Dictionary<string, MemberBucket> buckets, int deliveredWeight,
|
||||||
bool includeDelivery = true, bool includePayment = false,
|
bool includeDelivery = true, bool includePayment = false,
|
||||||
bool isTiny = false, IEnumerable<string>? filter = null
|
bool isTiny = false, IEnumerable<string>? filter = null
|
||||||
) {
|
) {
|
||||||
@@ -307,10 +317,8 @@ namespace Elwig.Documents {
|
|||||||
.OrderBy(b => b.Value.Name);
|
.OrderBy(b => b.Value.Name);
|
||||||
|
|
||||||
tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA", isTiny: isTiny));
|
tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA", isTiny: isTiny));
|
||||||
tbl.AddCells(FormatRow(Member.BusinessShares * season.MinKgPerBusinessShare,
|
tbl.AddCells(FormatRow(Member.BusinessShares * season.MinKgPerBusinessShare, Member.BusinessShares * season.MaxKgPerBusinessShare,
|
||||||
Member.BusinessShares * season.MaxKgPerBusinessShare,
|
deliveredWeight, isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
|
||||||
season.Deliveries.Where(d => d.MgNr == Member.MgNr).Sum(d => d.Weight),
|
|
||||||
isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
|
|
||||||
|
|
||||||
if (fbs.Any()) {
|
if (fbs.Any()) {
|
||||||
tbl.AddCell(NewBucketSubHdr("Flächenbindungen" + (vtr.Any() ? " (inkl. Verträge)" : "") + ":", includePayment ? 8 : 7, isTiny: isTiny));
|
tbl.AddCell(NewBucketSubHdr("Flächenbindungen" + (vtr.Any() ? " (inkl. Verträge)" : "") + ":", includePayment ? 8 : 7, isTiny: isTiny));
|
||||||
|
|||||||
@@ -1,55 +1,82 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Billing;
|
||||||
using Elwig.Models.Dtos;
|
using Elwig.Models.Dtos;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using iText.Kernel.Pdf;
|
using iText.Kernel.Pdf;
|
||||||
using iText.Layout.Borders;
|
using iText.Layout.Borders;
|
||||||
using iText.Layout.Element;
|
using iText.Layout.Element;
|
||||||
using iText.Layout.Properties;
|
using iText.Layout.Properties;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class CreditNote : BusinessDocument {
|
public class CreditNote : BusinessDocument {
|
||||||
|
|
||||||
public new static string Name => "Traubengutschrift";
|
public new static string Name => "Traubengutschrift";
|
||||||
|
|
||||||
public PaymentMember? Payment;
|
public PaymentMember Payment;
|
||||||
public Credit? Credit;
|
public Credit? Credit;
|
||||||
public CreditNoteDeliveryData Data;
|
|
||||||
public string? Text;
|
public string? Text;
|
||||||
public string CurrencySymbol;
|
public string CurrencySymbol;
|
||||||
public int Precision;
|
public int Precision;
|
||||||
public string MemberModifier;
|
public string? MemberModifier;
|
||||||
public List<(string Name, int Kg, decimal Amount)>? MemberUnderDeliveries;
|
public List<(string Name, int Kg, decimal Amount)>? MemberUnderDeliveries;
|
||||||
public decimal MemberTotalUnderDelivery;
|
public decimal MemberTotalUnderDelivery;
|
||||||
public int MemberAutoBusinessShares;
|
public int MemberAutoBusinessShares;
|
||||||
public decimal MemberAutoBusinessSharesAmount;
|
public decimal MemberAutoBusinessSharesAmount;
|
||||||
public PaymentCustom? CustomPayment;
|
public PaymentCustom? CustomPayment;
|
||||||
|
|
||||||
public CreditNote(
|
protected bool ConsiderContractPenalties;
|
||||||
AppDbContext ctx,
|
protected bool ConsiderTotalPenalty;
|
||||||
PaymentMember p,
|
protected bool ConsiderAutoBusinessShares;
|
||||||
CreditNoteDeliveryData data,
|
protected bool ConsiderCustomModifiers;
|
||||||
bool considerContractPenalties,
|
|
||||||
bool considerTotalPenalty,
|
private CreditNoteDeliveryData? _data;
|
||||||
bool considerAutoBusinessShares,
|
private Dictionary<string, UnderDelivery>? _underDeliveries;
|
||||||
bool considerCustomModifiers,
|
|
||||||
Dictionary<string, UnderDelivery>? underDeliveries = null
|
public CreditNote(PaymentMember p, DateOnly? dateFrom, BillingData? billingData = null, CreditNoteDeliveryData? data = null, Dictionary<string, UnderDelivery>? underDeliveries = null) :
|
||||||
) :
|
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.FullName)} – {p.Variant.Name}", p.Member, dateFrom) {
|
||||||
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.FullName)} – {p.Variant.Name}", p.Member) {
|
|
||||||
UseBillingAddress = true;
|
UseBillingAddress = true;
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
Data = data;
|
|
||||||
Payment = p;
|
Payment = p;
|
||||||
Credit = p.Credit;
|
Credit = p.Credit;
|
||||||
IsPreview = Payment == null || Credit == null;
|
Text = App.Client.TextCreditNote;
|
||||||
var season = p.Variant.Season;
|
DocumentId = $"Tr.-Gutschr. " + (Credit != null ? $"{Credit.Year}/{Credit.TgNr:000}" : Payment.MgNr);
|
||||||
if (considerCustomModifiers) {
|
IsPreview = Credit == null;
|
||||||
CustomPayment = ctx.CustomPayments.Find(p.Year, p.MgNr);
|
_data = data;
|
||||||
|
_underDeliveries = underDeliveries;
|
||||||
|
CurrencySymbol = Payment.Variant.Season.Currency.Symbol ?? Payment.Variant.Season.Currency.Code;
|
||||||
|
Precision = Payment.Variant.Season.Precision;
|
||||||
|
|
||||||
|
billingData ??= BillingData.FromJson(Payment.Variant.Data);
|
||||||
|
ConsiderContractPenalties = billingData.ConsiderContractPenalties;
|
||||||
|
ConsiderTotalPenalty = billingData.ConsiderTotalPenalty;
|
||||||
|
ConsiderAutoBusinessShares = billingData.ConsiderAutoBusinessShares;
|
||||||
|
ConsiderCustomModifiers = billingData.ConsiderCustomModifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<CreditNote> Initialize(int year, int avnr, int mgnr, DateOnly? dateFrom, BillingData? billingData = null, CreditNoteDeliveryData? data = null, Dictionary<string, UnderDelivery>? underDeliveries = null) {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
var p = await ctx.MemberPayments
|
||||||
|
.Where(p => p.Year == year && p.AvNr == avnr && p.MgNr == mgnr)
|
||||||
|
.SingleAsync();
|
||||||
|
return new CreditNote(p, dateFrom, billingData, data, underDeliveries);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task LoadData(AppDbContext ctx) {
|
||||||
|
await base.LoadData(ctx);
|
||||||
|
var season = Payment.Variant.Season;
|
||||||
|
if (ConsiderCustomModifiers) {
|
||||||
|
CustomPayment = await ctx.CustomPayments.FindAsync(Payment.Year, Payment.MgNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mod = App.Client.IsMatzen ? ctx.Modifiers.Where(m => m.Year == season.Year && m.Name.StartsWith("Treue")).FirstOrDefault() : null;
|
_data ??= (await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, Payment.Year, Payment.AvNr))[Member.MgNr];
|
||||||
|
_underDeliveries ??= await ctx.GetMemberUnderDelivery(Payment.Year, Member.MgNr);
|
||||||
|
|
||||||
|
var mod = App.Client.IsMatzen ? await ctx.FetchModifiers(season.Year).Where(m => m.Name.StartsWith("Treue")).FirstOrDefaultAsync() : null;
|
||||||
if (CustomPayment?.ModComment != null) {
|
if (CustomPayment?.ModComment != null) {
|
||||||
MemberModifier = CustomPayment.ModComment;
|
MemberModifier = CustomPayment.ModComment;
|
||||||
} else if (mod != null) {
|
} else if (mod != null) {
|
||||||
@@ -57,32 +84,28 @@ namespace Elwig.Documents {
|
|||||||
} else {
|
} else {
|
||||||
MemberModifier = "Sonstige Zu-/Abschläge";
|
MemberModifier = "Sonstige Zu-/Abschläge";
|
||||||
}
|
}
|
||||||
Text = App.Client.TextCreditNote;
|
|
||||||
DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : p.MgNr);
|
|
||||||
CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
|
|
||||||
Precision = season.Precision;
|
|
||||||
|
|
||||||
if (considerTotalPenalty) {
|
if (ConsiderTotalPenalty) {
|
||||||
var total = data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
|
var total = _data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
|
||||||
var totalUnderDelivery = total - p.Member.BusinessShares * season.MinKgPerBusinessShare;
|
var totalUnderDelivery = total - Member.BusinessShares * season.MinKgPerBusinessShare;
|
||||||
MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerBsAmount * Math.Floor(-(decimal)totalUnderDelivery / season.MinKgPerBusinessShare) ?? 0) : 0;
|
MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerBsAmount * Math.Floor(-(decimal)totalUnderDelivery / season.MinKgPerBusinessShare) ?? 0) : 0;
|
||||||
if (total == 0)
|
if (total == 0)
|
||||||
MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0) + (season.PenaltyPerBsNone * p.Member.BusinessShares ?? 0);
|
MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0) + (season.PenaltyPerBsNone * Member.BusinessShares ?? 0);
|
||||||
}
|
}
|
||||||
if (considerAutoBusinessShares) {
|
if (ConsiderAutoBusinessShares) {
|
||||||
var fromDate = $"{season.Year}-01-01";
|
var fromDate = $"{season.Year}-01-01";
|
||||||
var toDate = $"{season.Year}-12-31";
|
var toDate = $"{season.Year}-12-31";
|
||||||
MemberAutoBusinessShares = ctx.MemberHistory
|
MemberAutoBusinessShares = await ctx.MemberHistory
|
||||||
.Where(h => h.MgNr == p.Member.MgNr && h.Type == "auto")
|
.Where(h => h.MgNr == Member.MgNr && h.Type == "auto")
|
||||||
.Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) <= 0)
|
.Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) <= 0)
|
||||||
.Sum(h => h.BusinessShares);
|
.SumAsync(h => h.BusinessShares);
|
||||||
MemberAutoBusinessSharesAmount = MemberAutoBusinessShares * (-season.BusinessShareValue ?? 0);
|
MemberAutoBusinessSharesAmount = MemberAutoBusinessShares * (-season.BusinessShareValue ?? 0);
|
||||||
}
|
}
|
||||||
if (considerContractPenalties) {
|
if (ConsiderContractPenalties) {
|
||||||
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
var varieties = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||||
var comTypes = ctx.AreaCommitmentTypes.ToDictionary(t => t.VtrgId, t => t);
|
var comTypes = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
|
||||||
MemberUnderDeliveries = underDeliveries?
|
MemberUnderDeliveries = _underDeliveries?
|
||||||
.OrderBy(u => u.Key)
|
.OrderBy(u => u.Key)
|
||||||
.Select(u => (
|
.Select(u => (
|
||||||
varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
||||||
@@ -95,8 +118,8 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.RenderHeader(doc, pdf);
|
base.BeforeRenderBody(doc, pdf);
|
||||||
Aside?.AddCell(NewAsideCell("Gutschrift", 2))
|
Aside?.AddCell(NewAsideCell("Gutschrift", 2))
|
||||||
.AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-"))
|
.AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-"))
|
||||||
.AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}"))
|
.AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}"))
|
||||||
@@ -104,8 +127,9 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
if (_data == null) throw new Exception("Call LoadData before RenderBody");
|
||||||
base.RenderBody(doc, pdf);
|
base.RenderBody(doc, pdf);
|
||||||
doc.Add(NewCreditTable(Data));
|
doc.Add(NewCreditTable(_data));
|
||||||
|
|
||||||
var div = new Table(ColsMM(60, 105))
|
var div = new Table(ColsMM(60, 105))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
@@ -131,7 +155,7 @@ namespace Elwig.Documents {
|
|||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
.SetKeepTogether(true);
|
.SetKeepTogether(true);
|
||||||
|
|
||||||
var sum = Data.Rows.Sum(p => p.Amount);
|
var sum = _data.Rows.Sum(p => p.Amount);
|
||||||
if (Payment == null) {
|
if (Payment == null) {
|
||||||
tbl1.AddCells(FormatRow("Gesamt", sum, bold: true, noTopBorder: true));
|
tbl1.AddCells(FormatRow("Gesamt", sum, bold: true, noTopBorder: true));
|
||||||
} else {
|
} else {
|
||||||
@@ -139,7 +163,7 @@ namespace Elwig.Documents {
|
|||||||
if (Payment.NetAmount != Payment.Amount) {
|
if (Payment.NetAmount != Payment.Amount) {
|
||||||
tbl1.AddCells(FormatRow("Zwischensumme", Payment.NetAmount, noTopBorder: noBorder));
|
tbl1.AddCells(FormatRow("Zwischensumme", Payment.NetAmount, noTopBorder: noBorder));
|
||||||
noBorder = false;
|
noBorder = false;
|
||||||
tbl1.AddCells(FormatRow(MemberModifier, Payment.Amount - Payment.NetAmount, add: true));
|
tbl1.AddCells(FormatRow(MemberModifier ?? "", Payment.Amount - Payment.NetAmount, add: true));
|
||||||
}
|
}
|
||||||
if (Credit == null) {
|
if (Credit == null) {
|
||||||
tbl1.AddCells(FormatRow("Gesamtbetrag", Payment.Amount, bold: true, noTopBorder: noBorder));
|
tbl1.AddCells(FormatRow("Gesamtbetrag", Payment.Amount, bold: true, noTopBorder: noBorder));
|
||||||
|
|||||||
@@ -5,34 +5,49 @@ using iText.Kernel.Pdf;
|
|||||||
using iText.Layout.Borders;
|
using iText.Layout.Borders;
|
||||||
using iText.Layout.Element;
|
using iText.Layout.Element;
|
||||||
using iText.Layout.Properties;
|
using iText.Layout.Properties;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class DeliveryConfirmation : BusinessDocument {
|
public class DeliveryConfirmation : BusinessDocument {
|
||||||
|
|
||||||
public new static string Name => "Anlieferungsbestätigung";
|
public new static string Name => "Anlieferungsbestätigung";
|
||||||
|
|
||||||
public Season Season;
|
private readonly int _year;
|
||||||
public DeliveryConfirmationDeliveryData Data;
|
public Season? Season;
|
||||||
|
public int MemberDeliveredWeight;
|
||||||
|
public DeliveryConfirmationDeliveryData? Data;
|
||||||
public string? Text = App.Client.TextDeliveryConfirmation;
|
public string? Text = App.Client.TextDeliveryConfirmation;
|
||||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||||
public List<MemberStat> MemberStats;
|
public List<MemberStat> MemberStats = [];
|
||||||
|
|
||||||
public DeliveryConfirmation(AppDbContext ctx, int year, Member m, DeliveryConfirmationDeliveryData data) :
|
public DeliveryConfirmation(int year, Member m, DateOnly? dateFrom, DeliveryConfirmationDeliveryData? data = null) :
|
||||||
base($"{Name} {year}", m) {
|
base($"{Name} {year}", m, dateFrom) {
|
||||||
Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("invalid season");
|
_year = year;
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
UseBillingAddress = true;
|
UseBillingAddress = true;
|
||||||
DocumentId = $"Anl.-Best. {Season.Year}/{m.MgNr}";
|
DocumentId = $"Anl.-Best. {_year}/{m.MgNr}";
|
||||||
Data = data;
|
Data = data;
|
||||||
MemberBuckets = ctx.GetMemberBuckets(Season.Year, m.MgNr).GetAwaiter().GetResult();
|
|
||||||
MemberStats = AppDbContext.GetMemberStats(Season.Year, m.MgNr).GetAwaiter().GetResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override async Task LoadData(AppDbContext ctx) {
|
||||||
base.RenderHeader(doc, pdf);
|
await base.LoadData(ctx);
|
||||||
|
Season = await ctx.FetchSeasons(_year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||||
|
MemberDeliveredWeight = await ctx.Deliveries
|
||||||
|
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
|
||||||
|
.SelectMany(d => d.Parts)
|
||||||
|
.SumAsync(p => p.Weight);
|
||||||
|
MemberBuckets = await ctx.GetMemberBuckets(Season.Year, Member.MgNr);
|
||||||
|
MemberStats = await AppDbContext.GetMemberStats(Season.Year, Member.MgNr);
|
||||||
|
Data ??= await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, Season.Year, Member);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
if (Data == null) throw new Exception("Call LoadData before BeforeRenderBody");
|
||||||
|
base.BeforeRenderBody(doc, pdf);
|
||||||
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
||||||
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
||||||
Aside?.AddCell(NewAsideCell("Saison", 2))
|
Aside?.AddCell(NewAsideCell("Saison", 2))
|
||||||
@@ -42,12 +57,13 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
if (Season == null || Data == null) throw new Exception("Call LoadData before RenderBody");
|
||||||
base.RenderBody(doc, pdf);
|
base.RenderBody(doc, pdf);
|
||||||
|
|
||||||
doc.Add(NewDeliveryListTable(Data));
|
doc.Add(NewDeliveryListTable(Data));
|
||||||
doc.Add(NewWeightsTable(MemberStats)
|
doc.Add(NewWeightsTable(MemberStats)
|
||||||
.SetMarginTopMM(10).SetKeepTogether(true));
|
.SetMarginTopMM(10).SetKeepTogether(true));
|
||||||
doc.Add(NewBucketTable(Season, MemberBuckets, includePayment: true)
|
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeight, includePayment: true)
|
||||||
.SetMarginTopMM(10).SetKeepTogether(true));
|
.SetMarginTopMM(10).SetKeepTogether(true));
|
||||||
|
|
||||||
if (Text != null) {
|
if (Text != null) {
|
||||||
@@ -120,8 +136,8 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i == p.Buckets.Length - 1) {
|
if (i == p.Buckets.Length - 1) {
|
||||||
sub.AddCell(NewTd($"{p.Weight:N0}"));
|
sub.AddCell(NewTd($"{p.Weight:N0}", right: true));
|
||||||
sub.AddCell(NewTd(p.IsNetWeight ? "\u2611" : "\u2610", 7, center: true).SetFont(SF).SetPadding(0));
|
sub.AddCell(NewTd(p.IsNetWeight ? "\u2611" : "\u2610", 7, right: true).SetFont(SF).SetPadding(0));
|
||||||
} else {
|
} else {
|
||||||
sub.AddCell(NewCell(colspan: 2));
|
sub.AddCell(NewCell(colspan: 2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ using iText.Layout.Borders;
|
|||||||
using iText.Layout.Element;
|
using iText.Layout.Element;
|
||||||
using iText.Layout.Layout;
|
using iText.Layout.Layout;
|
||||||
using iText.Layout.Properties;
|
using iText.Layout.Properties;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class DeliveryNote : BusinessDocument {
|
public class DeliveryNote : BusinessDocument {
|
||||||
@@ -17,7 +19,8 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
public Delivery Delivery;
|
public Delivery Delivery;
|
||||||
public string? Text;
|
public string? Text;
|
||||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
public int MemberDeliveredWeight;
|
||||||
|
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||||
|
|
||||||
// 0 - none
|
// 0 - none
|
||||||
// 1 - GA only
|
// 1 - GA only
|
||||||
@@ -25,19 +28,45 @@ namespace Elwig.Documents {
|
|||||||
// 3 - full
|
// 3 - full
|
||||||
public int DisplayStats = App.Client.ModeDeliveryNoteStats;
|
public int DisplayStats = App.Client.ModeDeliveryNoteStats;
|
||||||
|
|
||||||
public DeliveryNote(Delivery d, AppDbContext? ctx = null) :
|
public DeliveryNote(Delivery d) :
|
||||||
base($"{Name} Nr. {d.LsNr}", d.Member) {
|
base($"{Name} Nr. {d.LsNr}", d.Member, DateOnly.FromDateTime(d.ModifiedAt)) {
|
||||||
UseBillingAddress = true;
|
UseBillingAddress = true;
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
Delivery = d;
|
Delivery = d;
|
||||||
Text = App.Client.TextDeliveryNote;
|
Text = App.Client.TextDeliveryNote;
|
||||||
DocumentId = d.LsNr;
|
DocumentId = d.LsNr;
|
||||||
IsDoublePaged = true;
|
|
||||||
MemberBuckets = ctx?.GetMemberBuckets(d.Year, d.Member.MgNr).GetAwaiter().GetResult() ?? [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
public static async Task<DeliveryNote> Initialize(int year, int did) {
|
||||||
base.RenderHeader(doc, pdf);
|
using var ctx = new AppDbContext();
|
||||||
|
await ctx.WineOrigins.LoadAsync();
|
||||||
|
var d = await ctx.Deliveries
|
||||||
|
.Where(d => d.Year == year && d.DId == did)
|
||||||
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
|
.SingleAsync();
|
||||||
|
return new DeliveryNote(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<DeliveryNote> Initialize(string lsnr) {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
await ctx.WineOrigins.LoadAsync();
|
||||||
|
var d = await ctx.Deliveries
|
||||||
|
.Where(d => d.LsNr == lsnr)
|
||||||
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
|
.SingleAsync();
|
||||||
|
return new DeliveryNote(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task LoadData(AppDbContext ctx) {
|
||||||
|
await base.LoadData(ctx);
|
||||||
|
MemberDeliveredWeight = await ctx.DeliveryParts
|
||||||
|
.Where(d => d.Year == Delivery.Year && d.Delivery.MgNr == Member.MgNr)
|
||||||
|
.SumAsync(p => p.Weight);
|
||||||
|
MemberBuckets = await ctx.GetMemberBuckets(Delivery.Year, Member.MgNr) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
base.BeforeRenderBody(doc, pdf);
|
||||||
Aside?.AddCell(NewAsideCell("Lieferung", 2))
|
Aside?.AddCell(NewAsideCell("Lieferung", 2))
|
||||||
.AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr))
|
.AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr))
|
||||||
.AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}"))
|
.AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}"))
|
||||||
@@ -52,7 +81,7 @@ namespace Elwig.Documents {
|
|||||||
doc.Add(new KernedParagraph($"Anmerkung zur Lieferung: {Delivery.Comment}", 10).SetMarginsMM(5, 0, 0, 0));
|
doc.Add(new KernedParagraph($"Anmerkung zur Lieferung: {Delivery.Comment}", 10).SetMarginsMM(5, 0, 0, 0));
|
||||||
}
|
}
|
||||||
if (DisplayStats > 0) {
|
if (DisplayStats > 0) {
|
||||||
doc.Add(NewBucketTable(Delivery.Season, MemberBuckets, isTiny: true,
|
doc.Add(NewBucketTable(Delivery.Season, MemberBuckets, MemberDeliveredWeight, isTiny: true,
|
||||||
filter: DisplayStats > 2 ? null : DisplayStats == 1 ? [] : Delivery.Parts.Select(p => p.SortId).Distinct().ToList())
|
filter: DisplayStats > 2 ? null : DisplayStats == 1 ? [] : Delivery.Parts.Select(p => p.SortId).Distinct().ToList())
|
||||||
.SetKeepTogether(true)
|
.SetKeepTogether(true)
|
||||||
.SetMarginsMM(5, 0, 0, 0));
|
.SetMarginsMM(5, 0, 0, 0));
|
||||||
|
|||||||
@@ -49,14 +49,12 @@ namespace Elwig.Documents {
|
|||||||
public bool IsPreview = false;
|
public bool IsPreview = false;
|
||||||
private iText.Layout.Document? _doc;
|
private iText.Layout.Document? _doc;
|
||||||
|
|
||||||
public int CurrentNextSeason;
|
|
||||||
public string? DocumentId;
|
public string? DocumentId;
|
||||||
public string Title;
|
public string Title;
|
||||||
public string Author;
|
public string Author;
|
||||||
public DateOnly Date;
|
public DateOnly Date;
|
||||||
|
|
||||||
public Document(string title) {
|
public Document(string title) {
|
||||||
CurrentNextSeason = Utils.CurrentNextSeason;
|
|
||||||
Title = title;
|
Title = title;
|
||||||
Author = App.Client.NameFull;
|
Author = App.Client.NameFull;
|
||||||
Date = DateOnly.FromDateTime(Utils.Today);
|
Date = DateOnly.FromDateTime(Utils.Today);
|
||||||
@@ -88,11 +86,15 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int Render(string path) {
|
public int Render(string path) {
|
||||||
using var writer = new PdfWriter(path);
|
using (var writer = new PdfWriter(path)) {
|
||||||
return Render(writer);
|
Render(writer);
|
||||||
|
}
|
||||||
|
using var reader = new PdfReader(path);
|
||||||
|
using var pdf = new PdfDocument(reader);
|
||||||
|
return pdf.GetNumberOfPages();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int Render(PdfWriter writer) {
|
private void Render(PdfWriter writer) {
|
||||||
NF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\times.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
NF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\times.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
||||||
BF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesbd.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
BF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesbd.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
||||||
IF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesi.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
IF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesi.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
||||||
@@ -117,16 +119,16 @@ namespace Elwig.Documents {
|
|||||||
_doc = new iText.Layout.Document(pdf, iText.Kernel.Geom.PageSize.A4);
|
_doc = new iText.Layout.Document(pdf, iText.Kernel.Geom.PageSize.A4);
|
||||||
try {
|
try {
|
||||||
_doc.SetFont(NF).SetFontSize(12);
|
_doc.SetFont(NF).SetFontSize(12);
|
||||||
RenderHeader(_doc, pdf);
|
BeforeRenderBody(_doc, pdf);
|
||||||
RenderBody(_doc, pdf);
|
RenderBody(_doc, pdf);
|
||||||
var pageNum = pdf.GetNumberOfPages();
|
|
||||||
return pageNum;
|
|
||||||
} finally {
|
} finally {
|
||||||
_doc.Close();
|
_doc.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { }
|
protected virtual async Task LoadData(AppDbContext ctx) { }
|
||||||
|
|
||||||
|
protected virtual void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
||||||
|
|
||||||
protected virtual void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
protected virtual void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
||||||
|
|
||||||
@@ -134,7 +136,7 @@ namespace Elwig.Documents {
|
|||||||
return new KernedParagraph(App.Client.NameFull, 10);
|
return new KernedParagraph(App.Client.NameFull, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Generate(CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
public async Task Generate(AppDbContext ctx, CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
||||||
if (_pdfFile != null)
|
if (_pdfFile != null)
|
||||||
return;
|
return;
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
@@ -150,84 +152,78 @@ namespace Elwig.Documents {
|
|||||||
using var mergedPdf = new PdfDocument(writer);
|
using var mergedPdf = new PdfDocument(writer);
|
||||||
var merger = new PdfMerger(mergedPdf);
|
var merger = new PdfMerger(mergedPdf);
|
||||||
|
|
||||||
PdfPage? letterheadPage = null;
|
(PdfPage Page, int InsertIndex, int DocIndex)? letterhead = null;
|
||||||
int letterheadInsertIndex = 0;
|
|
||||||
int letterheadDocIndex = 0;
|
|
||||||
|
|
||||||
|
int p = mergedPdf.GetNumberOfPages();
|
||||||
for (int i = 0; i < m.Documents.Count; i++) {
|
for (int i = 0; i < m.Documents.Count; i++) {
|
||||||
if (cancelToken?.IsCancellationRequested ?? false)
|
if (cancelToken?.IsCancellationRequested ?? false)
|
||||||
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||||
var doc = m.Documents[i];
|
var doc = m.Documents[i];
|
||||||
int p0 = mergedPdf.GetNumberOfPages();
|
int p0 = p;
|
||||||
|
|
||||||
if (letterheadPage != null && doc is Letterhead) {
|
if (letterhead != null && doc is Letterhead) {
|
||||||
if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) {
|
if (p0 <= letterhead.Value.InsertIndex) {
|
||||||
mergedPdf.AddPage(letterheadPage);
|
mergedPdf.AddPage(letterhead.Value.Page);
|
||||||
mergedPdf.AddNewPage();
|
mergedPdf.AddNewPage();
|
||||||
} else {
|
} else {
|
||||||
mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage);
|
mergedPdf.AddPage(letterhead.Value.InsertIndex + 1, letterhead.Value.Page);
|
||||||
mergedPdf.AddNewPage(letterheadInsertIndex + 2);
|
mergedPdf.AddNewPage(letterhead.Value.InsertIndex + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pageNums[letterheadDocIndex] = 1;
|
pageNums[letterhead.Value.DocIndex] = 1;
|
||||||
letterheadPage = null;
|
letterhead = null;
|
||||||
|
p += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc is RawPdfDocument) {
|
if (doc is RawPdfDocument) {
|
||||||
if (IsDoublePaged && doc is Letterhead) {
|
using var reader = new PdfReader(doc.PdfPath);
|
||||||
using var reader = new PdfReader(doc.PdfPath);
|
using var src = new PdfDocument(reader);
|
||||||
using var src = new PdfDocument(reader);
|
merger.Merge(src, 1, src.GetNumberOfPages());
|
||||||
letterheadPage = src.GetPage(1).CopyTo(mergedPdf);
|
p += src.GetNumberOfPages();
|
||||||
letterheadInsertIndex = p0;
|
|
||||||
letterheadDocIndex = i;
|
|
||||||
} else {
|
|
||||||
using var reader = new PdfReader(doc.PdfPath);
|
|
||||||
using var src = new PdfDocument(reader);
|
|
||||||
merger.Merge(src, 1, src.GetNumberOfPages());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
await doc.LoadData(ctx);
|
||||||
int pageNum = doc.Render(tmpPdf.FilePath);
|
int pageNum = doc.Render(tmpPdf.FilePath);
|
||||||
if (IsDoublePaged && doc is Letterhead) {
|
if (IsDoublePaged && doc is Letterhead) {
|
||||||
using var reader = new PdfReader(tmpPdf.FilePath);
|
using var reader = new PdfReader(tmpPdf.FilePath);
|
||||||
using var src = new PdfDocument(reader);
|
using var src = new PdfDocument(reader);
|
||||||
letterheadPage = src.GetPage(1).CopyTo(mergedPdf);
|
letterhead = (src.GetPage(1).CopyTo(mergedPdf), p0, i);
|
||||||
letterheadInsertIndex = p0;
|
|
||||||
letterheadDocIndex = i;
|
|
||||||
} else {
|
} else {
|
||||||
using var reader = new PdfReader(tmpPdf.FilePath);
|
using var reader = new PdfReader(tmpPdf.FilePath);
|
||||||
using var src = new PdfDocument(reader);
|
using var src = new PdfDocument(reader);
|
||||||
merger.Merge(src, 1, pageNum);
|
merger.Merge(src, 1, pageNum);
|
||||||
|
p += pageNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int p1 = mergedPdf.GetNumberOfPages();
|
int p1 = p;
|
||||||
pageNums.Add(p1 - p0);
|
pageNums.Add(p1 - p0);
|
||||||
|
|
||||||
if (IsDoublePaged && doc is not Letterhead && mergedPdf.GetNumberOfPages() % 2 != 0) {
|
if (IsDoublePaged && doc is not Letterhead && p % 2 != 0) {
|
||||||
if (letterheadPage != null) {
|
if (letterhead != null) {
|
||||||
mergedPdf.AddPage(letterheadPage);
|
mergedPdf.AddPage(letterhead.Value.Page);
|
||||||
letterheadPage = null;
|
letterhead = null;
|
||||||
} else {
|
} else {
|
||||||
mergedPdf.AddNewPage();
|
mergedPdf.AddNewPage();
|
||||||
}
|
}
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress?.Report(100.0 * (i + 1) / (m.Documents.Count + 1));
|
progress?.Report(100.0 * (i + 1) / (m.Documents.Count + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (letterheadPage != null) {
|
if (letterhead != null) {
|
||||||
if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) {
|
if (p <= letterhead.Value.InsertIndex) {
|
||||||
mergedPdf.AddPage(letterheadPage.CopyTo(mergedPdf));
|
mergedPdf.AddPage(letterhead.Value.Page);
|
||||||
mergedPdf.AddNewPage();
|
mergedPdf.AddNewPage();
|
||||||
} else {
|
} else {
|
||||||
mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage.CopyTo(mergedPdf));
|
mergedPdf.AddPage(letterhead.Value.InsertIndex + 1, letterhead.Value.Page);
|
||||||
mergedPdf.AddNewPage(letterheadInsertIndex + 2);
|
mergedPdf.AddNewPage(letterhead.Value.InsertIndex + 2);
|
||||||
}
|
}
|
||||||
|
pageNums[letterhead.Value.DocIndex] = 1;
|
||||||
pageNums[letterheadDocIndex] = 1;
|
p += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
TotalPages = pageNums.Sum();
|
TotalPages = p;
|
||||||
} catch {
|
} catch {
|
||||||
pdf.Dispose();
|
pdf.Dispose();
|
||||||
throw;
|
throw;
|
||||||
@@ -238,6 +234,7 @@ namespace Elwig.Documents {
|
|||||||
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||||
var pdf = new TempFile("pdf");
|
var pdf = new TempFile("pdf");
|
||||||
try {
|
try {
|
||||||
|
await LoadData(ctx);
|
||||||
TotalPages = Render(pdf.FilePath);
|
TotalPages = Render(pdf.FilePath);
|
||||||
} catch {
|
} catch {
|
||||||
pdf.Dispose();
|
pdf.Dispose();
|
||||||
@@ -297,7 +294,7 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
protected Cell NewTh(string? text, float fontSize = 8, int rowspan = 1, int colspan = 1, bool left = false, bool rotated = false) {
|
protected Cell NewTh(string? text, float fontSize = 8, int rowspan = 1, int colspan = 1, bool left = false, bool rotated = false) {
|
||||||
var p = new KernedParagraph(text ?? "", fontSize);
|
var p = new KernedParagraph(text ?? "", fontSize);
|
||||||
if (rotated) p.SetRotationAngle(rotated ? 0.5 * Math.PI : 0);
|
if (rotated) p.SetRotationAngle(0.5 * Math.PI);
|
||||||
var cell = NewCell(p, rowspan: rowspan, colspan: colspan)
|
var cell = NewCell(p, rowspan: rowspan, colspan: colspan)
|
||||||
.SetTextAlignment(left ? TextAlignment.LEFT : TextAlignment.CENTER)
|
.SetTextAlignment(left ? TextAlignment.LEFT : TextAlignment.CENTER)
|
||||||
.SetVerticalAlignment(VerticalAlignment.MIDDLE)
|
.SetVerticalAlignment(VerticalAlignment.MIDDLE)
|
||||||
@@ -394,6 +391,8 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageEnd(PdfDocumentEvent evt) {
|
private void OnPageEnd(PdfDocumentEvent evt) {
|
||||||
|
if (_doc is Letterhead) return;
|
||||||
|
|
||||||
var pdf = evt.GetDocument();
|
var pdf = evt.GetDocument();
|
||||||
var page = evt.GetPage();
|
var page = evt.GetPage();
|
||||||
var pageNum = pdf.GetPageNumber(page);
|
var pageNum = pdf.GetPageNumber(page);
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
|
using iText.Kernel.Pdf;
|
||||||
|
using iText.Kernel.Pdf.Canvas;
|
||||||
|
using iText.Layout;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class Letterhead : BusinessDocument {
|
public class Letterhead : BusinessDocument {
|
||||||
public Letterhead(Member m) :
|
public Letterhead(Member m) :
|
||||||
base($"Briefkopf {m.FullName}", m, true) {
|
base($"Briefkopf {m.FullName}", m, null, includeSender: true) {
|
||||||
Aside = null;
|
}
|
||||||
|
|
||||||
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
// do not render anything except this
|
||||||
|
var page = pdf.AddNewPage();
|
||||||
|
var pageSize = page.GetPageSize();
|
||||||
|
var pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdf);
|
||||||
|
using var canvas = new Canvas(pdfCanvas, pageSize);
|
||||||
|
RenderAddress(canvas, pageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,31 +5,52 @@ using iText.Kernel.Pdf;
|
|||||||
using iText.Layout.Borders;
|
using iText.Layout.Borders;
|
||||||
using iText.Layout.Element;
|
using iText.Layout.Element;
|
||||||
using iText.Layout.Properties;
|
using iText.Layout.Properties;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class MemberDataSheet : BusinessDocument {
|
public class MemberDataSheet : BusinessDocument {
|
||||||
|
|
||||||
public new static string Name => "Stammdatenblatt";
|
public new static string Name => "Stammdatenblatt";
|
||||||
|
|
||||||
public Season Season;
|
public Season? Season;
|
||||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
public int MemberDeliveredWeight;
|
||||||
public List<AreaCom> ActiveAreaCommitments;
|
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||||
|
public List<AreaCom> ActiveAreaCommitments = [];
|
||||||
|
|
||||||
public MemberDataSheet(Member m, AppDbContext ctx) : base($"{Name} {m.AdministrativeName}", m) {
|
public MemberDataSheet(Member m) :
|
||||||
|
base($"{Name} {m.AdministrativeName}", m, DateOnly.FromDateTime(m.ModifiedAt)) {
|
||||||
|
ShowDateAndLocation = true;
|
||||||
DocumentId = $"{Name} {m.MgNr}";
|
DocumentId = $"{Name} {m.MgNr}";
|
||||||
Season = ctx.Seasons.ToList().MaxBy(s => s.Year) ?? throw new ArgumentException("invalid season");
|
}
|
||||||
MemberBuckets = ctx.GetMemberBuckets(Utils.CurrentYear, m.MgNr).GetAwaiter().GetResult();
|
|
||||||
ActiveAreaCommitments = [.. m.ActiveAreaCommitments(ctx)];
|
public static async Task<MemberDataSheet> Initialize(int mgnr) {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
return new MemberDataSheet(await ctx.FetchMembers(mgnr, true, true).SingleAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task LoadData(AppDbContext ctx) {
|
||||||
|
await base.LoadData(ctx);
|
||||||
|
Season = await ctx.FetchSeasons().FirstOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||||
|
MemberBuckets = await ctx.GetMemberBuckets(Utils.CurrentYear, Member.MgNr);
|
||||||
|
ActiveAreaCommitments = await Member.ActiveAreaCommitments(ctx)
|
||||||
|
.Include(c => c.Contract).ThenInclude(c => c.Revisions)
|
||||||
|
.ToListAsync();
|
||||||
|
MemberDeliveredWeight = await ctx.Deliveries
|
||||||
|
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
|
||||||
|
.SelectMany(d => d.Parts)
|
||||||
|
.SumAsync(p => p.Weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
if (Season == null) throw new Exception("Call LoadData before RenderBody");
|
||||||
base.RenderBody(doc, pdf);
|
base.RenderBody(doc, pdf);
|
||||||
doc.Add(NewMemberData().SetMarginBottomMM(5));
|
doc.Add(NewMemberData(Season).SetMarginBottomMM(5));
|
||||||
doc.Add(NewBucketTable(Season, MemberBuckets, includeDelivery: false));
|
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeight, includeDelivery: false));
|
||||||
if (ActiveAreaCommitments.Count != 0) {
|
if (ActiveAreaCommitments.Count != 0) {
|
||||||
bool firstOnPage = false;
|
bool firstOnPage = false;
|
||||||
if (pdf.GetNumberOfPages() == 1) {
|
if (pdf.GetNumberOfPages() == 1) {
|
||||||
@@ -37,7 +58,7 @@ namespace Elwig.Documents {
|
|||||||
firstOnPage = true;
|
firstOnPage = true;
|
||||||
}
|
}
|
||||||
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 12, 0));
|
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 12, 0));
|
||||||
doc.Add(NewAreaComTable());
|
doc.Add(NewAreaComTable(ActiveAreaCommitments));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +72,7 @@ namespace Elwig.Documents {
|
|||||||
.SetPaddingRightMM(0);
|
.SetPaddingRightMM(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewMemberData() {
|
protected Table NewMemberData(Season season) {
|
||||||
var tbl = new Table(ColsMM(30.0, 51.5, 20.0, 12.0, 18.0, 31.5))
|
var tbl = new Table(ColsMM(30.0, 51.5, 20.0, 12.0, 18.0, 31.5))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
@@ -116,7 +137,7 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewDataTh("UID:", colspan: 2)).AddCell(NewTd(Member.UstIdNr, colspan: 2))
|
.AddCell(NewDataTh("UID:", colspan: 2)).AddCell(NewTd(Member.UstIdNr, colspan: 2))
|
||||||
.AddCell(NewDataTh("Stammgemeinde:")).AddCell(NewTd(Member.DefaultKg?.Name))
|
.AddCell(NewDataTh("Stammgemeinde:")).AddCell(NewTd(Member.DefaultKg?.Name))
|
||||||
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
||||||
.Add(Normal($"({(Member.IsBuchführend ? Season.VatNormal : Season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
.Add(Normal($"({(Member.IsBuchführend ? season.VatNormal : season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
||||||
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
||||||
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(Member.IsOrganic ? "Ja" : "Nein", colspan: 2))
|
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(Member.IsOrganic ? "Ja" : "Nein", colspan: 2))
|
||||||
.AddCell(NewDataHdr("Genossenschaft", colspan: 6))
|
.AddCell(NewDataHdr("Genossenschaft", colspan: 6))
|
||||||
@@ -133,10 +154,10 @@ namespace Elwig.Documents {
|
|||||||
return tbl;
|
return tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewAreaComTable() {
|
protected Table NewAreaComTable(IEnumerable<AreaCom> activeAreaComs) {
|
||||||
var areaComs = ActiveAreaCommitments.GroupBy(a => a.AreaComType).Select(group => new {
|
var areaComs = activeAreaComs.GroupBy(a => a.AreaComType).Select(group => new {
|
||||||
Type = group.Key,
|
Type = group.Key,
|
||||||
AreaComs = group.OrderBy(c => c.Kg.AtKg.Name).ToList(),
|
AreaComs = group.OrderBy(c => c.Contract.Kg.AtKg.Name).ToList(),
|
||||||
Size = group.Sum(c => c.Area)
|
Size = group.Sum(c => c.Area)
|
||||||
}).OrderByDescending(a => a.Size).ToList();
|
}).OrderByDescending(a => a.Size).ToList();
|
||||||
|
|
||||||
@@ -164,18 +185,19 @@ namespace Elwig.Documents {
|
|||||||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER));
|
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER));
|
||||||
|
|
||||||
foreach (var areaCom in contractType.AreaComs) {
|
foreach (var areaCom in contractType.AreaComs) {
|
||||||
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{areaCom.Kg.AtKg.Name} ")).Add(Normal($"({areaCom.Kg.AtKg.KgNr:00000})", 8))))
|
var c = areaCom.Contract;
|
||||||
.AddCell(NewTd(areaCom.Rd?.Name))
|
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{c.Kg.AtKg.Name} ")).Add(Normal($"({c.Kg.AtKg.KgNr:00000})", 8))))
|
||||||
|
.AddCell(NewTd(c.Rd?.Name))
|
||||||
.AddCell(NewTd(Regex.Replace(areaCom.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
.AddCell(NewTd(Regex.Replace(areaCom.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
||||||
.AddCell(NewTd($"{areaCom.Area:N0}", right: true))
|
.AddCell(NewTd($"{areaCom.Area:N0}", right: true))
|
||||||
.AddCell(NewTd(areaCom.WineCult?.Name, center: true))
|
.AddCell(NewTd(areaCom.WineCult?.Name, center: true))
|
||||||
.AddCell(NewTd(areaCom.YearTo == null ? (areaCom.YearFrom == null ? "unbefristet" : $"ab {areaCom.YearFrom}") : (areaCom.YearFrom == null ? $"bis {areaCom.YearTo}" : $"{areaCom.YearFrom}–{areaCom.YearTo}"), center: true));
|
.AddCell(NewTd(c.YearTo == null ? (c.YearFrom == null ? "unbefristet" : $"ab {c.YearFrom}") : (c.YearFrom == null ? $"bis {c.YearTo}" : $"{c.YearFrom}–{c.YearTo}"), center: true));
|
||||||
lastContract = contractType.Type.DisplayName;
|
lastContract = contractType.Type.DisplayName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||||
tbl.AddCell(NewTd($"{ActiveAreaCommitments.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
tbl.AddCell(NewTd($"{activeAreaComs.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||||
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||||
|
|
||||||
return tbl;
|
return tbl;
|
||||||
|
|||||||
@@ -7,40 +7,60 @@ using iText.Kernel.Pdf;
|
|||||||
using iText.Layout.Borders;
|
using iText.Layout.Borders;
|
||||||
using iText.Layout.Element;
|
using iText.Layout.Element;
|
||||||
using iText.Layout.Properties;
|
using iText.Layout.Properties;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class PaymentVariantSummary : Document {
|
public class PaymentVariantSummary : Document {
|
||||||
|
|
||||||
public new static string Name => "Auszahlungsvariante";
|
public new static string Name => "Auszahlungsvariante";
|
||||||
|
|
||||||
public PaymentVariantSummaryData Data;
|
public PaymentVariantSummaryData? Data;
|
||||||
public PaymentVar Variant;
|
public PaymentVar Variant;
|
||||||
public BillingData BillingData;
|
public BillingData BillingData;
|
||||||
public string CurrencySymbol;
|
public string CurrencySymbol;
|
||||||
public int MemberNum;
|
public int MemberNum;
|
||||||
public int DeliveryNum;
|
public int DeliveryNum;
|
||||||
public int DeliveryPartNum;
|
public int DeliveryPartNum;
|
||||||
public List<ModifierStat> ModifierStat;
|
public List<ModifierStat>? ModifierStat;
|
||||||
public Dictionary<string, Modifier> Modifiers;
|
public Dictionary<string, Modifier>? Modifiers;
|
||||||
|
|
||||||
public PaymentVariantSummary(PaymentVar v, PaymentVariantSummaryData data) :
|
private List<Credit> _credits = [];
|
||||||
|
private List<PaymentDeliveryPart> _parts = [];
|
||||||
|
|
||||||
|
public PaymentVariantSummary(PaymentVar v, PaymentVariantSummaryData? data = null) :
|
||||||
base($"{Name} {v.Year} - {v.Name}") {
|
base($"{Name} {v.Year} - {v.Name}") {
|
||||||
Variant = v;
|
Variant = v;
|
||||||
BillingData = BillingData.FromJson(v.Data);
|
BillingData = BillingData.FromJson(v.Data);
|
||||||
Data = data;
|
Data = data;
|
||||||
CurrencySymbol = v.Season.Currency.Symbol ?? v.Season.Currency.Code;
|
CurrencySymbol = v.Season.Currency.Symbol ?? v.Season.Currency.Code;
|
||||||
MemberNum = v.Credits.Count;
|
}
|
||||||
|
|
||||||
|
public static async Task<PaymentVariantSummary> Initialize(int year, int avnr, PaymentVariantSummaryData? data = null) {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
var v = await ctx.PaymentVariants
|
||||||
|
.Where(v => v.Year == year && v.AvNr == avnr)
|
||||||
|
.SingleAsync();
|
||||||
|
return new PaymentVariantSummary(v, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task LoadData(AppDbContext ctx) {
|
||||||
|
_credits = await ctx.Credits.Where(c => c.Year == Variant.Year && c.AvNr == Variant.AvNr).ToListAsync();
|
||||||
|
_parts = await ctx.PaymentDeliveryParts.Where(p => p.Year == Variant.Year && p.AvNr == Variant.AvNr).ToListAsync();
|
||||||
|
MemberNum = _credits.Count;
|
||||||
IsPreview = MemberNum == 0;
|
IsPreview = MemberNum == 0;
|
||||||
DeliveryNum = v.DeliveryPartPayments.DistinctBy(p => p.DeliveryPart.Delivery).Count();
|
DeliveryNum = await ctx.Deliveries.Where(d => d.Year == Variant.Year).CountAsync();
|
||||||
DeliveryPartNum = v.DeliveryPartPayments.Count;
|
DeliveryPartNum = await ctx.DeliveryParts.Where(d => d.Year == Variant.Year).CountAsync();
|
||||||
ModifierStat = AppDbContext.GetModifierStats(v.Year, v.AvNr).GetAwaiter().GetResult();
|
Data ??= await PaymentVariantSummaryData.ForPaymentVariant(Variant, ctx.PaymentVariantSummaryRows);
|
||||||
Modifiers = v.Season.Modifiers.ToDictionary(m => m.ModId);
|
ModifierStat = await AppDbContext.GetModifierStats(Variant.Year, Variant.AvNr);
|
||||||
|
Modifiers = await ctx.FetchModifiers(Variant.Year).ToDictionaryAsync(m => m.ModId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
if (Data == null || Modifiers == null || ModifierStat == null) throw new Exception("Call LoadData before RenderBody");
|
||||||
base.RenderBody(doc, pdf);
|
base.RenderBody(doc, pdf);
|
||||||
doc.Add(new KernedParagraph($"{Name} Lese {Variant.Year}", 24)
|
doc.Add(new KernedParagraph($"{Name} Lese {Variant.Year}", 24)
|
||||||
.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
||||||
@@ -48,10 +68,10 @@ namespace Elwig.Documents {
|
|||||||
doc.Add(new KernedParagraph(Variant.Name, 14)
|
doc.Add(new KernedParagraph(Variant.Name, 14)
|
||||||
.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
||||||
.SetMarginsMM(0, 0, 10, 0));
|
.SetMarginsMM(0, 0, 10, 0));
|
||||||
doc.Add(NewVariantStatTable().SetMarginBottomMM(10));
|
doc.Add(NewVariantStatTable(Data).SetMarginBottomMM(10));
|
||||||
doc.Add(NewModifierStatTable());
|
doc.Add(NewModifierStatTable(Modifiers, ModifierStat));
|
||||||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||||||
doc.Add(NewPriceTable());
|
doc.Add(NewPriceTable(Data));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Cell NewSectionHdr(string text, int colspan = 1, bool borderLeft = false) {
|
protected Cell NewSectionHdr(string text, int colspan = 1, bool borderLeft = false) {
|
||||||
@@ -67,33 +87,33 @@ namespace Elwig.Documents {
|
|||||||
.SetBorderLeft(borderLeft ? new SolidBorder(BorderThickness) : Border.NO_BORDER);
|
.SetBorderLeft(borderLeft ? new SolidBorder(BorderThickness) : Border.NO_BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewVariantStatTable() {
|
protected Table NewVariantStatTable(PaymentVariantSummaryData data) {
|
||||||
var tbl = new Table(ColsMM(20, 30, 4.5, 4.5, 23.5, 47.5, 15, 20))
|
var tbl = new Table(ColsMM(20, 30, 4.5, 4.5, 23.5, 47.5, 15, 20))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
.SetBorder(new SolidBorder(BorderThickness));
|
.SetBorder(new SolidBorder(BorderThickness));
|
||||||
|
|
||||||
//var sum1 = Variant.DeliveryPartPayments.Sum(p => p.NetAmount);
|
//var sum1 = _parts.Sum(p => p.NetAmount);
|
||||||
//var sum2 = Variant.Credits.Sum(p => p.); //Variant.MemberPayments.Sum(p => p.Amount);
|
//var sum2 = _credits.Sum(p => p.); //Variant.MemberPayments.Sum(p => p.Amount);
|
||||||
var deliveryModifiers = Variant.DeliveryPartPayments.Sum(p => p.Amount - p.NetAmount);
|
var deliveryModifiers = _parts.Sum(p => p.Amount - p.NetAmount);
|
||||||
var memberModifiers = Variant.Credits.Sum(c => c.Payment.Amount - c.Payment.NetAmount);
|
var memberModifiers = _credits.Sum(c => c.Payment.Amount - c.Payment.NetAmount);
|
||||||
var sum2 = Variant.Credits.Sum(p => p.NetAmount);
|
var sum2 = _credits.Sum(p => p.NetAmount);
|
||||||
var sum1 = sum2 - deliveryModifiers - memberModifiers;
|
var sum1 = sum2 - deliveryModifiers - memberModifiers;
|
||||||
var payed = -Variant.Credits.Sum(p => p.PrevNetAmount ?? 0m);
|
var payed = -_credits.Sum(p => p.PrevNetAmount ?? 0m);
|
||||||
var netSum = Variant.Credits.Sum(p => p.NetAmount) - Variant.Credits.Sum(p => p.PrevNetAmount ?? 0m);
|
var netSum = _credits.Sum(p => p.NetAmount) - _credits.Sum(p => p.PrevNetAmount ?? 0m);
|
||||||
var vat = Variant.Credits.Sum(p => p.VatAmount);
|
var vat = _credits.Sum(p => p.VatAmount);
|
||||||
var grossSum = Variant.Credits.Sum(p => p.GrossAmount);
|
var grossSum = _credits.Sum(p => p.GrossAmount);
|
||||||
var totalMods = Variant.Credits.Sum(p => p.Modifiers ?? 0m);
|
var totalMods = _credits.Sum(p => p.Modifiers ?? 0m);
|
||||||
var considered = -Variant.Credits.Sum(p => p.PrevModifiers ?? 0m);
|
var considered = -_credits.Sum(p => p.PrevModifiers ?? 0m);
|
||||||
var totalSum = Variant.Credits.Sum(p => p.Amount);
|
var totalSum = _credits.Sum(p => p.Amount);
|
||||||
|
|
||||||
var weiRows = Data.Rows.Where(r => r.QualityLevel == "Wein");
|
var weiRows = data.Rows.Where(r => r.QualityLevel == "Wein");
|
||||||
var minWei = weiRows.Min(r => r.Ungeb.MinPrice);
|
var minWei = weiRows.Min(r => r.Ungeb.MinPrice);
|
||||||
var maxWei = weiRows.Max(r => r.Ungeb.MaxPrice);
|
var maxWei = weiRows.Max(r => r.Ungeb.MaxPrice);
|
||||||
var quwRows = Data.Rows.Where(r => r.QualityLevel != "Wein");
|
var quwRows = data.Rows.Where(r => r.QualityLevel != "Wein");
|
||||||
var minPrice = quwRows.Min(r => r.Ungeb.MinPrice);
|
var minPrice = quwRows.Min(r => r.Ungeb.MinPrice);
|
||||||
var maxPrice = quwRows.Max(r => r.Ungeb.MaxPrice);
|
var maxPrice = quwRows.Max(r => r.Ungeb.MaxPrice);
|
||||||
var gebRows = Data.Rows
|
var gebRows = data.Rows
|
||||||
.Where(r => r.Geb.MaxPrice != null && r.Ungeb.MinPrice != null)
|
.Where(r => r.Geb.MaxPrice != null && r.Ungeb.MinPrice != null)
|
||||||
.Select(r => r.Geb.MaxPrice - r.Ungeb.MinPrice);
|
.Select(r => r.Geb.MaxPrice - r.Ungeb.MinPrice);
|
||||||
var minGeb = gebRows.Min();
|
var minGeb = gebRows.Min();
|
||||||
@@ -191,26 +211,26 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewTd(CurrencySymbol))
|
.AddCell(NewTd(CurrencySymbol))
|
||||||
.AddCell(NewTd($"{Math.Abs(totalMods):N2}", right: true))
|
.AddCell(NewTd($"{Math.Abs(totalMods):N2}", right: true))
|
||||||
.AddCell(NewSectionTh("Menge (ungebunden):", borderLeft: true, borderTop: true))
|
.AddCell(NewSectionTh("Menge (ungebunden):", borderLeft: true, borderTop: true))
|
||||||
.AddCell(NewTd($"{Data.Rows.Sum(r => r.Ungeb.Weight):N0} kg", colspan: 2, right: true, borderTop: true))
|
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ungeb.Weight):N0} kg", colspan: 2, right: true, borderTop: true))
|
||||||
|
|
||||||
.AddCell(NewSectionTh("Bereits berücksichtigte Abzüge:", colspan: 2))
|
.AddCell(NewSectionTh("Bereits berücksichtigte Abzüge:", colspan: 2))
|
||||||
.AddCell(NewTd(Utils.GetSign(considered)))
|
.AddCell(NewTd(Utils.GetSign(considered)))
|
||||||
.AddCell(NewTd(CurrencySymbol))
|
.AddCell(NewTd(CurrencySymbol))
|
||||||
.AddCell(NewTd($"{Math.Abs(considered):N2}", right: true))
|
.AddCell(NewTd($"{Math.Abs(considered):N2}", right: true))
|
||||||
.AddCell(NewSectionTh("Menge (gebunden):", borderLeft: true))
|
.AddCell(NewSectionTh("Menge (gebunden):", borderLeft: true))
|
||||||
.AddCell(NewTd($"{Data.Rows.Sum(r => r.Geb.Weight + r.LowGeb.Weight):N0} kg", colspan: 2, right: true))
|
.AddCell(NewTd($"{data.Rows.Sum(r => r.Geb.Weight + r.LowGeb.Weight):N0} kg", colspan: 2, right: true))
|
||||||
|
|
||||||
.AddCell(NewSectionTh("Auszahlungsbetrag:", colspan: 2))
|
.AddCell(NewSectionTh("Auszahlungsbetrag:", colspan: 2))
|
||||||
.AddCell(NewTd(borderTop: true))
|
.AddCell(NewTd(borderTop: true))
|
||||||
.AddCell(NewTd(CurrencySymbol, borderTop: true))
|
.AddCell(NewTd(CurrencySymbol, borderTop: true))
|
||||||
.AddCell(NewTd($"{totalSum:N2}", right: true, borderTop: true))
|
.AddCell(NewTd($"{totalSum:N2}", right: true, borderTop: true))
|
||||||
.AddCell(NewSectionTh("Gesamtmenge:", borderLeft: true))
|
.AddCell(NewSectionTh("Gesamtmenge:", borderLeft: true))
|
||||||
.AddCell(NewTd($"{Data.Rows.Sum(r => r.Ungeb.Weight + r.LowGeb.Weight + r.Geb.Weight):N0} kg", colspan: 2, right: true, borderTop: true));
|
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ungeb.Weight + r.LowGeb.Weight + r.Geb.Weight):N0} kg", colspan: 2, right: true, borderTop: true));
|
||||||
|
|
||||||
return tbl;
|
return tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewModifierStatTable() {
|
protected Table NewModifierStatTable(Dictionary<string, Modifier> modifiers, IEnumerable<ModifierStat> modStat) {
|
||||||
var tbl = new Table(ColsMM(35, 30, 25, 25, 25, 25))
|
var tbl = new Table(ColsMM(35, 30, 25, 25, 25, 25))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
@@ -228,8 +248,8 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewTh($"[{CurrencySymbol}]"))
|
.AddCell(NewTh($"[{CurrencySymbol}]"))
|
||||||
.AddCell(NewTh($"[{CurrencySymbol}]"));
|
.AddCell(NewTh($"[{CurrencySymbol}]"));
|
||||||
|
|
||||||
foreach (var m in ModifierStat) {
|
foreach (var m in modStat) {
|
||||||
var mod = Modifiers[m.ModId];
|
var mod = modifiers[m.ModId];
|
||||||
tbl.AddCell(NewTd(mod.Name, italic: true))
|
tbl.AddCell(NewTd(mod.Name, italic: true))
|
||||||
.AddCell(NewTd(mod.ValueStr, right: true))
|
.AddCell(NewTd(mod.ValueStr, right: true))
|
||||||
.AddCell(NewTd($"{m.Count:N0}", right: true))
|
.AddCell(NewTd($"{m.Count:N0}", right: true))
|
||||||
@@ -241,7 +261,7 @@ namespace Elwig.Documents {
|
|||||||
return tbl;
|
return tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewPriceTable() {
|
protected Table NewPriceTable(PaymentVariantSummaryData data) {
|
||||||
var tbl = new Table(ColsMM(25, 19, 18, 15, 18, 15, 18, 15, 22))
|
var tbl = new Table(ColsMM(25, 19, 18, 15, 18, 15, 18, 15, 22))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||||
@@ -262,10 +282,10 @@ namespace Elwig.Documents {
|
|||||||
.AddHeaderCell(NewTh($"[{CurrencySymbol}]"));
|
.AddHeaderCell(NewTh($"[{CurrencySymbol}]"));
|
||||||
|
|
||||||
string? lastHdr = null;
|
string? lastHdr = null;
|
||||||
foreach (var row in Data.Rows) {
|
foreach (var row in data.Rows) {
|
||||||
var hdr = $"{row.Variety}{(row.Attribute != null ? " / " : "")}{row.Attribute}{(row.Cultivation != null ? " / " : "")}{row.Cultivation}";
|
var hdr = $"{row.Variety}{(row.Attribute != null ? " / " : "")}{row.Attribute}{(row.Cultivation != null ? " / " : "")}{row.Cultivation}";
|
||||||
if (lastHdr != hdr) {
|
if (lastHdr != hdr) {
|
||||||
var rows = Data.Rows
|
var rows = data.Rows
|
||||||
.Where(r => r.Variety == row.Variety && r.Attribute == row.Attribute && r.Cultivation == row.Cultivation)
|
.Where(r => r.Variety == row.Variety && r.Attribute == row.Attribute && r.Cultivation == row.Cultivation)
|
||||||
.ToList();
|
.ToList();
|
||||||
var border = lastHdr != null;
|
var border = lastHdr != null;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>1.0.3.4</Version>
|
<Version>1.0.5.0</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
@@ -23,18 +23,17 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="148.0.7734" />
|
<PackageReference Include="bblanchon.PDFium.Win32" Version="148.0.7776" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="itext" Version="9.5.0" />
|
<PackageReference Include="itext" Version="9.6.0" />
|
||||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.5.0" />
|
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.6.0" />
|
||||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||||
<PackageReference Include="MailKit" Version="4.15.1" />
|
<PackageReference Include="MailKit" Version="4.15.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.5" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.5" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.5" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.5" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.5" />
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3856.49" />
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3856.49" />
|
||||||
<PackageReference Include="NJsonSchema" Version="11.5.2" />
|
<PackageReference Include="NJsonSchema" Version="11.5.2" />
|
||||||
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
|
<PackageReference Include="ScottPlot.WPF" Version="5.1.58" />
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
|
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
|
||||||
<PackageReference Include="System.IO.Hashing" Version="10.0.5" />
|
<PackageReference Include="System.IO.Hashing" Version="10.0.5" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="10.0.5" />
|
<PackageReference Include="System.IO.Ports" Version="10.0.5" />
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Elwig.Models.Entities;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.IO;
|
|
||||||
using System;
|
|
||||||
using System.Windows;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Elwig.Models.Dtos;
|
using Elwig.Models.Dtos;
|
||||||
|
using Elwig.Models.Entities;
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using ScottPlot.TickGenerators.Financial;
|
||||||
|
using ScottPlot.TickGenerators.TimeUnits;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media.Converters;
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
namespace Elwig.Helpers {
|
||||||
|
|
||||||
@@ -48,6 +51,7 @@ namespace Elwig.Helpers {
|
|||||||
public DbSet<MemberTelNr> MemberTelephoneNrs { get; private set; }
|
public DbSet<MemberTelNr> MemberTelephoneNrs { get; private set; }
|
||||||
public DbSet<MemberEmailAddr> MemberEmailAddrs { get; private set; }
|
public DbSet<MemberEmailAddr> MemberEmailAddrs { get; private set; }
|
||||||
public DbSet<MemberHistory> MemberHistory { get; private set; }
|
public DbSet<MemberHistory> MemberHistory { get; private set; }
|
||||||
|
public DbSet<AreaComContract> AreaCommitmentContracts { get; private set; }
|
||||||
public DbSet<AreaCom> AreaCommitments { get; private set; }
|
public DbSet<AreaCom> AreaCommitments { get; private set; }
|
||||||
public DbSet<Season> Seasons { get; private set; }
|
public DbSet<Season> Seasons { get; private set; }
|
||||||
public DbSet<DeliverySchedule> DeliverySchedules { get; private set; }
|
public DbSet<DeliverySchedule> DeliverySchedules { get; private set; }
|
||||||
@@ -81,6 +85,70 @@ namespace Elwig.Helpers {
|
|||||||
public static string? ConnectionStringOverride { get; set; } = null;
|
public static string? ConnectionStringOverride { get; set; } = null;
|
||||||
public static string ConnectionString => ConnectionStringOverride ?? $"Data Source=\"{App.Config.DatabaseFile}\"; Mode=ReadWrite; Foreign Keys=True; Cache=Default; Pooling=False";
|
public static string ConnectionString => ConnectionStringOverride ?? $"Data Source=\"{App.Config.DatabaseFile}\"; Mode=ReadWrite; Foreign Keys=True; Cache=Default; Pooling=False";
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, string?, bool, IAsyncEnumerable<Branch>> _compiledQueryBranches =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, string?, bool, Branch>((ctx, zwstid, includeWithoutMembers) => ctx.Branches
|
||||||
|
.Where(b => includeWithoutMembers || b.Members.Count > 0)
|
||||||
|
.Where(b => zwstid == null || b.ZwstId == zwstid)
|
||||||
|
.Include(b => b.PostalDest)
|
||||||
|
.OrderBy(b => b.Name));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, string?, IAsyncEnumerable<WineVar>> _compiledQueryWineVarieties =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, string?, WineVar>((ctx, sortid) => ctx.WineVarieties
|
||||||
|
.Where(v => sortid == null || v.SortId == sortid)
|
||||||
|
.OrderBy(v => v.Name));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, string?, bool, IAsyncEnumerable<WineAttr>> _compiledQueryWineAttributes =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, string?, bool, WineAttr>((ctx, attrid, includeNotActive) => ctx.WineAttributes
|
||||||
|
.Where(a => includeNotActive || a.IsActive)
|
||||||
|
.Where(a => attrid == null || a.AttrId == attrid)
|
||||||
|
.OrderBy(a => a.Name));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, string?, IAsyncEnumerable<WineCult>> _compiledQueryWineCultivations =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, string?, WineCult>((ctx, cultid) => ctx.WineCultivations
|
||||||
|
.Where(c => cultid == null || c.CultId == cultid)
|
||||||
|
.OrderBy(v => v.Name));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, bool, IAsyncEnumerable<WineQualLevel>> _compiledQueryWineQualityLevels =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, bool, WineQualLevel>((ctx, includePredicate) => ctx.WineQualityLevels
|
||||||
|
.Where(l => includePredicate || !l.IsPredicate)
|
||||||
|
.OrderBy(l => l.MinKmw));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, int?, bool, IAsyncEnumerable<Modifier>> _compiledQueryModifiers =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, int?, bool, Modifier>((ctx, year, incudeNotActive) => ctx.Modifiers
|
||||||
|
.Where(m => (year == null || m.Year == year) && (incudeNotActive || m.IsActive))
|
||||||
|
.OrderBy(m => m.Year).ThenBy(m => m.Ordering).ThenBy(m => m.Name));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, int?, bool, IAsyncEnumerable<Member>> _compiledQueryMembers =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, int?, bool, Member>((ctx, mgnr, includeNotActive) => ctx.Members
|
||||||
|
.Where(m => includeNotActive || m.IsActive)
|
||||||
|
.Where(m => mgnr == null || m.MgNr == mgnr)
|
||||||
|
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, int?, bool, IAsyncEnumerable<Member>> _compiledQueryMembersContactInfo =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, int?, bool, Member>((ctx, mgnr, includeNotActive) => ctx.Members
|
||||||
|
.Where(m => includeNotActive || m.IsActive)
|
||||||
|
.Where(m => mgnr == null || m.MgNr == mgnr)
|
||||||
|
.Include(m => m.EmailAddresses)
|
||||||
|
.Include(m => m.TelephoneNumbers)
|
||||||
|
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr)
|
||||||
|
.AsSplitQuery());
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<AreaCom>> _compiledQueryAreaCommitments =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, int?, AreaCom>((ctx, fbnr) => ctx.AreaCommitments
|
||||||
|
.Where(c => fbnr == null || c.FbNr == fbnr)
|
||||||
|
.OrderBy(c => c.FbNr).ThenBy(c => c.RevNr));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<Season>> _compiledQuerySeasons =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, int?, Season>((ctx, year) => ctx.Seasons
|
||||||
|
.Where(s => year == null || s.Year == year)
|
||||||
|
.OrderByDescending(s => s.Year));
|
||||||
|
|
||||||
|
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<Season>> _compiledQuerySeasonsModifiers =
|
||||||
|
EF.CompileAsyncQuery<AppDbContext, int?, Season>((ctx, year) => ctx.Seasons
|
||||||
|
.Where(s => year == null || s.Year == year)
|
||||||
|
.Include(s => s.Modifiers)
|
||||||
|
.OrderByDescending(s => s.Year));
|
||||||
|
|
||||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = [];
|
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = [];
|
||||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = [];
|
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = [];
|
||||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = [];
|
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = [];
|
||||||
@@ -118,11 +186,55 @@ namespace Elwig.Helpers {
|
|||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
|
||||||
optionsBuilder.UseSqlite(ConnectionString);
|
optionsBuilder.UseSqlite(ConnectionString);
|
||||||
optionsBuilder.UseLazyLoadingProxies();
|
|
||||||
optionsBuilder.LogTo(Log, LogLevel.Information);
|
optionsBuilder.LogTo(Log, LogLevel.Information);
|
||||||
base.OnConfiguring(optionsBuilder);
|
base.OnConfiguring(optionsBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
||||||
|
modelBuilder.Entity<WbKg>().Navigation(k => k.AtKg).AutoInclude();
|
||||||
|
modelBuilder.Entity<WbKg>().Navigation(k => k.Gl).AutoInclude();
|
||||||
|
modelBuilder.Entity<AT_Kg>().Navigation(k => k.Gem).AutoInclude();
|
||||||
|
modelBuilder.Entity<PostalDest>().Navigation(p => p.Country).AutoInclude();
|
||||||
|
modelBuilder.Entity<PostalDest>().Navigation(p => p.AtPlz).AutoInclude();
|
||||||
|
modelBuilder.Entity<AT_PlzDest>().Navigation(p => p.AtPlz).AutoInclude();
|
||||||
|
modelBuilder.Entity<AT_PlzDest>().Navigation(p => p.Ort).AutoInclude();
|
||||||
|
modelBuilder.Entity<Member>().Navigation(m => m.DefaultWbKg).AutoInclude();
|
||||||
|
modelBuilder.Entity<Member>().Navigation(m => m.Country).AutoInclude();
|
||||||
|
modelBuilder.Entity<Member>().Navigation(m => m.PostalDest).AutoInclude();
|
||||||
|
modelBuilder.Entity<Member>().Navigation(m => m.BillingAddress).AutoInclude();
|
||||||
|
modelBuilder.Entity<BillingAddr>().Navigation(a => a.Country).AutoInclude();
|
||||||
|
modelBuilder.Entity<BillingAddr>().Navigation(a => a.PostalDest).AutoInclude();
|
||||||
|
modelBuilder.Entity<Modifier>().Navigation(m => m.Season).AutoInclude();
|
||||||
|
modelBuilder.Entity<Season>().Navigation(s => s.Currency).AutoInclude();
|
||||||
|
modelBuilder.Entity<PaymentVar>().Navigation(v => v.Season).AutoInclude();
|
||||||
|
modelBuilder.Entity<PaymentDeliveryPart>().Navigation(p => p.Variant).AutoInclude();
|
||||||
|
modelBuilder.Entity<Credit>().Navigation(c => c.Payment).AutoInclude();
|
||||||
|
modelBuilder.Entity<Delivery>().Navigation(d => d.Member).AutoInclude();
|
||||||
|
modelBuilder.Entity<Delivery>().Navigation(d => d.Season).AutoInclude();
|
||||||
|
modelBuilder.Entity<Delivery>().Navigation(d => d.Branch).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Quality).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Variety).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Attribute).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Cultivation).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Kg).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Rd).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryPartModifier>().Navigation(m => m.Modifier).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Kg).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Rd).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaCom>().Navigation(c => c.Contract).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaCom>().Navigation(c => c.WineCult).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaCom>().Navigation(c => c.AreaComType).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineVar).AutoInclude();
|
||||||
|
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineAttr).AutoInclude();
|
||||||
|
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Credit).AutoInclude();
|
||||||
|
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Member).AutoInclude();
|
||||||
|
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Variant).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Member).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Schedule).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Variety).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliverySchedule>().Navigation(s => s.Branch).AutoInclude();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Dispose() {
|
public override void Dispose() {
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
LogFile?.Dispose();
|
LogFile?.Dispose();
|
||||||
@@ -138,23 +250,23 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> MgNrExists(int mgnr) {
|
public async Task<bool> MgNrExists(int mgnr) {
|
||||||
return await Members.FindAsync(mgnr) != null;
|
return await _compiledQueryMembers.Invoke(this, mgnr, true).AnyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> FbNrExists(int fbnr) {
|
public async Task<bool> FbNrExists(int fbnr) {
|
||||||
return await AreaCommitments.FindAsync(fbnr) != null;
|
return await _compiledQueryAreaCommitments.Invoke(this, fbnr).AnyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> SortIdExists(string sortId) {
|
public async Task<bool> SortIdExists(string sortId) {
|
||||||
return await WineVarieties.FindAsync(sortId) != null;
|
return await _compiledQueryWineVarieties.Invoke(this, sortId).AnyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> AttrIdExists(string attrId) {
|
public async Task<bool> AttrIdExists(string attrId) {
|
||||||
return await WineAttributes.FindAsync(attrId) != null;
|
return await _compiledQueryWineAttributes.Invoke(this, attrId, true).AnyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> CultIdExists(string cultId) {
|
public async Task<bool> CultIdExists(string cultId) {
|
||||||
return await WineCultivations.FindAsync(cultId) != null;
|
return await _compiledQueryWineCultivations.Invoke(this, cultId).AnyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> NextMgNr() {
|
public async Task<int> NextMgNr() {
|
||||||
@@ -166,87 +278,113 @@ namespace Elwig.Helpers {
|
|||||||
|
|
||||||
public async Task<int> NextFbNr() {
|
public async Task<int> NextFbNr() {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
(await AreaCommitments.OrderBy(ac => ac.FbNr).Select(ac => ac.FbNr).ToListAsync())
|
(await AreaCommitmentContracts.OrderBy(ac => ac.FbNr).Select(ac => ac.FbNr).ToListAsync())
|
||||||
.ForEach(a => { if (a <= c + 10000) c = a; });
|
.ForEach(a => { if (a <= c + 10000) c = a; });
|
||||||
return c + 1;
|
return c + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> NextRevNr(int fbnr) {
|
||||||
|
return (await AreaCommitments.Where(c => c.FbNr == fbnr).Select(c => (int?)c.RevNr).MaxAsync() ?? 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<int> NextLNr(DateOnly date, string zwstid) {
|
public async Task<int> NextLNr(DateOnly date, string zwstid) {
|
||||||
var dateStr = date.ToString("yyyy-MM-dd");
|
var dateStr = date.ToString("yyyy-MM-dd");
|
||||||
int c = 0;
|
return (await Deliveries.Where(d => d.DateString == dateStr && d.ZwstId == zwstid).Select(d => (int?)d.LNr).MaxAsync() ?? 0) + 1;
|
||||||
(await Deliveries.Where(d => d.DateString == dateStr && d.ZwstId == zwstid).Select(d => d.LNr).ToListAsync())
|
|
||||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
|
||||||
return c + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> NextDId(int year) {
|
public async Task<int> NextDId(int year) {
|
||||||
int c = 0;
|
return (await Deliveries.Where(d => d.Year == year).Select(d => (int?)d.DId).MaxAsync() ?? 0) + 1;
|
||||||
(await Deliveries.Where(d => d.Year == year).Select(d => d.DId).ToListAsync())
|
|
||||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
|
||||||
return c + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> NextDPNr(int year, int did) {
|
public async Task<int> NextDPNr(int year, int did) {
|
||||||
int c = 0;
|
return (await DeliveryParts.Where(p => p.Year == year && p.DId == did).Select(p => (int?)p.DPNr).MaxAsync() ?? 0) + 1;
|
||||||
(await DeliveryParts.Where(p => p.Year == year && p.DId == did).Select(d => d.DPNr).ToListAsync())
|
|
||||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
|
||||||
return c + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> NextRdNr(int kgnr) {
|
public async Task<int> NextRdNr(int kgnr) {
|
||||||
int c = 0;
|
return (await WbRde.Where(r => r.KgNr == kgnr).Select(r => (int?)r.RdNr).MaxAsync() ?? 0) + 1;
|
||||||
(await WbRde.Where(r => r.KgNr == kgnr).Select(r => r.RdNr).ToListAsync())
|
|
||||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
|
||||||
return c + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> NextAvNr(int year) {
|
public async Task<int> NextAvNr(int year) {
|
||||||
int c = 0;
|
return (await PaymentVariants.Where(v => v.Year == year).Select(v => (int?)v.AvNr).MaxAsync() ?? 0) + 1;
|
||||||
(await PaymentVariants.Where(v => v.Year == year).Select(v => v.AvNr).ToListAsync())
|
|
||||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
|
||||||
return c + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> NextDsNr(int year) {
|
public async Task<int> NextDsNr(int year) {
|
||||||
int c = 0;
|
return (await DeliverySchedules.Where(s => s.Year == year).Select(v => (int?)v.DsNr).MaxAsync() ?? 0) + 1;
|
||||||
(await DeliverySchedules.Where(s => s.Year == year).Select(s => s.DsNr).ToListAsync())
|
|
||||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
|
||||||
return c + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDeliveryPartModifiers(DeliveryPart part, IEnumerable<Modifier> oldModifiers, IEnumerable<Modifier> newModifiers) {
|
public IAsyncEnumerable<Branch> FetchBranches(string? zwstid = null, bool includeWithoutMembers = true) {
|
||||||
foreach (var m in Modifiers.Where(m => m.Year == part.Year)) {
|
return _compiledQueryBranches.Invoke(this, zwstid, includeWithoutMembers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<WineVar> FetchWineVarieties() {
|
||||||
|
return _compiledQueryWineVarieties.Invoke(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<WineAttr> FetchWineAttributes(bool incudeNotActive = true) {
|
||||||
|
return _compiledQueryWineAttributes.Invoke(this, null, incudeNotActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<WineCult> FetchWineCultivations() {
|
||||||
|
return _compiledQueryWineCultivations.Invoke(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<WineQualLevel> FetchWineQualityLevels(bool includePredicate = true) {
|
||||||
|
return _compiledQueryWineQualityLevels.Invoke(this, includePredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<Modifier> FetchModifiers(int? year, bool incudeNotActive = true) {
|
||||||
|
return _compiledQueryModifiers.Invoke(this, year, incudeNotActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<Member> FetchMembers(int? mgnr = null, bool includeNotActive = false, bool includeContactInfo = false) {
|
||||||
|
if (includeContactInfo) {
|
||||||
|
return _compiledQueryMembersContactInfo.Invoke(this, mgnr, includeNotActive);
|
||||||
|
} else {
|
||||||
|
return _compiledQueryMembers.Invoke(this, mgnr, includeNotActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncEnumerable<Season> FetchSeasons(int? year = null, bool includeModifiers = false) {
|
||||||
|
if (includeModifiers) {
|
||||||
|
return _compiledQuerySeasonsModifiers.Invoke(this, year);
|
||||||
|
} else {
|
||||||
|
return _compiledQuerySeasons.Invoke(this, year);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateDeliveryPartModifiers(DeliveryPart part, IEnumerable<string> oldModIds, IEnumerable<string> newModIds) {
|
||||||
|
foreach (var m in await FetchModifiers(part.Year).ToListAsync()) {
|
||||||
var mod = new DeliveryPartModifier {
|
var mod = new DeliveryPartModifier {
|
||||||
Year = part.Year,
|
Year = part.Year,
|
||||||
DId = part.DId,
|
DId = part.DId,
|
||||||
DPNr = part.DPNr,
|
DPNr = part.DPNr,
|
||||||
ModId = m.ModId,
|
ModId = m.ModId,
|
||||||
};
|
};
|
||||||
var old = oldModifiers.Where(pa => pa.ModId == m.ModId).FirstOrDefault();
|
var old = oldModIds.Contains(m.ModId);
|
||||||
if (newModifiers.Any(md => md.ModId == m.ModId)) {
|
if (newModIds.Contains(m.ModId)) {
|
||||||
if (old == null) {
|
if (!old) {
|
||||||
Add(mod);
|
Add(mod);
|
||||||
} else {
|
} else {
|
||||||
Update(mod);
|
Update(mod);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (old != null) {
|
if (old) {
|
||||||
Remove(mod);
|
Remove(mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDeliveryScheduleWineVarieties(DeliverySchedule schedule, IEnumerable<(WineVar, int)> oldVarieties, IEnumerable<(WineVar, int)> newVarieties) {
|
public async Task UpdateDeliveryScheduleWineVarieties(DeliverySchedule schedule, IEnumerable<(string, int)> oldVarieties, IEnumerable<(string, int)> newVarieties) {
|
||||||
foreach (var v in WineVarieties) {
|
foreach (var v in await FetchWineVarieties().ToArrayAsync()) {
|
||||||
var e = new DeliveryScheduleWineVar {
|
var e = new DeliveryScheduleWineVar {
|
||||||
Year = schedule.Year,
|
Year = schedule.Year,
|
||||||
DsNr = schedule.DsNr,
|
DsNr = schedule.DsNr,
|
||||||
SortId = v.SortId,
|
SortId = v.SortId,
|
||||||
Priority = 1,
|
Priority = 1,
|
||||||
};
|
};
|
||||||
var o = oldVarieties.Where(x => x.Item1.SortId == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
var o = oldVarieties.Where(x => x.Item1 == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
||||||
var n = newVarieties.Where(x => x.Item1.SortId == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
var n = newVarieties.Where(x => x.Item1 == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
||||||
if (n != -1) {
|
if (n != -1) {
|
||||||
e.Priority = n;
|
e.Priority = n;
|
||||||
if (o == -1) {
|
if (o == -1) {
|
||||||
@@ -391,10 +529,12 @@ namespace Elwig.Helpers {
|
|||||||
var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
|
var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
|
||||||
if (ownCnx) await cnx.DisposeAsync();
|
if (ownCnx) await cnx.DisposeAsync();
|
||||||
|
|
||||||
|
var varieties = await WineVarieties.ToDictionaryAsync(v => v.SortId);
|
||||||
|
var attributes = await WineAttributes.ToDictionaryAsync(a => a.AttrId);
|
||||||
var buckets = new Dictionary<string, MemberBucket>();
|
var buckets = new Dictionary<string, MemberBucket>();
|
||||||
foreach (var id in rightsAndObligations.Keys.Union(deliveryBuckets.Keys).Union(paymentBuckets.Keys)) {
|
foreach (var id in rightsAndObligations.Keys.Union(deliveryBuckets.Keys).Union(paymentBuckets.Keys)) {
|
||||||
var variety = await WineVarieties.FindAsync(id[..2]);
|
var variety = varieties.GetValueOrDefault(id[..2]);
|
||||||
var attribute = await WineAttributes.FindAsync(id[2..]);
|
var attribute = attributes.GetValueOrDefault(id[2..]);
|
||||||
var name = (variety?.Name ?? "") + (id[2..] == "_" ? " (kein Qual.Wein)" : attribute != null ? $" ({attribute})" : "");
|
var name = (variety?.Name ?? "") + (id[2..] == "_" ? " (kein Qual.Wein)" : attribute != null ? $" ({attribute})" : "");
|
||||||
buckets[id] = new(
|
buckets[id] = new(
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Elwig.Helpers {
|
|||||||
public static class AppDbUpdater {
|
public static class AppDbUpdater {
|
||||||
|
|
||||||
// Don't forget to update value in Tests/fetch-resources.bat!
|
// Don't forget to update value in Tests/fetch-resources.bat!
|
||||||
public static readonly int RequiredSchemaVersion = 37;
|
public static readonly int RequiredSchemaVersion = 38;
|
||||||
|
|
||||||
private static int VersionOffset = 0;
|
private static int VersionOffset = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -16,13 +15,30 @@ namespace Elwig.Helpers.Billing {
|
|||||||
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
||||||
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
||||||
|
|
||||||
public Billing(int year) {
|
protected Billing(int year, Season season,
|
||||||
|
Dictionary<string, string> attributes,
|
||||||
|
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||||
|
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes
|
||||||
|
) {
|
||||||
Year = year;
|
Year = year;
|
||||||
|
Season = season;
|
||||||
|
Attributes = attributes;
|
||||||
|
Modifiers = modifiers;
|
||||||
|
AreaComTypes = areaComTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static async Task<(Season, Dictionary<string, string>, Dictionary<string, (decimal?, decimal?)>, Dictionary<string, (string, string?, string?, int?, decimal?)>)> LoadData(AppDbContext ctx, int year) {
|
||||||
|
var season = await ctx.FetchSeasons(year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||||
|
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a.Name);
|
||||||
|
var modifiers = await ctx.FetchModifiers(year).ToDictionaryAsync(m => m.ModId, m => (m.Abs, m.Rel));
|
||||||
|
var areaComTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||||
|
return (season, attributes, modifiers, areaComTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<Billing> Create(int year) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
Season = ctx.Seasons.Find(Year)!;
|
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
||||||
Attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a.Name);
|
return new Billing(year, season, attributes, modifiers, areaComTypes);
|
||||||
Modifiers = ctx.Modifiers.Where(m => m.Year == Year).Include(m => m.Season).ToDictionary(m => m.ModId, m => (m.Abs, m.Rel));
|
|
||||||
AreaComTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task FinishSeason() {
|
public async Task FinishSeason() {
|
||||||
|
|||||||
@@ -10,17 +10,35 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public class BillingVariant : Billing {
|
public class BillingVariant : Billing {
|
||||||
|
|
||||||
protected readonly int AvNr;
|
protected readonly int AvNr;
|
||||||
protected readonly PaymentVar PaymentVariant;
|
protected PaymentVar PaymentVariant;
|
||||||
protected readonly PaymentBillingData Data;
|
protected PaymentBillingData Data;
|
||||||
|
|
||||||
public BillingVariant(int year, int avnr) : base(year) {
|
protected BillingVariant(int year, int avnr, Season season,
|
||||||
|
Dictionary<string, string> attributes,
|
||||||
|
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||||
|
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes,
|
||||||
|
PaymentVar paymentVar, PaymentBillingData data) :
|
||||||
|
base(year, season, attributes, modifiers, areaComTypes) {
|
||||||
AvNr = avnr;
|
AvNr = avnr;
|
||||||
|
PaymentVariant = paymentVar;
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static async Task<(PaymentVar, PaymentBillingData)> LoadData(AppDbContext ctx, int year, int avnr) {
|
||||||
|
var paymentVar = await ctx.PaymentVariants.Where(v => v.Year == year && v.AvNr == avnr).SingleAsync();
|
||||||
|
var data = PaymentBillingData.FromJson(paymentVar.Data, await Utils.GetVaributes(ctx, year, onlyDelivered: false));
|
||||||
|
return (paymentVar, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<BillingVariant> Create(int year, int avnr) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
PaymentVariant = ctx.PaymentVariants.Include(v => v.Season).Where(v => v.Year == Year && v.AvNr == AvNr).Single() ?? throw new ArgumentException("PaymentVar not found");
|
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
||||||
Data = PaymentBillingData.FromJson(PaymentVariant.Data, Utils.GetVaributes(ctx, Year, onlyDelivered: false));
|
var (paymentVar, data) = await LoadData(ctx, year, avnr);
|
||||||
|
return new BillingVariant(year, avnr, season, attributes, modifiers, areaComTypes, paymentVar, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Calculate(bool strictPrices = true, bool? honorGebunden = null, bool? allowAttrsIntoLower = null, bool? avoidUnderDeliveries = null) {
|
public async Task Calculate(bool strictPrices = true, bool? honorGebunden = null, bool? allowAttrsIntoLower = null, bool? avoidUnderDeliveries = null) {
|
||||||
|
if (PaymentVariant == null || Data == null) throw new Exception("Call Load before Calculate");
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
using var tx = await cnx.BeginTransactionAsync();
|
using var tx = await cnx.BeginTransactionAsync();
|
||||||
await CalculateBuckets(honorGebunden, allowAttrsIntoLower, avoidUnderDeliveries, cnx);
|
await CalculateBuckets(honorGebunden, allowAttrsIntoLower, avoidUnderDeliveries, cnx);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Billing {
|
namespace Elwig.Helpers.Billing {
|
||||||
public class EditBillingData : BillingData {
|
public class EditBillingData : BillingData {
|
||||||
@@ -70,14 +71,14 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return (curves, dict3);
|
return (curves, dict3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<GraphEntry> CreateGraphEntries(
|
private static async Task<List<GraphEntry>> CreateGraphEntries(
|
||||||
AppDbContext ctx, int precision,
|
AppDbContext ctx, int precision,
|
||||||
Dictionary<int, Curve> curves,
|
Dictionary<int, Curve> curves,
|
||||||
Dictionary<int, List<RawVaribute>> entries
|
Dictionary<int, List<RawVaribute>> entries
|
||||||
) {
|
) {
|
||||||
var vars = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
var vars = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var attrs = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
var attrs = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||||
var cults = ctx.WineCultivations.ToDictionary(c => c.CultId, c => c);
|
var cults = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.CultId, c => c);
|
||||||
return entries
|
return entries
|
||||||
.Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value
|
.Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value
|
||||||
.Select(s => new Varibute(s, vars, attrs, cults))
|
.Select(s => new Varibute(s, vars, attrs, cults))
|
||||||
@@ -85,18 +86,18 @@ namespace Elwig.Helpers.Billing {
|
|||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<GraphEntry> GetPaymentGraphEntries(AppDbContext ctx, Season season) {
|
public async Task<IEnumerable<GraphEntry>> GetPaymentGraphEntries(AppDbContext ctx, Season season) {
|
||||||
var root = GetPaymentEntry();
|
var root = GetPaymentEntry();
|
||||||
var (curves, entries) = GetGraphEntries(root);
|
var (curves, entries) = GetGraphEntries(root);
|
||||||
return CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Vaributes.Count > 0);
|
return (await CreateGraphEntries(ctx, season.Precision, curves, entries)).Where(e => e.Vaributes.Count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<GraphEntry> GetQualityGraphEntries(AppDbContext ctx, Season season, int idOffset = 0) {
|
public async Task<IEnumerable<GraphEntry>> GetQualityGraphEntries(AppDbContext ctx, Season season, int idOffset = 0) {
|
||||||
var root = GetQualityEntry();
|
var root = GetQualityEntry();
|
||||||
if (root == null || root["WEI"] is not JsonNode qualityWei)
|
if (root == null || root["WEI"] is not JsonNode qualityWei)
|
||||||
return [];
|
return [];
|
||||||
var (curves, entries) = GetGraphEntries(qualityWei);
|
var (curves, entries) = GetGraphEntries(qualityWei);
|
||||||
var list = CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Vaributes.Count > 0);
|
var list = (await CreateGraphEntries(ctx, season.Precision, curves, entries)).Where(e => e.Vaributes.Count > 0);
|
||||||
foreach (var e in list) {
|
foreach (var e in list) {
|
||||||
e.Id += idOffset;
|
e.Id += idOffset;
|
||||||
e.Abgewertet = true;
|
e.Abgewertet = true;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
List<WbGl> currentWbGls;
|
List<WbGl> currentWbGls;
|
||||||
|
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
branches = await ctx.Branches.ToDictionaryAsync(b => b.ZwstId);
|
branches = await ctx.FetchBranches().ToDictionaryAsync(b => b.ZwstId);
|
||||||
currentDids = await ctx.Deliveries
|
currentDids = await ctx.Deliveries
|
||||||
.GroupBy(d => d.Year)
|
.GroupBy(d => d.Year)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.Max(d => d.DId));
|
.ToDictionaryAsync(g => g.Key, g => g.Max(d => d.DId));
|
||||||
@@ -60,13 +60,14 @@ namespace Elwig.Helpers.Export {
|
|||||||
List<MemberTelNr> TelephoneNumbers,
|
List<MemberTelNr> TelephoneNumbers,
|
||||||
List<MemberEmailAddr> EmailAddresses,
|
List<MemberEmailAddr> EmailAddresses,
|
||||||
List<AreaCom> AreaCommitments,
|
List<AreaCom> AreaCommitments,
|
||||||
|
List<AreaComContract> Contracts,
|
||||||
List<WbRd> Riede,
|
List<WbRd> Riede,
|
||||||
List<WbKg> WbKgs,
|
List<WbKg> WbKgs,
|
||||||
List<WbGl> WbGls,
|
List<WbGl> WbGls,
|
||||||
List<Delivery> Deliveries,
|
List<Delivery> Deliveries,
|
||||||
List<DeliveryPart> DeliveryParts,
|
List<DeliveryPart> DeliveryParts,
|
||||||
List<DeliveryPartModifier> Modifiers,
|
List<DeliveryPartModifier> Modifiers,
|
||||||
Dictionary<string, List<(int Id1, int Id2, DateTime CreatedAt, DateTime ModifiedAt)>> Timestamps)>();
|
Dictionary<string, List<(int Id1, int Id2, int Id3, DateTime CreatedAt, DateTime ModifiedAt)>> Timestamps)>();
|
||||||
|
|
||||||
var metaData = new List<(string FileName, string ZwstId, string Device,
|
var metaData = new List<(string FileName, string ZwstId, string Device,
|
||||||
int? MemberNum, string? MemberFilters,
|
int? MemberNum, string? MemberFilters,
|
||||||
@@ -75,10 +76,12 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
foreach (var filename in filenames) {
|
foreach (var filename in filenames) {
|
||||||
try {
|
try {
|
||||||
data.Add(new([], [], [], [], [], [], [], new([], [], [], [], new() {
|
data.Add(new([], [], [], [], [], [], [], new([], [], [], [], [], new() {
|
||||||
["member"] = [],
|
["member"] = [],
|
||||||
|
["area_commitment_contract"] = [],
|
||||||
["area_commitment"] = [],
|
["area_commitment"] = [],
|
||||||
["delivery"] = [],
|
["delivery"] = [],
|
||||||
|
["delivery_part"] = [],
|
||||||
})));
|
})));
|
||||||
var r = data[^1];
|
var r = data[^1];
|
||||||
|
|
||||||
@@ -86,9 +89,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
|
using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
|
||||||
await zip.CheckIntegrity();
|
await zip.CheckIntegrity();
|
||||||
|
|
||||||
|
string[] acceptableVersions = ["1", "2"];
|
||||||
var version = zip.GetEntry("version");
|
var version = zip.GetEntry("version");
|
||||||
using (var reader = new StreamReader(version!.Open(), Utils.UTF8)) {
|
using (var reader = new StreamReader(version!.Open(), Utils.UTF8)) {
|
||||||
if (await reader.ReadToEndAsync() != "elwig:1")
|
var v = await reader.ReadToEndAsync();
|
||||||
|
if (!v.StartsWith("elwig:") || !acceptableVersions.Contains(v[6..]))
|
||||||
throw new FileFormatException($"Ungültige Elwig-Export-Datei ({filename})");
|
throw new FileFormatException($"Ungültige Elwig-Export-Datei ({filename})");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,8 +101,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
var meta = await JsonNode.ParseAsync(metaJson!.Open());
|
var meta = await JsonNode.ParseAsync(metaJson!.Open());
|
||||||
var memberCount = meta!["members"]?["count"]?.AsValue().GetValue<int>();
|
var memberCount = meta!["members"]?["count"]?.AsValue().GetValue<int>();
|
||||||
var memberFilters = meta!["members"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
var memberFilters = meta!["members"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||||
var areaComCount = meta!["area_commitments"]?["count"]?.AsValue().GetValue<int>();
|
var areaComCount = meta!["area_commitment_contracts"]?["count"]?.AsValue().GetValue<int>();
|
||||||
var areaComFilters = meta!["area_commitments"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
var areaComFilters = meta!["area_commitment_contracts"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||||
var deliveryCount = meta!["deliveries"]?["count"]?.AsValue().GetValue<int>();
|
var deliveryCount = meta!["deliveries"]?["count"]?.AsValue().GetValue<int>();
|
||||||
var deliveryFilters = meta!["deliveries"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
var deliveryFilters = meta!["deliveries"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||||
metaData.Add((Path.GetFileName(filename),
|
metaData.Add((Path.GetFileName(filename),
|
||||||
@@ -133,23 +138,48 @@ namespace Elwig.Helpers.Export {
|
|||||||
r.TelephoneNumbers.AddRange(telNrs);
|
r.TelephoneNumbers.AddRange(telNrs);
|
||||||
r.EmailAddresses.AddRange(emailAddrs);
|
r.EmailAddresses.AddRange(emailAddrs);
|
||||||
if (timestamps.HasValue)
|
if (timestamps.HasValue)
|
||||||
r.Timestamps["member"].Add((m.MgNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
r.Timestamps["member"].Add((m.MgNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy area commitments
|
||||||
var areaComsJson = zip.GetEntry("area_commitments.json");
|
var areaComsJson = zip.GetEntry("area_commitments.json");
|
||||||
if (areaComsJson != null) {
|
if (areaComsJson != null) {
|
||||||
using var reader = new StreamReader(areaComsJson.Open(), Utils.UTF8);
|
using var reader = new StreamReader(areaComsJson.Open(), Utils.UTF8);
|
||||||
string? line;
|
string? line;
|
||||||
while ((line = await reader.ReadLineAsync()) != null) {
|
while ((line = await reader.ReadLineAsync()) != null) {
|
||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (areaCom, wbrd, timestamps) = obj.ToAreaCom(currentWbRde);
|
var (contract, areaCom, wbrd, timestamps) = obj.ToAreaCom(currentWbRde);
|
||||||
|
r.Contracts.Add(contract);
|
||||||
r.AreaCommitments.Add(areaCom);
|
r.AreaCommitments.Add(areaCom);
|
||||||
if (wbrd != null) {
|
if (wbrd != null) {
|
||||||
r.Riede.Add(wbrd);
|
r.Riede.Add(wbrd);
|
||||||
}
|
}
|
||||||
|
if (timestamps.HasValue) {
|
||||||
|
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
|
r.Timestamps["area_commitment"].Add((areaCom.FbNr, areaCom.RevNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var contractsJson = zip.GetEntry("area_commitment_contracts.json");
|
||||||
|
if (contractsJson != null) {
|
||||||
|
using var reader = new StreamReader(contractsJson.Open(), Utils.UTF8);
|
||||||
|
string? line;
|
||||||
|
while ((line = await reader.ReadLineAsync()) != null) {
|
||||||
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
|
var (contract, areaComs, wbrd, timestamps) = obj.ToAreaComContract(currentWbRde);
|
||||||
|
r.Contracts.Add(contract);
|
||||||
|
r.AreaCommitments.AddRange(areaComs.Select(v => v.Item1));
|
||||||
|
if (wbrd != null) {
|
||||||
|
r.Riede.Add(wbrd);
|
||||||
|
}
|
||||||
if (timestamps.HasValue)
|
if (timestamps.HasValue)
|
||||||
r.Timestamps["area_commitment"].Add((areaCom.FbNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
|
foreach (var (areaCom, ts) in areaComs) {
|
||||||
|
if (!ts.HasValue) continue;
|
||||||
|
r.Timestamps["area_commitment"].Add((areaCom.FbNr, areaCom.RevNr, 0, ts.Value.CreatedAt, ts.Value.ModifiedAt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,11 +191,15 @@ namespace Elwig.Helpers.Export {
|
|||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (d, parts, mods, rde, timestamps) = obj.ToDelivery(currentLsNrs, currentDids, kgs, currentWbRde);
|
var (d, parts, mods, rde, timestamps) = obj.ToDelivery(currentLsNrs, currentDids, kgs, currentWbRde);
|
||||||
r.Deliveries.Add(d);
|
r.Deliveries.Add(d);
|
||||||
r.DeliveryParts.AddRange(parts);
|
r.DeliveryParts.AddRange(parts.Select(p => p.Item1));
|
||||||
r.Modifiers.AddRange(mods);
|
r.Modifiers.AddRange(mods);
|
||||||
r.Riede.AddRange(rde);
|
r.Riede.AddRange(rde);
|
||||||
if (timestamps.HasValue)
|
if (timestamps.HasValue)
|
||||||
r.Timestamps["delivery"].Add((d.Year, d.DId, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
r.Timestamps["delivery"].Add((d.Year, d.DId, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
|
foreach (var (part, ts) in parts) {
|
||||||
|
if (!ts.HasValue) continue;
|
||||||
|
r.Timestamps["area_commitment"].Add((part.Year, part.DId, part.DPNr, ts.Value.CreatedAt, ts.Value.ModifiedAt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception exc) when (
|
} catch (Exception exc) when (
|
||||||
@@ -189,11 +223,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var importedMembers = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string Filters)>();
|
var importedMembers = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||||
var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int Imported, int NotImported, string Filters)>();
|
var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||||
var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string Filters)>();
|
var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||||
|
|
||||||
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, areaCommitments, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
|
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, areaCommitments, contracts, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
|
||||||
var branch = branches[meta.ZwstId];
|
var branch = branches[meta.ZwstId];
|
||||||
var device = meta.Device;
|
var device = meta.Device;
|
||||||
|
|
||||||
@@ -220,11 +254,20 @@ namespace Elwig.Helpers.Export {
|
|||||||
if (duplicateMgNrs.Count > 0)
|
if (duplicateMgNrs.Count > 0)
|
||||||
importDuplicateMembers = ImportQuestion(branch.Name, device, "Mitglieder", true, duplicateMgNrs.Count);
|
importDuplicateMembers = ImportQuestion(branch.Name, device, "Mitglieder", true, duplicateMgNrs.Count);
|
||||||
|
|
||||||
var fbnrs = areaCommitments.Select(c => c.FbNr).ToList();
|
var fbnrs = contracts.Select(c => c.FbNr).ToList();
|
||||||
var duplicateFbNrs = await ctx.AreaCommitments
|
var duplicateFbNrs = await ctx.AreaCommitmentContracts
|
||||||
.Where(c => fbnrs.Contains(c.FbNr))
|
.Where(c => fbnrs.Contains(c.FbNr))
|
||||||
.Select(c => c.FbNr)
|
.Select(c => c.FbNr)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
bool importNewContracts = false, importDuplicateContracts = false;
|
||||||
|
if (mode == ImportMode.Interactively) {
|
||||||
|
if (fbnrs.Count - duplicateFbNrs.Count > 0)
|
||||||
|
importNewContracts = ImportQuestion(branch.Name, device, "Flächenbindungsverträge", false, fbnrs.Count - duplicateFbNrs.Count);
|
||||||
|
} else {
|
||||||
|
importNewContracts = true;
|
||||||
|
}
|
||||||
|
if (duplicateFbNrs.Count > 0)
|
||||||
|
importDuplicateContracts = ImportQuestion(branch.Name, device, "Flächenbindungsverträge", true, duplicateFbNrs.Count);
|
||||||
|
|
||||||
var lsnrs = deliveries.Select(d => d.LsNr).ToList();
|
var lsnrs = deliveries.Select(d => d.LsNr).ToList();
|
||||||
var duplicateLsNrs = await ctx.Deliveries
|
var duplicateLsNrs = await ctx.Deliveries
|
||||||
@@ -258,40 +301,47 @@ namespace Elwig.Helpers.Export {
|
|||||||
importDuplicateDeliveries = ImportQuestion(branch.Name, device, "Lieferungen", true, duplicateLsNrs.Count);
|
importDuplicateDeliveries = ImportQuestion(branch.Name, device, "Lieferungen", true, duplicateLsNrs.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (importDuplicateMembers || importNewMembers || importDuplicateDeliveries || importNewDeliveries) {
|
if (importDuplicateMembers || importNewMembers || importDuplicateContracts || importNewContracts || importDuplicateDeliveries || importNewDeliveries) {
|
||||||
ctx.AddRange(wbGls);
|
ctx.AddRange(wbGls);
|
||||||
ctx.UpdateRange(wbKgs.Where(k => duplicateKgNrs.Contains(k.KgNr)));
|
ctx.UpdateRange(wbKgs.Where(k => duplicateKgNrs.Contains(k.KgNr)));
|
||||||
ctx.AddRange(wbKgs.Where(k => !duplicateKgNrs.Contains(k.KgNr)));
|
ctx.AddRange(wbKgs.Where(k => !duplicateKgNrs.Contains(k.KgNr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (importDuplicateMembers) {
|
if (importDuplicateMembers) {
|
||||||
ctx.RemoveRange(ctx.BillingAddresses.Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
ctx.RemoveRange(ctx.BillingAddresses.IgnoreAutoIncludes().Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
||||||
ctx.RemoveRange(ctx.MemberTelephoneNrs.Where(n => duplicateMgNrs.Contains(n.MgNr)));
|
ctx.RemoveRange(ctx.MemberTelephoneNrs.IgnoreAutoIncludes().Where(n => duplicateMgNrs.Contains(n.MgNr)));
|
||||||
ctx.RemoveRange(ctx.MemberEmailAddrs.Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
ctx.RemoveRange(ctx.MemberEmailAddrs.IgnoreAutoIncludes().Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
||||||
ctx.UpdateRange(members.Where(m => duplicateMgNrs.Contains(m.MgNr)));
|
ctx.UpdateRange(members.Where(m => duplicateMgNrs.Contains(m.MgNr)));
|
||||||
ctx.AddRange(billingAddresses.Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
ctx.AddRange(billingAddresses.Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
||||||
ctx.AddRange(telephoneNumbers.Where(n => duplicateMgNrs.Contains(n.MgNr)));
|
ctx.AddRange(telephoneNumbers.Where(n => duplicateMgNrs.Contains(n.MgNr)));
|
||||||
ctx.AddRange(emailAddresses.Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
ctx.AddRange(emailAddresses.Where(a => duplicateMgNrs.Contains(a.MgNr)));
|
||||||
ctx.UpdateRange(areaCommitments.Where(c => duplicateMgNrs.Contains(c.MgNr) && duplicateFbNrs.Contains(c.FbNr)));
|
|
||||||
ctx.AddRange(areaCommitments.Where(c => duplicateMgNrs.Contains(c.MgNr) && !duplicateFbNrs.Contains(c.FbNr)));
|
|
||||||
}
|
}
|
||||||
if (importNewMembers) {
|
if (importNewMembers) {
|
||||||
ctx.AddRange(members.Where(m => !duplicateMgNrs.Contains(m.MgNr)));
|
ctx.AddRange(members.Where(m => !duplicateMgNrs.Contains(m.MgNr)));
|
||||||
ctx.AddRange(billingAddresses.Where(a => !duplicateMgNrs.Contains(a.MgNr)));
|
ctx.AddRange(billingAddresses.Where(a => !duplicateMgNrs.Contains(a.MgNr)));
|
||||||
ctx.AddRange(telephoneNumbers.Where(n => !duplicateMgNrs.Contains(n.MgNr)));
|
ctx.AddRange(telephoneNumbers.Where(n => !duplicateMgNrs.Contains(n.MgNr)));
|
||||||
ctx.AddRange(emailAddresses.Where(a => !duplicateMgNrs.Contains(a.MgNr)));
|
ctx.AddRange(emailAddresses.Where(a => !duplicateMgNrs.Contains(a.MgNr)));
|
||||||
ctx.UpdateRange(areaCommitments.Where(c => !duplicateMgNrs.Contains(c.MgNr) && duplicateFbNrs.Contains(c.FbNr)));
|
|
||||||
ctx.AddRange(areaCommitments.Where(c => !duplicateMgNrs.Contains(c.MgNr) && !duplicateFbNrs.Contains(c.FbNr)));
|
|
||||||
}
|
}
|
||||||
if (members.Count > 0) {
|
if (members.Count > 0) {
|
||||||
var n = importNewMembers ? members.Count - duplicateMgNrs.Count : 0;
|
var n = importNewMembers ? members.Count - duplicateMgNrs.Count : 0;
|
||||||
var o = importDuplicateMembers ? duplicateMgNrs.Count : 0;
|
var o = importDuplicateMembers ? duplicateMgNrs.Count : 0;
|
||||||
importedMembers.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, members.Count - n - o, meta.MemberFilters));
|
importedMembers.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, members.Count - n - o, meta.MemberFilters));
|
||||||
}
|
}
|
||||||
if (areaCommitments.Count > 0) {
|
|
||||||
|
if (importDuplicateContracts) {
|
||||||
|
ctx.RemoveRange(ctx.AreaCommitments.IgnoreAutoIncludes().Where(c => duplicateFbNrs.Contains(c.FbNr)));
|
||||||
|
ctx.UpdateRange(contracts.Where(c => duplicateFbNrs.Contains(c.FbNr)));
|
||||||
|
ctx.AddRange(areaCommitments.Where(c => duplicateFbNrs.Contains(c.FbNr)));
|
||||||
|
}
|
||||||
|
if (importNewContracts) {
|
||||||
|
ctx.AddRange(contracts.Where(c => !duplicateFbNrs.Contains(c.FbNr)));
|
||||||
|
ctx.AddRange(areaCommitments.Where(c => !duplicateFbNrs.Contains(c.FbNr)));
|
||||||
|
}
|
||||||
|
if (contracts.Count > 0) {
|
||||||
ctx.AddRange(riede);
|
ctx.AddRange(riede);
|
||||||
var imported = areaCommitments.Where(c => (importNewMembers && !duplicateMgNrs.Contains(c.MgNr)) || (importDuplicateMembers && duplicateMgNrs.Contains(c.MgNr))).ToList();
|
var n = importNewContracts ? contracts.Count - duplicateFbNrs.Count : 0;
|
||||||
importedAreaComs.Add((meta.FileName, meta.ZwstId, meta.Device, imported.Count, areaCommitments.Count - imported.Count, meta.AreaComFilters));
|
var o = importDuplicateContracts ? duplicateFbNrs.Count : 0;
|
||||||
|
importedAreaComs.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, contracts.Count - n - o, meta.AreaComFilters));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowedDuplicateLsNrs.Count > 0) {
|
if (allowedDuplicateLsNrs.Count > 0) {
|
||||||
@@ -300,9 +350,10 @@ namespace Elwig.Helpers.Export {
|
|||||||
.Select(d => (d.Year, d.DId))
|
.Select(d => (d.Year, d.DId))
|
||||||
.ToList();
|
.ToList();
|
||||||
ctx.RemoveRange(ctx.DeliveryParts
|
ctx.RemoveRange(ctx.DeliveryParts
|
||||||
|
.IgnoreAutoIncludes()
|
||||||
.Where(p => allowedDuplicateLsNrs.Contains(p.Delivery.LsNr))
|
.Where(p => allowedDuplicateLsNrs.Contains(p.Delivery.LsNr))
|
||||||
.SelectMany(p => p.PartModifiers));
|
.SelectMany(p => p.PartModifiers));
|
||||||
ctx.RemoveRange(ctx.DeliveryParts.Where(p => allowedDuplicateLsNrs.Contains(p.Delivery.LsNr)));
|
ctx.RemoveRange(ctx.DeliveryParts.IgnoreAutoIncludes().Where(p => allowedDuplicateLsNrs.Contains(p.Delivery.LsNr)));
|
||||||
ctx.UpdateRange(deliveries.Where(d => dids.Contains((d.Year, d.DId))));
|
ctx.UpdateRange(deliveries.Where(d => dids.Contains((d.Year, d.DId))));
|
||||||
ctx.AddRange(deliveryParts.Where(p => dids.Contains((p.Year, p.DId))));
|
ctx.AddRange(deliveryParts.Where(p => dids.Contains((p.Year, p.DId))));
|
||||||
ctx.AddRange(modifiers.Where(m => dids.Contains((m.Year, m.DId))));
|
ctx.AddRange(modifiers.Where(m => dids.Contains((m.Year, m.DId))));
|
||||||
@@ -314,9 +365,10 @@ namespace Elwig.Helpers.Export {
|
|||||||
.Select(d => (d.Year, d.DId))
|
.Select(d => (d.Year, d.DId))
|
||||||
.ToList();
|
.ToList();
|
||||||
ctx.RemoveRange(ctx.DeliveryParts
|
ctx.RemoveRange(ctx.DeliveryParts
|
||||||
|
.IgnoreAutoIncludes()
|
||||||
.Where(p => l.Contains(p.Delivery.LsNr))
|
.Where(p => l.Contains(p.Delivery.LsNr))
|
||||||
.SelectMany(p => p.PartModifiers));
|
.SelectMany(p => p.PartModifiers));
|
||||||
ctx.RemoveRange(ctx.DeliveryParts.Where(p => l.Contains(p.Delivery.LsNr)));
|
ctx.RemoveRange(ctx.DeliveryParts.IgnoreAutoIncludes().Where(p => l.Contains(p.Delivery.LsNr)));
|
||||||
ctx.UpdateRange(deliveries.Where(d => dids.Contains((d.Year, d.DId))));
|
ctx.UpdateRange(deliveries.Where(d => dids.Contains((d.Year, d.DId))));
|
||||||
ctx.AddRange(deliveryParts.Where(p => dids.Contains((p.Year, p.DId))));
|
ctx.AddRange(deliveryParts.Where(p => dids.Contains((p.Year, p.DId))));
|
||||||
ctx.AddRange(modifiers.Where(m => dids.Contains((m.Year, m.DId))));
|
ctx.AddRange(modifiers.Where(m => dids.Contains((m.Year, m.DId))));
|
||||||
@@ -335,15 +387,17 @@ namespace Elwig.Helpers.Export {
|
|||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
var primaryKeys = new Dictionary<string, string>() {
|
var primaryKeys = new Dictionary<string, string>() {
|
||||||
["member"] = "mgnr, 0",
|
["member"] = "mgnr, 0, 0",
|
||||||
["area_commitment"] = "fbnr, 0",
|
["area_commitment_contract"] = "fbnr, 0, 0",
|
||||||
["delivery"] = "year, did",
|
["area_commitment"] = "fbnr, revnr, 0",
|
||||||
|
["delivery"] = "year, did, 0",
|
||||||
|
["delivery_part"] = "year, did, dpnr",
|
||||||
};
|
};
|
||||||
var updateStmts = timestamps
|
var updateStmts = timestamps
|
||||||
.SelectMany(e => e.Value.Select(m => $"UPDATE {e.Key} " +
|
.SelectMany(e => e.Value.Select(m => $"UPDATE {e.Key} " +
|
||||||
$"SET ctime = {((DateTimeOffset)m.CreatedAt.ToUniversalTime()).ToUnixTimeSeconds()}, " +
|
$"SET ctime = {((DateTimeOffset)m.CreatedAt.ToUniversalTime()).ToUnixTimeSeconds()}, " +
|
||||||
$"mtime = {((DateTimeOffset)m.ModifiedAt.ToUniversalTime()).ToUnixTimeSeconds()} " +
|
$"mtime = {((DateTimeOffset)m.ModifiedAt.ToUniversalTime()).ToUnixTimeSeconds()} " +
|
||||||
$"WHERE ({primaryKeys[e.Key]}) = ({m.Id1}, {m.Id2});"));
|
$"WHERE ({primaryKeys[e.Key]}) = ({m.Id1}, {m.Id2}, {m.Id3});"));
|
||||||
using var cnx = AppDbContext.Connect();
|
using var cnx = AppDbContext.Connect();
|
||||||
await cnx.ExecuteBatch($"""
|
await cnx.ExecuteBatch($"""
|
||||||
BEGIN;
|
BEGIN;
|
||||||
@@ -367,10 +421,10 @@ namespace Elwig.Helpers.Export {
|
|||||||
$" ({d.New} neu, {d.Overwritten} überschrieben, {d.NotImported} nicht importiert)\n" +
|
$" ({d.New} neu, {d.Overwritten} überschrieben, {d.NotImported} nicht importiert)\n" +
|
||||||
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
||||||
$" Filter: {d.Filters}"),
|
$" Filter: {d.Filters}"),
|
||||||
$"Flächenbindungen: {importedAreaComs.Sum(d => d.Imported)}",
|
$"Flächenbindungen: {importedAreaComs.Sum(d => d.New + d.Overwritten)}",
|
||||||
..importedAreaComs.Select(d =>
|
..importedAreaComs.Select(d =>
|
||||||
$" {d.FileName} ({d.Imported})\n" +
|
$" {d.FileName} ({d.New + d.Overwritten})\n" +
|
||||||
$" ({d.Imported} importiert, {d.NotImported} nicht importiert)\n" +
|
$" ({d.New} importiert, {d.Overwritten} überschreiben, {d.NotImported} nicht importiert)\n" +
|
||||||
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
||||||
$" Filter: {d.Filters}"),
|
$" Filter: {d.Filters}"),
|
||||||
$"Lieferungen: {importedDeliveries.Sum(d => d.New + d.Overwritten)}",
|
$"Lieferungen: {importedDeliveries.Sum(d => d.New + d.Overwritten)}",
|
||||||
@@ -407,7 +461,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
}.Export(filename);
|
}.Export(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<AreaCom> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
|
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
|
||||||
return new ElwigExport {
|
return new ElwigExport {
|
||||||
Members = (members, filters),
|
Members = (members, filters),
|
||||||
AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
|
AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
|
||||||
@@ -425,7 +479,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
public class ElwigExport {
|
public class ElwigExport {
|
||||||
public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
|
public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
|
||||||
public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
|
public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
|
||||||
public (IEnumerable<AreaCom> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; }
|
public (IEnumerable<AreaComContract> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; }
|
||||||
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
|
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
|
||||||
|
|
||||||
public async Task Export(string filename) {
|
public async Task Export(string filename) {
|
||||||
@@ -434,7 +488,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
||||||
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
||||||
await writer.WriteAsync("elwig:1");
|
await writer.WriteAsync("elwig:2");
|
||||||
}
|
}
|
||||||
|
|
||||||
var meta = zip.CreateEntry("meta.json", CompressionLevel.NoCompression);
|
var meta = zip.CreateEntry("meta.json", CompressionLevel.NoCompression);
|
||||||
@@ -456,8 +510,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
["filters"] = new JsonArray(Members.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
["filters"] = new JsonArray(Members.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||||
};
|
};
|
||||||
if (AreaComs != null)
|
if (AreaComs != null)
|
||||||
obj["area_commitments"] = new JsonObject {
|
obj["area_commitment_contracts"] = new JsonObject {
|
||||||
["count"] = AreaComs.Value.AreaComs.Count(),
|
["count"] = AreaComs.Value.AreaComs.Count(),
|
||||||
|
["revisions"] = AreaComs.Value.AreaComs.Sum(c => c.Revisions.Count),
|
||||||
["filters"] = new JsonArray(AreaComs.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
["filters"] = new JsonArray(AreaComs.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||||
};
|
};
|
||||||
if (Deliveries != null)
|
if (Deliveries != null)
|
||||||
@@ -485,7 +540,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (AreaComs != null) {
|
if (AreaComs != null) {
|
||||||
var json = zip.CreateEntry("area_commitments.json", CompressionLevel.SmallestSize);
|
var json = zip.CreateEntry("area_commitment_contracts.json", CompressionLevel.SmallestSize);
|
||||||
using var writer = new StreamWriter(json.Open(), Utils.UTF8);
|
using var writer = new StreamWriter(json.Open(), Utils.UTF8);
|
||||||
foreach (var c in AreaComs.Value.AreaComs) {
|
foreach (var c in AreaComs.Value.AreaComs) {
|
||||||
await writer.WriteLineAsync(c.ToJson().ToJsonString(Utils.JsonOpts));
|
await writer.WriteLineAsync(c.ToJson().ToJsonString(Utils.JsonOpts));
|
||||||
@@ -639,42 +694,102 @@ namespace Elwig.Helpers.Export {
|
|||||||
CountryNum = a["country"]!.AsValue().GetValue<int>(),
|
CountryNum = a["country"]!.AsValue().GetValue<int>(),
|
||||||
PostalDestId = a["postal_dest"]!.AsValue().GetValue<string>(),
|
PostalDestId = a["postal_dest"]!.AsValue().GetValue<string>(),
|
||||||
Address = a["address"]!.AsValue().GetValue<string>(),
|
Address = a["address"]!.AsValue().GetValue<string>(),
|
||||||
} : null, json["telephone_numbers"]!.AsArray().Select(n => n!.AsObject()).Select((n, i) => new MemberTelNr {
|
} : null, [.. json["telephone_numbers"]!.AsArray().Select(n => n!.AsObject()).Select((n, i) => new MemberTelNr {
|
||||||
MgNr = mgnr,
|
MgNr = mgnr,
|
||||||
Nr = i + 1,
|
Nr = i + 1,
|
||||||
Type = n["type"]!.AsValue().GetValue<string>(),
|
Type = n["type"]!.AsValue().GetValue<string>(),
|
||||||
Number = n["number"]!.AsValue().GetValue<string>(),
|
Number = n["number"]!.AsValue().GetValue<string>(),
|
||||||
Comment = n["comment"]?.AsValue().GetValue<string>(),
|
Comment = n["comment"]?.AsValue().GetValue<string>(),
|
||||||
}).ToList(), json["email_addresses"]!.AsArray().Select(a => a!.AsObject()).Select((a, i) => new MemberEmailAddr {
|
})], [.. json["email_addresses"]!.AsArray().Select(a => a!.AsObject()).Select((a, i) => new MemberEmailAddr {
|
||||||
MgNr = mgnr,
|
MgNr = mgnr,
|
||||||
Nr = i + 1,
|
Nr = i + 1,
|
||||||
Address = a["address"]!.AsValue().GetValue<string>(),
|
Address = a["address"]!.AsValue().GetValue<string>(),
|
||||||
Comment = a["comment"]?.AsValue().GetValue<string>(),
|
Comment = a["comment"]?.AsValue().GetValue<string>(),
|
||||||
}).ToList(),
|
})],
|
||||||
createdAt == null || modifiedAt == null ? null :
|
createdAt == null || modifiedAt == null ? null :
|
||||||
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
||||||
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
|
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JsonObject ToJson(this AreaCom c) {
|
public static JsonObject ToJson(this AreaComContract c) {
|
||||||
return new JsonObject {
|
return new JsonObject {
|
||||||
["fbnr"] = c.FbNr,
|
["fbnr"] = c.FbNr,
|
||||||
["mgnr"] = c.MgNr,
|
|
||||||
["vtrgid"] = c.VtrgId,
|
|
||||||
["cultid"] = c.CultId,
|
|
||||||
["area"] = c.Area,
|
|
||||||
["kgnr"] = c.KgNr,
|
["kgnr"] = c.KgNr,
|
||||||
["gstnr"] = c.GstNr,
|
|
||||||
["ried"] = c.Rd?.Name,
|
["ried"] = c.Rd?.Name,
|
||||||
["year_from"] = c.YearFrom,
|
["revisions"] = new JsonArray(c.Revisions.OrderBy(r => r.RevNr).Select(r => r.ToJson()).ToArray()),
|
||||||
["year_to"] = c.YearTo,
|
|
||||||
["comment"] = c.Comment,
|
["comment"] = c.Comment,
|
||||||
["created_at"] = $"{c.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
["created_at"] = $"{c.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
["modified_at"] = $"{c.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
["modified_at"] = $"{c.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (AreaCom, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCom(this JsonNode json, Dictionary<int, List<WbRd>> riede) {
|
private static JsonObject ToJson(this AreaCom c) {
|
||||||
|
return new JsonObject {
|
||||||
|
["revnr"] = c.RevNr,
|
||||||
|
["mgnr"] = c.MgNr,
|
||||||
|
["vtrgid"] = c.VtrgId,
|
||||||
|
["cultid"] = c.CultId,
|
||||||
|
["area"] = c.Area,
|
||||||
|
["gstnr"] = c.GstNr,
|
||||||
|
["year_from"] = c.YearFrom,
|
||||||
|
["year_to"] = c.YearTo,
|
||||||
|
["created_at"] = $"{c.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
|
["modified_at"] = $"{c.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (AreaComContract, List<(AreaCom, (DateTime CreatedAt, DateTime ModifiedAt)?)>, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaComContract(this JsonNode json, Dictionary<int, List<WbRd>> riede) {
|
||||||
|
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
||||||
|
var ried = json["ried"]?.AsValue().GetValue<string>();
|
||||||
|
var fbnr = json["fbnr"]!.AsValue()!.GetValue<int>();
|
||||||
|
WbRd? rd = null;
|
||||||
|
bool newRd = false;
|
||||||
|
if (ried != null) {
|
||||||
|
var rde = riede.GetValueOrDefault(kgnr, []);
|
||||||
|
rd = rde.FirstOrDefault(r => r.Name == ried);
|
||||||
|
if (rd == null) {
|
||||||
|
newRd = true;
|
||||||
|
rd = new WbRd {
|
||||||
|
KgNr = kgnr,
|
||||||
|
RdNr = (rde.Count == 0 ? 1 : rde.Max(r => r.RdNr)) + 1,
|
||||||
|
Name = ried,
|
||||||
|
};
|
||||||
|
rde.Add(rd);
|
||||||
|
riede[rd.KgNr] = rde;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
|
return (new AreaComContract {
|
||||||
|
FbNr = fbnr,
|
||||||
|
KgNr = kgnr,
|
||||||
|
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
||||||
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||||
|
ImportedAt = DateTime.Now,
|
||||||
|
}, [.. json["revisions"]!.AsArray().Select(r => r!.AsObject()).Select<JsonObject, (AreaCom, (DateTime, DateTime)?)>(r => {
|
||||||
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
|
return (new AreaCom {
|
||||||
|
FbNr = fbnr,
|
||||||
|
RevNr = r["revnr"]!.AsValue().GetValue<int>(),
|
||||||
|
MgNr = r["mgnr"]!.AsValue().GetValue<int>(),
|
||||||
|
VtrgId = r["vtrgid"]!.AsValue().GetValue<string>(),
|
||||||
|
CultId = r["cultid"]?.AsValue().GetValue<string>(),
|
||||||
|
Area = r["area"]!.AsValue().GetValue<int>(),
|
||||||
|
GstNr = r["gstnr"]?.AsValue().GetValue<string>() ?? "-",
|
||||||
|
YearFrom = r["year_from"]?.AsValue().GetValue<int>(),
|
||||||
|
YearTo = r["year_to"]?.AsValue().GetValue<int>(),
|
||||||
|
ImportedAt = DateTime.Now,
|
||||||
|
}, createdAt == null || modifiedAt == null ? null :
|
||||||
|
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
||||||
|
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
|
||||||
|
})], newRd ? rd : null,
|
||||||
|
createdAt == null || modifiedAt == null ? null :
|
||||||
|
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
||||||
|
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (AreaComContract, AreaCom, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCom(this JsonNode json, Dictionary<int, List<WbRd>> riede) {
|
||||||
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
||||||
var ried = json["ried"]?.AsValue().GetValue<string>();
|
var ried = json["ried"]?.AsValue().GetValue<string>();
|
||||||
WbRd? rd = null;
|
WbRd? rd = null;
|
||||||
@@ -695,18 +810,22 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
return (new AreaCom {
|
return (new AreaComContract {
|
||||||
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
||||||
|
KgNr = kgnr,
|
||||||
|
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
||||||
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||||
|
ImportedAt = DateTime.Now,
|
||||||
|
}, new AreaCom {
|
||||||
|
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
||||||
|
RevNr = 1,
|
||||||
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
||||||
VtrgId = json["vtrgid"]!.AsValue().GetValue<string>(),
|
VtrgId = json["vtrgid"]!.AsValue().GetValue<string>(),
|
||||||
CultId = json["cultid"]?.AsValue().GetValue<string>(),
|
CultId = json["cultid"]?.AsValue().GetValue<string>(),
|
||||||
Area = json["area"]!.AsValue().GetValue<int>(),
|
Area = json["area"]!.AsValue().GetValue<int>(),
|
||||||
KgNr = kgnr,
|
|
||||||
GstNr = json["gstnr"]?.AsValue().GetValue<string>() ?? "-",
|
GstNr = json["gstnr"]?.AsValue().GetValue<string>() ?? "-",
|
||||||
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
|
||||||
YearFrom = json["year_from"]?.AsValue().GetValue<int>(),
|
YearFrom = json["year_from"]?.AsValue().GetValue<int>(),
|
||||||
YearTo = json["year_to"]?.AsValue().GetValue<int>(),
|
YearTo = json["year_to"]?.AsValue().GetValue<int>(),
|
||||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
|
||||||
ImportedAt = DateTime.Now,
|
ImportedAt = DateTime.Now,
|
||||||
}, newRd ? rd : null,
|
}, newRd ? rd : null,
|
||||||
createdAt == null || modifiedAt == null ? null :
|
createdAt == null || modifiedAt == null ? null :
|
||||||
@@ -723,43 +842,45 @@ namespace Elwig.Helpers.Export {
|
|||||||
["lnr"] = d.LNr,
|
["lnr"] = d.LNr,
|
||||||
["time"] = d.Time != null ? $"{d.Time:HH:mm:ss}" : null,
|
["time"] = d.Time != null ? $"{d.Time:HH:mm:ss}" : null,
|
||||||
["mgnr"] = d.MgNr,
|
["mgnr"] = d.MgNr,
|
||||||
["parts"] = new JsonArray(d.Parts.OrderBy(p => p.DPNr).Select(p => {
|
["parts"] = new JsonArray(d.Parts.OrderBy(p => p.DPNr).Select(p => p.ToJson()).ToArray()),
|
||||||
var obj = new JsonObject {
|
|
||||||
["dpnr"] = p.DPNr,
|
|
||||||
["sortid"] = p.SortId,
|
|
||||||
["attrid"] = p.AttrId,
|
|
||||||
["cultid"] = p.CultId,
|
|
||||||
["weight"] = p.Weight,
|
|
||||||
["kmw"] = p.Kmw,
|
|
||||||
["qualid"] = p.QualId,
|
|
||||||
["hkid"] = p.HkId,
|
|
||||||
["kgnr"] = p.KgNr,
|
|
||||||
["ried"] = p.Rd?.Name,
|
|
||||||
["net_weight"] = p.IsNetWeight,
|
|
||||||
["manual_weighing"] = p.IsManualWeighing,
|
|
||||||
["modids"] = new JsonArray(p.Modifiers.Select(m => (JsonNode)m.ModId).ToArray()),
|
|
||||||
["comment"] = p.Comment,
|
|
||||||
["created_at"] = $"{p.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
|
||||||
["modified_at"] = $"{p.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
|
||||||
};
|
|
||||||
if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck;
|
|
||||||
if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked;
|
|
||||||
if (p.IsGebunden != null) obj["gebunden"] = p.IsGebunden;
|
|
||||||
if (p.Unloading != null) obj["unloading"] = p.Unloading;
|
|
||||||
if (p.Temperature != null) obj["temperature"] = p.Temperature;
|
|
||||||
if (p.Acid != null) obj["acid"] = p.Acid;
|
|
||||||
if (p.ScaleId != null) obj["scale_id"] = p.ScaleId;
|
|
||||||
if (p.WeighingData != null) obj["weighing_data"] = JsonNode.Parse(p.WeighingData);
|
|
||||||
if (p.WeighingReason != null) obj["weighing_reason"] = p.WeighingReason;
|
|
||||||
return obj;
|
|
||||||
}).ToArray()),
|
|
||||||
["comment"] = d.Comment,
|
["comment"] = d.Comment,
|
||||||
["created_at"] = $"{d.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
["created_at"] = $"{d.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
["modified_at"] = $"{d.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
["modified_at"] = $"{d.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (Delivery, List<DeliveryPart>, List<DeliveryPartModifier>, List<WbRd>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToDelivery(this JsonNode json, Dictionary<string, int> currentLsNrs, Dictionary<int, int> currentDids, Dictionary<int, AT_Kg> kgs, Dictionary<int, List<WbRd>> riede) {
|
private static JsonObject ToJson(this DeliveryPart p) {
|
||||||
|
var obj = new JsonObject {
|
||||||
|
["dpnr"] = p.DPNr,
|
||||||
|
["sortid"] = p.SortId,
|
||||||
|
["attrid"] = p.AttrId,
|
||||||
|
["cultid"] = p.CultId,
|
||||||
|
["weight"] = p.Weight,
|
||||||
|
["kmw"] = p.Kmw,
|
||||||
|
["qualid"] = p.QualId,
|
||||||
|
["hkid"] = p.HkId,
|
||||||
|
["kgnr"] = p.KgNr,
|
||||||
|
["ried"] = p.Rd?.Name,
|
||||||
|
["net_weight"] = p.IsNetWeight,
|
||||||
|
["manual_weighing"] = p.IsManualWeighing,
|
||||||
|
["modids"] = new JsonArray(p.PartModifiers.Select(m => (JsonNode)m.ModId).ToArray()),
|
||||||
|
["comment"] = p.Comment,
|
||||||
|
["created_at"] = $"{p.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
|
["modified_at"] = $"{p.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||||
|
};
|
||||||
|
if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck;
|
||||||
|
if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked;
|
||||||
|
if (p.IsGebunden != null) obj["gebunden"] = p.IsGebunden;
|
||||||
|
if (p.Unloading != null) obj["unloading"] = p.Unloading;
|
||||||
|
if (p.Temperature != null) obj["temperature"] = p.Temperature;
|
||||||
|
if (p.Acid != null) obj["acid"] = p.Acid;
|
||||||
|
if (p.ScaleId != null) obj["scale_id"] = p.ScaleId;
|
||||||
|
if (p.WeighingData != null) obj["weighing_data"] = JsonNode.Parse(p.WeighingData);
|
||||||
|
if (p.WeighingReason != null) obj["weighing_reason"] = p.WeighingReason;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (Delivery, List<(DeliveryPart, (DateTime CreatedAt, DateTime ModifiedAt)?)>, List<DeliveryPartModifier>, List<WbRd>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToDelivery(this JsonNode json, Dictionary<string, int> currentLsNrs, Dictionary<int, int> currentDids, Dictionary<int, AT_Kg> kgs, Dictionary<int, List<WbRd>> riede) {
|
||||||
var year = json["year"]!.AsValue().GetValue<int>();
|
var year = json["year"]!.AsValue().GetValue<int>();
|
||||||
var lsnr = json["lsnr"]!.AsValue().GetValue<string>();
|
var lsnr = json["lsnr"]!.AsValue().GetValue<string>();
|
||||||
var did = currentLsNrs.GetValueOrDefault(lsnr, -1);
|
var did = currentLsNrs.GetValueOrDefault(lsnr, -1);
|
||||||
@@ -782,7 +903,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
||||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||||
ImportedAt = DateTime.Now,
|
ImportedAt = DateTime.Now,
|
||||||
}, json["parts"]!.AsArray().Select(p => p!.AsObject()).Select(p => {
|
}, [.. json["parts"]!.AsArray().Select(p => p!.AsObject()).Select<JsonObject, (DeliveryPart, (DateTime, DateTime)?)>(p => {
|
||||||
var kgnr = p["kgnr"]?.AsValue().GetValue<int>();
|
var kgnr = p["kgnr"]?.AsValue().GetValue<int>();
|
||||||
var ried = p["ried"]?.AsValue().GetValue<string>();
|
var ried = p["ried"]?.AsValue().GetValue<string>();
|
||||||
WbRd? rd = null;
|
WbRd? rd = null;
|
||||||
@@ -800,7 +921,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
wbRde.Add(rd);
|
wbRde.Add(rd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new DeliveryPart {
|
var createdAt = p["created_at"]?.AsValue().GetValue<string>();
|
||||||
|
var modifiedAt = p["modified_at"]?.AsValue().GetValue<string>();
|
||||||
|
return (new DeliveryPart {
|
||||||
Year = year,
|
Year = year,
|
||||||
DId = did,
|
DId = did,
|
||||||
DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
|
DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
|
||||||
@@ -825,13 +948,15 @@ namespace Elwig.Helpers.Export {
|
|||||||
ScaleId = p["scale_id"]?.AsValue().GetValue<string>(),
|
ScaleId = p["scale_id"]?.AsValue().GetValue<string>(),
|
||||||
WeighingData = p["weighing_data"]?.AsObject().ToJsonString(Utils.JsonOpts),
|
WeighingData = p["weighing_data"]?.AsObject().ToJsonString(Utils.JsonOpts),
|
||||||
WeighingReason = p["weighing_reason"]?.AsValue().GetValue<string>(),
|
WeighingReason = p["weighing_reason"]?.AsValue().GetValue<string>(),
|
||||||
};
|
}, createdAt == null || modifiedAt == null ? null :
|
||||||
}).ToList(), json["parts"]!.AsArray().SelectMany(p => p!["modids"]!.AsArray().Select(m => new DeliveryPartModifier {
|
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
||||||
|
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
|
||||||
|
})], [.. json["parts"]!.AsArray().SelectMany(p => p!["modids"]!.AsArray().Select(m => new DeliveryPartModifier {
|
||||||
Year = year,
|
Year = year,
|
||||||
DId = did,
|
DId = did,
|
||||||
DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
|
DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
|
||||||
ModId = m!.AsValue().GetValue<string>(),
|
ModId = m!.AsValue().GetValue<string>(),
|
||||||
})).ToList(),
|
}))],
|
||||||
wbRde,
|
wbRde,
|
||||||
createdAt == null || modifiedAt == null ? null :
|
createdAt == null || modifiedAt == null ? null :
|
||||||
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
|
||||||
|
|||||||
@@ -413,8 +413,8 @@ namespace Elwig.Helpers {
|
|||||||
return output.OrderByDescending(l => l.Count());
|
return output.OrderByDescending(l => l.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<RawVaribute> GetVaributes(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
public static async Task<List<RawVaribute>> GetVaributes(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||||
var varieties = ctx.WineVarieties.Select(v => new RawVaribute(v.SortId, "", null)).ToList();
|
var varieties = await ctx.FetchWineVarieties().Select(v => new RawVaribute(v.SortId, "", null)).ToListAsync();
|
||||||
var delivered = ctx.DeliveryParts
|
var delivered = ctx.DeliveryParts
|
||||||
.Where(d => d.Year == year)
|
.Where(d => d.Year == year)
|
||||||
.Select(d => new RawVaribute(d.SortId, d.AttrId ?? "", d.CultId ?? ""))
|
.Select(d => new RawVaribute(d.SortId, d.AttrId ?? "", d.CultId ?? ""))
|
||||||
@@ -423,13 +423,11 @@ namespace Elwig.Helpers {
|
|||||||
return [.. (onlyDelivered ? delivered : delivered.Union(varieties)).Order()];
|
return [.. (onlyDelivered ? delivered : delivered.Union(varieties)).Order()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Varibute> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
public static async Task<List<Varibute>> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||||
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
var varieties = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||||
var cultivations = ctx.WineCultivations.ToDictionary(c => c.CultId, c => c);
|
var cultivations = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.CultId, c => c);
|
||||||
return GetVaributes(ctx, year, onlyDelivered)
|
return [.. (await GetVaributes(ctx, year, onlyDelivered)).Select(s => new Varibute(s, varieties, attributes, cultivations))];
|
||||||
.Select(s => new Varibute(s, varieties, attributes, cultivations))
|
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[LibraryImport("wininet.dll")]
|
[LibraryImport("wininet.dll")]
|
||||||
@@ -557,7 +555,9 @@ namespace Elwig.Helpers {
|
|||||||
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
|
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await doc.Generate();
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
await doc.Print();
|
await doc.Print();
|
||||||
} else if (mode == ExportMode.Email && emailData is (Member, string, string) e) {
|
} else if (mode == ExportMode.Email && emailData is (Member, string, string) e) {
|
||||||
if (doc.IsPreview) {
|
if (doc.IsPreview) {
|
||||||
@@ -565,7 +565,9 @@ namespace Elwig.Helpers {
|
|||||||
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
|
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await doc.Generate();
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]);
|
var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]);
|
||||||
if (success)
|
if (success)
|
||||||
MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mail im Posteingang des Empfängers aufscheint.", "E-Mail verschickt",
|
MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mail im Posteingang des Empfängers aufscheint.", "E-Mail verschickt",
|
||||||
@@ -582,12 +584,16 @@ namespace Elwig.Helpers {
|
|||||||
Title = $"{doc.Title} speichern unter - Elwig"
|
Title = $"{doc.Title} speichern unter - Elwig"
|
||||||
};
|
};
|
||||||
if (d.ShowDialog() == true) {
|
if (d.ShowDialog() == true) {
|
||||||
await doc.Generate();
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
doc.SaveTo(d.FileName);
|
doc.SaveTo(d.FileName);
|
||||||
Process.Start("explorer.exe", d.FileName);
|
Process.Start("explorer.exe", d.FileName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await doc.Generate();
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
doc.Show();
|
doc.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckFbNr(TextBox input, bool required, AreaCom? c) {
|
public static ValidationResult CheckFbNr(TextBox input, bool required, AreaComContract? c) {
|
||||||
var res = CheckInteger(input, required);
|
var res = CheckInteger(input, required);
|
||||||
if (!res.IsValid) {
|
if (!res.IsValid) {
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<PaymentVar> paymentVariants, int year, int avnr) {
|
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<PaymentVar> paymentVariants, int year, int avnr) {
|
||||||
var variant = await paymentVariants.FindAsync(year, avnr);
|
var variant = await paymentVariants.Include(v => v.Season.Modifiers).Where(v => v.Year == year && v.AvNr == avnr).SingleAsync();
|
||||||
BillingData? varData = null;
|
BillingData? varData = null;
|
||||||
try { varData = variant != null ? BillingData.FromJson(variant.Data) : null; } catch { }
|
try { varData = variant.Data != null ? BillingData.FromJson(variant.Data) : null; } catch { }
|
||||||
return (await FromDbSet(table, year, avnr))
|
return (await FromDbSet(table, year, avnr))
|
||||||
.GroupBy(
|
.GroupBy(
|
||||||
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
||||||
|
|||||||
@@ -28,12 +28,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DeliveryAncmtListData> FromQuery(IQueryable<DeliveryAncmt> query, List<string> filterNames) {
|
public static async Task<DeliveryAncmtListData> FromQuery(IQueryable<DeliveryAncmt> query, List<string> filterNames) {
|
||||||
return new((await query
|
return new((await query.ToListAsync()).Select(d => new DeliveryAncmtListRow(d)), filterNames);
|
||||||
.Include(a => a.Schedule.Branch)
|
|
||||||
.Include(a => a.Member)
|
|
||||||
.Include(a => a.Variety)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync()).Select(d => new DeliveryAncmtListRow(d)), filterNames);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,12 +52,8 @@ namespace Elwig.Models.Dtos {
|
|||||||
if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr);
|
if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr);
|
||||||
await q
|
await q
|
||||||
.Include(p => p.Delivery)
|
.Include(p => p.Delivery)
|
||||||
.Include(p => p.Variety)
|
|
||||||
.Include(p => p.Attribute)
|
|
||||||
.Include(p => p.Quality)
|
|
||||||
.Include(p => p.Buckets)
|
.Include(p => p.Buckets)
|
||||||
.Include(p => p.PartModifiers)
|
.Include(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||||
.ThenInclude(m => m.Modifier)
|
|
||||||
.LoadAsync();
|
.LoadAsync();
|
||||||
return await table.FromSqlRaw($"""
|
return await table.FromSqlRaw($"""
|
||||||
SELECT p.*
|
SELECT p.*
|
||||||
@@ -65,7 +61,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (v.year, v.did, v.dpnr)
|
JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (v.year, v.did, v.dpnr)
|
||||||
WHERE (p.year = {y} OR {y} IS NULL) AND (v.mgnr = {m} OR {m} IS NULL)
|
WHERE (p.year = {y} OR {y} IS NULL) AND (v.mgnr = {m} OR {m} IS NULL)
|
||||||
ORDER BY p.year, v.mgnr, v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr
|
ORDER BY p.year, v.mgnr, v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr
|
||||||
""").ToListAsync();
|
""").IgnoreAutoIncludes().ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,12 +40,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
.Include(p => p.Delivery.Member.Branch)
|
.Include(p => p.Delivery.Member.Branch)
|
||||||
.Include(p => p.Delivery.Branch)
|
.Include(p => p.Delivery.Branch)
|
||||||
.Include(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
.Include(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||||
.Include(p => p.Variety)
|
|
||||||
.Include(p => p.Attribute)
|
|
||||||
.Include(p => p.Cultivation)
|
|
||||||
.Include(p => p.Origin)
|
.Include(p => p.Origin)
|
||||||
.Include(p => p.Quality)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync()).Select(d => new DeliveryJournalRow(d)), filterNames);
|
.ToListAsync()).Select(d => new DeliveryJournalRow(d)), filterNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,15 +47,11 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCom) {
|
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCom) {
|
||||||
var areaComs = await query.ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
var areaComs = await query.Include(m => m.AreaCommitments).ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
||||||
return new((await query
|
return new((await query
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.Include(m => m.Branch)
|
.Include(m => m.Branch)
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync()).Select(m => new MemberListRow(m,
|
.ToListAsync()).Select(m => new MemberListRow(m,
|
||||||
areaComs[m.MgNr].Sum(c => c.Area),
|
areaComs[m.MgNr].Sum(c => c.Area),
|
||||||
areaComs[m.MgNr].Where(c => filterAreaCom.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
areaComs[m.MgNr].Where(c => filterAreaCom.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
using Elwig.Helpers;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Elwig.Models.Entities {
|
namespace Elwig.Models.Entities {
|
||||||
[Table("area_commitment"), PrimaryKey("FbNr")]
|
[Table("area_commitment"), PrimaryKey("FbNr", "RevNr")]
|
||||||
public class AreaCom {
|
public class AreaCom {
|
||||||
[Column("fbnr")]
|
[Column("fbnr")]
|
||||||
public int FbNr { get; set; }
|
public int FbNr { get; set; }
|
||||||
|
|
||||||
|
[Column("revnr")]
|
||||||
|
public int RevNr { get; set; }
|
||||||
|
|
||||||
[Column("mgnr")]
|
[Column("mgnr")]
|
||||||
public int MgNr { get; set; }
|
public int MgNr { get; set; }
|
||||||
|
|
||||||
@@ -22,24 +23,15 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("area")]
|
[Column("area")]
|
||||||
public int Area { get; set; }
|
public int Area { get; set; }
|
||||||
|
|
||||||
[Column("kgnr")]
|
|
||||||
public int KgNr { get; set; }
|
|
||||||
|
|
||||||
[Column("gstnr")]
|
[Column("gstnr")]
|
||||||
public required string GstNr { get; set; }
|
public required string GstNr { get; set; }
|
||||||
|
|
||||||
[Column("rdnr")]
|
|
||||||
public int? RdNr { get; set; }
|
|
||||||
|
|
||||||
[Column("year_from")]
|
[Column("year_from")]
|
||||||
public int? YearFrom { get; set; }
|
public int? YearFrom { get; set; }
|
||||||
|
|
||||||
[Column("year_to")]
|
[Column("year_to")]
|
||||||
public int? YearTo { get; set; }
|
public int? YearTo { get; set; }
|
||||||
|
|
||||||
[Column("comment")]
|
|
||||||
public string? Comment { get; set; }
|
|
||||||
|
|
||||||
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||||
public long CTime { get; set; }
|
public long CTime { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
@@ -72,6 +64,9 @@ namespace Elwig.Models.Entities {
|
|||||||
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
|
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ForeignKey("FbNr")]
|
||||||
|
public virtual AreaComContract Contract { get; private set; } = null!;
|
||||||
|
|
||||||
[ForeignKey("MgNr")]
|
[ForeignKey("MgNr")]
|
||||||
public virtual Member Member { get; private set; } = null!;
|
public virtual Member Member { get; private set; } = null!;
|
||||||
|
|
||||||
@@ -80,17 +75,5 @@ namespace Elwig.Models.Entities {
|
|||||||
|
|
||||||
[ForeignKey("CultId")]
|
[ForeignKey("CultId")]
|
||||||
public virtual WineCult? WineCult { get; private set; }
|
public virtual WineCult? WineCult { get; private set; }
|
||||||
|
|
||||||
[ForeignKey("KgNr")]
|
|
||||||
public virtual WbKg Kg { get; private set; } = null!;
|
|
||||||
|
|
||||||
[ForeignKey("KgNr, RdNr")]
|
|
||||||
public virtual WbRd? Rd { get; private set; }
|
|
||||||
|
|
||||||
public int SearchScore(IEnumerable<string> keywords) {
|
|
||||||
return Utils.GetSearchScore([
|
|
||||||
WineCult?.Name, Kg.AtKg.Name, Rd?.Name, GstNr, Comment,
|
|
||||||
], keywords);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
Elwig/Models/Entities/AreaComContract.cs
Normal file
78
Elwig/Models/Entities/AreaComContract.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Elwig.Models.Entities {
|
||||||
|
[Table("area_commitment_contract"), PrimaryKey("FbNr")]
|
||||||
|
public class AreaComContract {
|
||||||
|
[Column("fbnr")]
|
||||||
|
public int FbNr { get; set; }
|
||||||
|
|
||||||
|
[Column("kgnr")]
|
||||||
|
public int KgNr { get; set; }
|
||||||
|
|
||||||
|
[Column("rdnr")]
|
||||||
|
public int? RdNr { get; set; }
|
||||||
|
|
||||||
|
[Column("comment")]
|
||||||
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||||
|
public long CTime { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime CreatedAt {
|
||||||
|
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
|
||||||
|
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
|
||||||
|
public long MTime { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime ModifiedAt {
|
||||||
|
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
|
||||||
|
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Column("xtime")]
|
||||||
|
public long? XTime { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime? ExportedAt {
|
||||||
|
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
|
||||||
|
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Column("itime")]
|
||||||
|
public long? ITime { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime? ImportedAt {
|
||||||
|
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
|
||||||
|
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ForeignKey("KgNr")]
|
||||||
|
public virtual WbKg Kg { get; private set; } = null!;
|
||||||
|
|
||||||
|
[ForeignKey("KgNr, RdNr")]
|
||||||
|
public virtual WbRd? Rd { get; private set; }
|
||||||
|
|
||||||
|
[InverseProperty(nameof(AreaCom.Contract))]
|
||||||
|
public virtual ICollection<AreaCom> Revisions { get; private set; } = null!;
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public AreaCom? Latest => Revisions.OrderBy(r => r.RevNr).LastOrDefault();
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public int? YearFrom => Revisions.Any(r => r.YearFrom == null) ? null : Revisions.Min(r => r.YearFrom);
|
||||||
|
[NotMapped]
|
||||||
|
public int? YearTo => Revisions.Any(r => r.YearTo == null) ? null : Revisions.Max(r => r.YearTo);
|
||||||
|
|
||||||
|
public int SearchScore(IEnumerable<string> keywords) {
|
||||||
|
return Utils.GetSearchScore([
|
||||||
|
..Revisions.Select(r => r.WineCult?.Name), Kg.AtKg.Name, Rd?.Name, ..Revisions.Select(r => r.GstNr), Comment,
|
||||||
|
], keywords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -106,21 +106,21 @@ namespace Elwig.Models.Entities {
|
|||||||
[InverseProperty(nameof(DeliveryPart.Delivery))]
|
[InverseProperty(nameof(DeliveryPart.Delivery))]
|
||||||
public virtual ICollection<DeliveryPart> Parts { get; private set; } = null!;
|
public virtual ICollection<DeliveryPart> Parts { get; private set; } = null!;
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public IEnumerable<DeliveryPart> FilteredParts => PartFilter == null ? Parts : Parts.Where(p => PartFilter(p));
|
public IEnumerable<DeliveryPart> FilteredParts => PartFilter == null ? Parts : Parts.Where(p => PartFilter(p));
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public Predicate<DeliveryPart>? PartFilter { get; set; }
|
public Predicate<DeliveryPart>? PartFilter { get; set; }
|
||||||
|
|
||||||
public int Weight => Parts.Select(p => p.Weight).Sum();
|
public int Weight => Parts.Sum(p => p.Weight);
|
||||||
public int FilteredWeight => FilteredParts.Select(p => p.Weight).Sum();
|
public int FilteredWeight => FilteredParts.Sum(p => p.Weight);
|
||||||
|
|
||||||
public IEnumerable<RawVaribute> Vaributes => Parts
|
public IEnumerable<RawVaribute> Vaributes => Parts
|
||||||
.GroupBy(p => (p.SortId, p.AttrId, p.CultId))
|
.GroupBy(p => (p.SortId, p.AttrId, p.CultId))
|
||||||
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
|
.OrderByDescending(g => g.Sum(p => p.Weight))
|
||||||
.Select(g => new RawVaribute(g.Key.SortId, g.Key.AttrId, g.Key.CultId));
|
.Select(g => new RawVaribute(g.Key.SortId, g.Key.AttrId, g.Key.CultId));
|
||||||
public IEnumerable<RawVaribute> FilteredVaributes => FilteredParts
|
public IEnumerable<RawVaribute> FilteredVaributes => FilteredParts
|
||||||
.GroupBy(p => (p.SortId, p.AttrId, p.CultId))
|
.GroupBy(p => (p.SortId, p.AttrId, p.CultId))
|
||||||
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
|
.OrderByDescending(g => g.Sum(p => p.Weight))
|
||||||
.Select(g => new RawVaribute(g.Key.SortId, g.Key.AttrId, g.Key.CultId));
|
.Select(g => new RawVaribute(g.Key.SortId, g.Key.AttrId, g.Key.CultId));
|
||||||
public string VaributeString => string.Join(", ", Vaributes);
|
public string VaributeString => string.Join(", ", Vaributes);
|
||||||
public string FilteredVaributeString => string.Join(", ", FilteredVaributes);
|
public string FilteredVaributeString => string.Join(", ", FilteredVaributes);
|
||||||
@@ -153,7 +153,7 @@ namespace Elwig.Models.Entities {
|
|||||||
Member.Name, Member.MiddleName, Member.GivenName, Member.BillingAddress?.FullName,
|
Member.Name, Member.MiddleName, Member.GivenName, Member.BillingAddress?.FullName,
|
||||||
Comment
|
Comment
|
||||||
}.ToList();
|
}.ToList();
|
||||||
list.AddRange(Parts.Select(p => p.Comment).Distinct());
|
list.AddRange(FilteredParts.Select(p => p.Comment).Distinct());
|
||||||
return Utils.GetSearchScore(list, keywords);
|
return Utils.GetSearchScore(list, keywords);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,15 @@ namespace Elwig.Models.Entities {
|
|||||||
public virtual ICollection<WbGem> Gems { get; private set; } = null!;
|
public virtual ICollection<WbGem> Gems { get; private set; } = null!;
|
||||||
|
|
||||||
[InverseProperty(nameof(Parent))]
|
[InverseProperty(nameof(Parent))]
|
||||||
public virtual ICollection<WineOrigin> Children { get; private set; } = null!;
|
public virtual ICollection<WineOrigin> RealChildren { get; private set; } = null!;
|
||||||
|
[NotMapped]
|
||||||
|
public List<WineOrigin> Children { get; private set; } = [];
|
||||||
|
|
||||||
public int Level => (Parent?.Level + 1) ?? 0;
|
public int Level => (Parent?.Level + 1) ?? 0;
|
||||||
|
|
||||||
public string HkIdLevel => $"{new string(' ', Level * 2)}{HkId}";
|
public string HkIdLevel => $"{new string(' ', Level * 2)}{HkId}";
|
||||||
|
|
||||||
public int TotalChildNum => 1 + Children.Select(c => c.TotalChildNum).Sum();
|
public int TotalChildNum => 1 + Children.Sum(c => c.TotalChildNum);
|
||||||
|
|
||||||
private int SortKey1 => (Parent?.SortKey1 ?? 0) | (TotalChildNum << ((3 - Level) * 8));
|
private int SortKey1 => (Parent?.SortKey1 ?? 0) | (TotalChildNum << ((3 - Level) * 8));
|
||||||
public int SortKey => SortKey1 | ((Level < 3) ? (-1 >>> (Level * 8 + 8)) : 0);
|
public int SortKey => SortKey1 | ((Level < 3) ? (-1 >>> (Level * 8 + 8)) : 0);
|
||||||
|
|||||||
239
Elwig/Resources/Sql/37-38.sql
Normal file
239
Elwig/Resources/Sql/37-38.sql
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
-- schema version 37 to 38
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
|
|
||||||
|
DROP TRIGGER t_area_commitment_i_ctime;
|
||||||
|
DROP TRIGGER t_area_commitment_u_ctime;
|
||||||
|
DROP TRIGGER t_area_commitment_i_mtime;
|
||||||
|
DROP TRIGGER t_area_commitment_u_mtime;
|
||||||
|
|
||||||
|
CREATE TABLE area_commitment_contract (
|
||||||
|
fbnr INTEGER NOT NULL,
|
||||||
|
|
||||||
|
kgnr INTEGER NOT NULL,
|
||||||
|
rdnr INTEGER,
|
||||||
|
|
||||||
|
comment TEXT DEFAULT NULL,
|
||||||
|
ctime INTEGER NOT NULL DEFAULT (UNIXEPOCH()),
|
||||||
|
mtime INTEGER NOT NULL DEFAULT (UNIXEPOCH()),
|
||||||
|
xtime INTEGER DEFAULT NULL,
|
||||||
|
itime INTEGER DEFAULT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT area_commitment_contract PRIMARY KEY (fbnr),
|
||||||
|
CONSTRAINT fk_area_commitment_contract_wb_kg FOREIGN KEY (kgnr) REFERENCES wb_kg (kgnr)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT fk_area_commitment_contract_wb_rd FOREIGN KEY (kgnr, rdnr) REFERENCES wb_rd (kgnr, rdnr)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
) STRICT;
|
||||||
|
|
||||||
|
CREATE TABLE area_commitment_new (
|
||||||
|
fbnr INTEGER NOT NULL,
|
||||||
|
revnr INTEGER NOT NULL,
|
||||||
|
mgnr INTEGER NOT NULL,
|
||||||
|
|
||||||
|
vtrgid TEXT NOT NULL,
|
||||||
|
cultid TEXT DEFAULT NULL,
|
||||||
|
area INTEGER NOT NULL,
|
||||||
|
gstnr TEXT NOT NULL,
|
||||||
|
|
||||||
|
year_from INTEGER CHECK (year_from >= 1000 AND year_from <= 9999) DEFAULT NULL,
|
||||||
|
year_to INTEGER CHECK (year_to >= 1000 AND year_to <= 9999) DEFAULT NULL,
|
||||||
|
|
||||||
|
ctime INTEGER NOT NULL DEFAULT (UNIXEPOCH()),
|
||||||
|
mtime INTEGER NOT NULL DEFAULT (UNIXEPOCH()),
|
||||||
|
xtime INTEGER DEFAULT NULL,
|
||||||
|
itime INTEGER DEFAULT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT pk_area_commitment PRIMARY KEY (fbnr, revnr),
|
||||||
|
CONSTRAINT fk_area_commitment_area_commitment_contract FOREIGN KEY (fbnr) REFERENCES area_commitment_contract (fbnr)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE,
|
||||||
|
CONSTRAINT fk_area_commitment_member FOREIGN KEY (mgnr) REFERENCES member (mgnr)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT fk_area_commitment_area_commitment_type FOREIGN KEY (vtrgid) REFERENCES area_commitment_type (vtrgid)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT,
|
||||||
|
CONSTRAINT fk_area_commitment_wine_cultivation FOREIGN KEY (cultid) REFERENCES wine_cultivation (cultid)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
) STRICT;
|
||||||
|
|
||||||
|
INSERT INTO area_commitment_contract (fbnr, kgnr, rdnr, comment, ctime, mtime, xtime, itime)
|
||||||
|
SELECT fbnr, kgnr, rdnr, comment, ctime, mtime, xtime, itime
|
||||||
|
FROM area_commitment;
|
||||||
|
|
||||||
|
INSERT INTO area_commitment_new (fbnr, revnr, mgnr, vtrgid, cultid, area, gstnr, year_from, year_to, ctime, mtime, xtime, itime)
|
||||||
|
SELECT fbnr, 1, mgnr, vtrgid, cultid, area, gstnr, year_from, year_to, ctime, mtime, xtime, itime
|
||||||
|
FROM area_commitment;
|
||||||
|
|
||||||
|
PRAGMA foreign_keys = OFF;
|
||||||
|
PRAGMA writable_schema = ON;
|
||||||
|
DROP TABLE area_commitment;
|
||||||
|
ALTER TABLE area_commitment_new RENAME TO area_commitment;
|
||||||
|
PRAGMA writable_schema = OFF;
|
||||||
|
PRAGMA foreign_keys = ON;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_contract_i_ctime
|
||||||
|
AFTER INSERT ON area_commitment_contract FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND NEW.ctime != UNIXEPOCH()
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment_contract SET ctime = UNIXEPOCH() WHERE fbnr = NEW.fbnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_contract_u_ctime
|
||||||
|
BEFORE UPDATE ON area_commitment_contract FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND OLD.ctime != NEW.ctime
|
||||||
|
BEGIN
|
||||||
|
SELECT RAISE(ABORT, 'It is not allowed to change ctime');
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_contract_i_mtime
|
||||||
|
AFTER INSERT ON area_commitment_contract FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND NEW.mtime != UNIXEPOCH()
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment_contract SET mtime = UNIXEPOCH() WHERE fbnr = NEW.fbnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_contract_u_mtime
|
||||||
|
AFTER UPDATE ON area_commitment_contract FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND NEW.mtime != UNIXEPOCH()
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment_contract SET mtime = UNIXEPOCH() WHERE fbnr = NEW.fbnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_i_ctime
|
||||||
|
AFTER INSERT ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND NEW.ctime != UNIXEPOCH()
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment SET ctime = UNIXEPOCH() WHERE (fbnr, revnr) = (NEW.fbnr, NEW.revnr);
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_u_ctime
|
||||||
|
BEFORE UPDATE ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND OLD.ctime != NEW.ctime
|
||||||
|
BEGIN
|
||||||
|
SELECT RAISE(ABORT, 'It is not allowed to change ctime');
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_i_mtime
|
||||||
|
AFTER INSERT ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND NEW.mtime != UNIXEPOCH()
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment SET mtime = UNIXEPOCH() WHERE (fbnr, revnr) = (NEW.fbnr, NEW.revnr);
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_u_mtime
|
||||||
|
AFTER UPDATE ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1 AND NEW.mtime != UNIXEPOCH()
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment SET mtime = UNIXEPOCH() WHERE (fbnr, revnr) = (NEW.fbnr, NEW.revnr);
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_i_mtime_contract
|
||||||
|
AFTER INSERT ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment_contract SET mtime = UNIXEPOCH() WHERE fbnr = NEW.fbnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_u_mtime_contract
|
||||||
|
AFTER UPDATE ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment_contract SET mtime = UNIXEPOCH() WHERE fbnr = NEW.fbnr OR fbnr = OLD.fbnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_d_mtime_contract
|
||||||
|
AFTER DELETE ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1
|
||||||
|
BEGIN
|
||||||
|
UPDATE area_commitment_contract SET mtime = UNIXEPOCH() WHERE fbnr = OLD.fbnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_i_mtime_member
|
||||||
|
AFTER INSERT ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1
|
||||||
|
BEGIN
|
||||||
|
UPDATE member SET mtime = UNIXEPOCH() WHERE mgnr = NEW.mgnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_u_mtime_member
|
||||||
|
AFTER UPDATE ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1
|
||||||
|
BEGIN
|
||||||
|
UPDATE member SET mtime = UNIXEPOCH() WHERE mgnr = NEW.mgnr OR mgnr = OLD.mgnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_area_commitment_d_mtime_member
|
||||||
|
AFTER DELETE ON area_commitment FOR EACH ROW
|
||||||
|
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_TIME_TRIGGERS') = 1
|
||||||
|
BEGIN
|
||||||
|
UPDATE member SET mtime = UNIXEPOCH() WHERE mgnr = OLD.mgnr;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- fix user fiddling - set actual year_from
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET fbnr = a.fbnr, revnr = b.fbnr, year_from = a.year_to + 1
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr < b.fbnr
|
||||||
|
AND COALESCE(a.year_from <= a.year_to, TRUE)
|
||||||
|
AND COALESCE(b.year_from <= b.year_to, TRUE)
|
||||||
|
AND SUBSTR(a.vtrgid, 0, 2) = SUBSTR(b.vtrgid, 0, 2)
|
||||||
|
AND (SELECT c.kgnr = d.kgnr AND COALESCE(c.rdnr = d.rdnr, TRUE) FROM area_commitment_contract c, area_commitment_contract d WHERE c.fbnr = a.fbnr AND d.fbnr = b.fbnr)
|
||||||
|
AND ((IIF(INSTR(a.gstnr, b.gstnr) > 0, 1, 0) + IIF(INSTR(b.gstnr, a.gstnr) > 0, 1, 0) + IIF(a.area = b.area, 2, 0) + (a.mgnr = b.mgnr)) > 1)
|
||||||
|
AND ((a.year_from = b.year_from AND b.year_to IS NULL AND a.year_to IS NOT NULL));
|
||||||
|
|
||||||
|
-- simple
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET fbnr = a.fbnr, revnr = b.fbnr
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr < b.fbnr
|
||||||
|
AND COALESCE(a.year_from <= a.year_to, TRUE)
|
||||||
|
AND COALESCE(b.year_from <= b.year_to, TRUE)
|
||||||
|
AND SUBSTR(a.vtrgid, 0, 2) = SUBSTR(b.vtrgid, 0, 2)
|
||||||
|
AND (SELECT c.kgnr = d.kgnr AND COALESCE(c.rdnr = d.rdnr, TRUE) FROM area_commitment_contract c, area_commitment_contract d WHERE c.fbnr = a.fbnr AND d.fbnr = b.fbnr)
|
||||||
|
AND (a.gstnr = b.gstnr OR a.gstnr IN ('offen', '', '-')) AND a.area = b.area
|
||||||
|
AND a.year_to + 1 = b.year_from;
|
||||||
|
|
||||||
|
-- copy comments
|
||||||
|
UPDATE area_commitment_contract AS b
|
||||||
|
SET comment = IIF(b.comment IS NULL, a.comment, CONCAT(b.comment, '; ', a.comment))
|
||||||
|
FROM area_commitment_contract AS a
|
||||||
|
WHERE a.comment IS NOT NULL AND a.fbnr IN (SELECT revnr FROM area_commitment WHERE revnr > 1 AND fbnr = b.fbnr);
|
||||||
|
|
||||||
|
-- fix revnr
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET revnr = a.revnr + 1
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr = b.fbnr AND a.revnr < b.revnr;
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET revnr = a.revnr + 1
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr = b.fbnr AND a.revnr < b.revnr;
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET revnr = a.revnr + 1
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr = b.fbnr AND a.revnr < b.revnr;
|
||||||
|
|
||||||
|
-- fix year_from
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET year_from = a.year_to + 1
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr = b.fbnr AND a.revnr = b.revnr - 1
|
||||||
|
AND a.year_to = b.year_from;
|
||||||
|
UPDATE area_commitment AS b
|
||||||
|
SET year_from = a.year_to + 1
|
||||||
|
FROM area_commitment AS a
|
||||||
|
WHERE a.fbnr = b.fbnr AND a.revnr = b.revnr - 1
|
||||||
|
AND a.year_to = b.year_from;
|
||||||
|
|
||||||
|
-- delete unreferenced contracts
|
||||||
|
DELETE FROM area_commitment_contract
|
||||||
|
WHERE fbnr IN (SELECT c.fbnr FROM area_commitment_contract c
|
||||||
|
LEFT JOIN area_commitment a ON a.fbnr = c.fbnr
|
||||||
|
WHERE a.fbnr IS NULL);
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
@@ -20,41 +20,45 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void ClearInputs(this AreaComAdminViewModel vm) {
|
public static void ClearInputs(this AreaComAdminViewModel vm) {
|
||||||
|
vm.Period = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FillInputs(this AreaComAdminViewModel vm, AreaComContract c) {
|
||||||
|
vm.FbNr = c.FbNr;
|
||||||
|
vm.Period = c.YearTo == null ? $"ab {c.YearFrom}" : $"{c.YearFrom}\u2013{c.YearTo}";
|
||||||
|
vm.Comment = c.Comment;
|
||||||
|
vm.Kg = ControlUtils.GetItemFromSourceWithPk(vm.KgSource, c.KgNr) as AT_Kg;
|
||||||
|
vm.Rd = ControlUtils.GetItemFromSourceWithPk(vm.RdSource, c.KgNr, c.RdNr) as WbRd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FillInputs(this AreaComAdminViewModel vm, AreaCom a) {
|
public static void FillInputs(this AreaComAdminViewModel vm, AreaCom a) {
|
||||||
vm.FbNr = a.FbNr;
|
|
||||||
vm.MgNr = a.MgNr;
|
vm.MgNr = a.MgNr;
|
||||||
vm.YearFrom = a.YearFrom;
|
vm.YearFrom = a.YearFrom;
|
||||||
vm.YearTo = a.YearTo;
|
vm.YearTo = a.YearTo;
|
||||||
vm.AreaComType = ControlUtils.GetItemFromSourceWithPk(vm.AreaComTypeSource, a.VtrgId) as AreaComType;
|
vm.AreaComType = ControlUtils.GetItemFromSourceWithPk(vm.AreaComTypeSource, a.VtrgId) as AreaComType;
|
||||||
vm.WineCult = ControlUtils.GetItemFromSourceWithPk(vm.WineCultSource, a.CultId) as WineCult;
|
vm.WineCult = ControlUtils.GetItemFromSourceWithPk(vm.WineCultSource, a.CultId) as WineCult;
|
||||||
vm.Comment = a.Comment;
|
|
||||||
vm.Kg = ControlUtils.GetItemFromSourceWithPk(vm.KgSource, a.KgNr) as AT_Kg;
|
|
||||||
vm.Rd = ControlUtils.GetItemFromSourceWithPk(vm.RdSource, a.KgNr, a.RdNr) as WbRd;
|
|
||||||
vm.GstNr = a.GstNr;
|
vm.GstNr = a.GstNr;
|
||||||
vm.Area = a.Area;
|
vm.Area = a.Area;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(List<string>, IQueryable<AreaCom>, List<string>)> GetFilters(this AreaComAdminViewModel vm, AppDbContext ctx) {
|
public static async Task<(List<string>, IQueryable<AreaComContract>, IQueryable<AreaCom>, List<string>)> GetFilters(this AreaComAdminViewModel vm, AppDbContext ctx) {
|
||||||
List<string> filterNames = [];
|
List<string> filterNames = [];
|
||||||
IQueryable<AreaCom> areaComQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
IQueryable<AreaCom> areaComQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
||||||
if (vm.ShowOnlyActiveAreaComs) {
|
if (vm.FilterSeason is int season) {
|
||||||
areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, Utils.CurrentLastSeason);
|
areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, season);
|
||||||
filterNames.Add($"laufend {Utils.CurrentLastSeason}");
|
filterNames.Add($"laufend {season}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var filterVar = new List<string>();
|
var filterVar = new List<string>();
|
||||||
var filterNotVar = new List<string>();
|
var filterNotVar = new List<string>();
|
||||||
var filterAttr = new List<string>();
|
var filterAttr = new List<string>();
|
||||||
var filterNotAttr = new List<string>();
|
var filterNotAttr = new List<string>();
|
||||||
var filterSeasons = new List<int>();
|
|
||||||
|
|
||||||
var filter = vm.TextFilter;
|
var filter = vm.TextFilter;
|
||||||
if (filter.Count > 0) {
|
if (filter.Count > 0) {
|
||||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var attr = await ctx.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(" ")[0], a => a);
|
var attrId = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||||
var attrId = await ctx.WineAttributes.ToDictionaryAsync(a => a.AttrId, a => a);
|
var attr = attrId.Values.ToDictionary(a => a.Name.ToLower().Split(" ")[0], a => a);
|
||||||
|
|
||||||
for (int i = 0; i < filter.Count; i++) {
|
for (int i = 0; i < filter.Count; i++) {
|
||||||
var e = filter[i];
|
var e = filter[i];
|
||||||
@@ -88,10 +92,6 @@ namespace Elwig.Services {
|
|||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add($"ohne {var[e[1..3].ToUpper()].Name}");
|
filterNames.Add($"ohne {var[e[1..3].ToUpper()].Name}");
|
||||||
filterNames.Add($"ohne Attribut {attrId[e[3..].ToUpper()].Name}");
|
filterNames.Add($"ohne Attribut {attrId[e[3..].ToUpper()].Name}");
|
||||||
} else if (e.Length == 4 && int.TryParse(e, out var year)) {
|
|
||||||
filterSeasons.Add(year);
|
|
||||||
filter.RemoveAt(i--);
|
|
||||||
filterNames.Add($"laufend {e}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,38 +99,50 @@ namespace Elwig.Services {
|
|||||||
if (filterNotVar.Count > 0) areaComQuery = areaComQuery.Where(a => !filterNotVar.Contains(a.AreaComType.WineVar.SortId));
|
if (filterNotVar.Count > 0) areaComQuery = areaComQuery.Where(a => !filterNotVar.Contains(a.AreaComType.WineVar.SortId));
|
||||||
if (filterAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
if (filterAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
||||||
if (filterNotAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
if (filterNotAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
||||||
foreach (var year in filterSeasons) areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, year);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (filterNames, areaComQuery, filter);
|
IQueryable<AreaComContract> contracts = areaComQuery
|
||||||
|
.Select(c => c.Contract).Distinct()
|
||||||
|
.OrderBy(c => c.FbNr);
|
||||||
|
|
||||||
|
return (filterNames, contracts, areaComQuery, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<int> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr) {
|
public static async Task<(int FbNr, int RevNr)> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr, int? revNr) {
|
||||||
int newFbNr = vm.FbNr!.Value;
|
int newFbNr = vm.FbNr!.Value;
|
||||||
|
|
||||||
return await Task.Run(async () => {
|
return await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
|
var c = new AreaComContract {
|
||||||
|
FbNr = oldFbNr ?? newFbNr,
|
||||||
|
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
|
||||||
|
KgNr = vm.Kg!.KgNr,
|
||||||
|
RdNr = vm.Rd?.RdNr,
|
||||||
|
};
|
||||||
var a = new AreaCom {
|
var a = new AreaCom {
|
||||||
FbNr = oldFbNr ?? newFbNr,
|
FbNr = oldFbNr ?? newFbNr,
|
||||||
|
RevNr = revNr ?? await ctx.NextRevNr(oldFbNr ?? newFbNr),
|
||||||
MgNr = vm.MgNr!.Value,
|
MgNr = vm.MgNr!.Value,
|
||||||
YearFrom = vm.YearFrom,
|
YearFrom = vm.YearFrom,
|
||||||
YearTo = vm.YearTo,
|
YearTo = vm.YearTo,
|
||||||
VtrgId = vm.AreaComType!.VtrgId,
|
VtrgId = vm.AreaComType!.VtrgId,
|
||||||
CultId = vm.WineCult?.CultId,
|
CultId = vm.WineCult?.CultId,
|
||||||
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
|
|
||||||
KgNr = vm.Kg!.KgNr,
|
|
||||||
RdNr = vm.Rd?.RdNr,
|
|
||||||
GstNr = vm.GstNr?.Trim() ?? "-",
|
GstNr = vm.GstNr?.Trim() ?? "-",
|
||||||
Area = vm.Area!.Value,
|
Area = vm.Area!.Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (vm.Rd?.RdNr == 0) {
|
if (vm.Rd?.RdNr == 0) {
|
||||||
vm.Rd.RdNr = await ctx.NextRdNr(a.KgNr);
|
vm.Rd.RdNr = await ctx.NextRdNr(c.KgNr);
|
||||||
a.RdNr = vm.Rd.RdNr;
|
c.RdNr = vm.Rd.RdNr;
|
||||||
ctx.Add(vm.Rd);
|
ctx.Add(vm.Rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldFbNr != null) {
|
if (oldFbNr != null) {
|
||||||
|
ctx.Update(c);
|
||||||
|
} else {
|
||||||
|
ctx.Add(c);
|
||||||
|
}
|
||||||
|
if (revNr != null) {
|
||||||
ctx.Update(a);
|
ctx.Update(a);
|
||||||
} else {
|
} else {
|
||||||
ctx.Add(a);
|
ctx.Add(a);
|
||||||
@@ -139,10 +151,10 @@ namespace Elwig.Services {
|
|||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
if (newFbNr != a.FbNr) {
|
if (newFbNr != a.FbNr) {
|
||||||
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}");
|
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment_contract SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFbNr;
|
return (newFbNr, a.RevNr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +268,16 @@ namespace Elwig.Services {
|
|||||||
public static async Task DeleteAreaCom(int fbnr) {
|
public static async Task DeleteAreaCom(int fbnr) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var l = (await ctx.AreaCommitments.FindAsync(fbnr))!;
|
var l = (await ctx.AreaCommitmentContracts.FindAsync(fbnr))!;
|
||||||
|
ctx.Remove(l);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task DeleteAreaComRevision(int fbnr, int revnr) {
|
||||||
|
await Task.Run(async () => {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
var l = (await ctx.AreaCommitments.FindAsync(fbnr, revnr))!;
|
||||||
ctx.Remove(l);
|
ctx.Remove(l);
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -65,11 +65,11 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
var filter = vm.TextFilter;
|
var filter = vm.TextFilter;
|
||||||
if (filter.Count > 0) {
|
if (filter.Count > 0) {
|
||||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
var mgnr = await ctx.FetchMembers(includeNotActive: true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||||
var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
var zwst = await ctx.FetchBranches().ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
||||||
var attr = await ctx.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
var attr = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
||||||
var cult = await ctx.WineCultivations.ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
var cult = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
||||||
|
|
||||||
for (int i = 0; i < filter.Count; i++) {
|
for (int i = 0; i < filter.Count; i++) {
|
||||||
var e = filter[i];
|
var e = filter[i];
|
||||||
@@ -318,18 +318,13 @@ namespace Elwig.Services {
|
|||||||
AddToolTipCell(grid, $"{weight * 100.0 / total2:N1} %", row, 4, 1, bold, true);
|
AddToolTipCell(grid, $"{weight * 100.0 / total2:N1} %", row, 4, 1, bold, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(string, Grid)> GenerateToolTip(IQueryable<DeliveryAncmt> deliveryAncmts) {
|
public static async Task<(string Text, (string?, string?, int, int?, int)[] Grid)> GenerateToolTipData(IQueryable<DeliveryAncmt> deliveryAncmts) {
|
||||||
var grid = new Grid();
|
var grid = new List<(string?, string?, int, int?, int)>();
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(10) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(60) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(80) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
||||||
var text = "-";
|
var text = "-";
|
||||||
|
|
||||||
var weight = await deliveryAncmts.SumAsync(p => p.Weight);
|
var weight = await deliveryAncmts.SumAsync(p => p.Weight);
|
||||||
text = $"{weight:N0} kg";
|
text = $"{weight:N0} kg";
|
||||||
AddToolTipRow(grid, 0, "Menge", null, weight, null, weight);
|
grid.Add(("Menge", null, weight, null, weight));
|
||||||
|
|
||||||
if (await deliveryAncmts.AnyAsync()) {
|
if (await deliveryAncmts.AnyAsync()) {
|
||||||
var attrGroups = await deliveryAncmts
|
var attrGroups = await deliveryAncmts
|
||||||
@@ -370,13 +365,11 @@ namespace Elwig.Services {
|
|||||||
.ThenBy(g => g.SortId)
|
.ThenBy(g => g.SortId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
int rowNum = 1;
|
|
||||||
foreach (var attrG in attrGroups) {
|
foreach (var attrG in attrGroups) {
|
||||||
rowNum++;
|
|
||||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
||||||
AddToolTipRow(grid, rowNum++, name, null, attrG.Weight, attrG.Weight, weight);
|
grid.Add((name, null, attrG.Weight, attrG.Weight, weight));
|
||||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||||
AddToolTipRow(grid, rowNum++, null, g.SortId, g.Weight, attrG.Weight, weight);
|
grid.Add((null, g.SortId, g.Weight, attrG.Weight, weight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,7 +388,22 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (text, grid);
|
return (text, grid.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Grid GenerateToolTip((string?, string?, int, int?, int)[] data) {
|
||||||
|
var grid = new Grid();
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(10) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(60) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(80) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
|
int rowNum = 0;
|
||||||
|
foreach (var row in data) {
|
||||||
|
if (rowNum != 0 && row.Item2 == null) rowNum++;
|
||||||
|
AddToolTipRow(grid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
|
||||||
|
}
|
||||||
|
return grid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
var filter = vm.TextFilter;
|
var filter = vm.TextFilter;
|
||||||
if (filter.Count > 0) {
|
if (filter.Count > 0) {
|
||||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(" ")[0], b => b);
|
var zwst = await ctx.FetchBranches().ToDictionaryAsync(b => b.Name.ToLower().Split(" ")[0], b => b);
|
||||||
|
|
||||||
for (int i = 0; i < filter.Count; i++) {
|
for (int i = 0; i < filter.Count; i++) {
|
||||||
var e = filter[i];
|
var e = filter[i];
|
||||||
@@ -174,12 +174,12 @@ namespace Elwig.Services {
|
|||||||
ctx.Add(s);
|
ctx.Add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.UpdateDeliveryScheduleWineVarieties(s, (await ctx.DeliveryScheduleWineVarieties
|
await ctx.UpdateDeliveryScheduleWineVarieties(s, (await ctx.DeliveryScheduleWineVarieties
|
||||||
.Where(v => v.Year == s.Year && v.DsNr == s.DsNr)
|
.Where(v => v.Year == s.Year && v.DsNr == s.DsNr)
|
||||||
.Select(v => new { v.Variety, v.Priority })
|
.Select(v => new { v.Variety, v.Priority })
|
||||||
.ToListAsync())
|
.ToListAsync())
|
||||||
.Select(v => (v.Variety, v.Priority))
|
.Select(v => (v.Variety.SortId, v.Priority))
|
||||||
.ToList(), vm.MainVarieties.Select(v => (v, 1)).Union(vm.OtherVarieties.Select(v => (v, 2))).ToList());
|
.ToList(), vm.MainVarieties.Select(v => (v.SortId, 1)).Union(vm.OtherVarieties.Select(v => (v.SortId, 2))).ToList());
|
||||||
|
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
public static async Task<Member?> GetMemberAsync(int mgnr) {
|
public static async Task<Member?> GetMemberAsync(int mgnr) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
return await ctx.Members
|
return await ctx.FetchMembers(mgnr).SingleOrDefaultAsync();
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.FirstOrDefaultAsync(m => m.MgNr == mgnr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Member? GetMember(int mgnr) {
|
public static Member? GetMember(int mgnr) {
|
||||||
@@ -71,7 +68,7 @@ namespace Elwig.Services {
|
|||||||
vm.IsNetWeight = p.IsNetWeight;
|
vm.IsNetWeight = p.IsNetWeight;
|
||||||
|
|
||||||
vm.Modifiers.Clear();
|
vm.Modifiers.Clear();
|
||||||
foreach (var m in p.Modifiers) {
|
foreach (var m in p.PartModifiers) {
|
||||||
vm.Modifiers.Add((Modifier)ControlUtils.GetItemFromSourceWithPk(vm.ModifiersSource, m.Year, m.ModId)!);
|
vm.Modifiers.Add((Modifier)ControlUtils.GetItemFromSourceWithPk(vm.ModifiersSource, m.Year, m.ModId)!);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,12 +126,12 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
var filter = vm.TextFilter;
|
var filter = vm.TextFilter;
|
||||||
if (filter.Count > 0) {
|
if (filter.Count > 0) {
|
||||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||||
var qual = await ctx.WineQualityLevels.Where(q => !q.IsPredicate).ToDictionaryAsync(q => q.QualId, q => q);
|
var qual = await ctx.FetchWineQualityLevels(false).ToDictionaryAsync(q => q.QualId, q => q);
|
||||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
var mgnr = await ctx.FetchMembers(includeNotActive: true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||||
var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
var zwst = await ctx.FetchBranches().ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
||||||
var attr = await ctx.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
var attr = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
||||||
var cult = await ctx.WineCultivations.ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
var cult = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
||||||
|
|
||||||
for (int i = 0; i < filter.Count; i++) {
|
for (int i = 0; i < filter.Count; i++) {
|
||||||
var e = filter[i];
|
var e = filter[i];
|
||||||
@@ -472,6 +469,7 @@ namespace Elwig.Services {
|
|||||||
DeliveryPart p;
|
DeliveryPart p;
|
||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
|
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||||
int year = oldYear ?? Utils.CurrentYear;
|
int year = oldYear ?? Utils.CurrentYear;
|
||||||
int did = oldDid ?? await ctx.NextDId(year);
|
int did = oldDid ?? await ctx.NextDId(year);
|
||||||
int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did);
|
int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did);
|
||||||
@@ -548,21 +546,21 @@ namespace Elwig.Services {
|
|||||||
ctx.Add(p);
|
ctx.Add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.UpdateDeliveryPartModifiers(p, await ctx.DeliveryPartModifiers
|
await ctx.UpdateDeliveryPartModifiers(p, await ctx.DeliveryPartModifiers
|
||||||
.Where(m => m.Year == p.Year && m.DId == p.DId && m.DPNr == p.DPNr)
|
.Where(m => m.Year == p.Year && m.DId == p.DId && m.DPNr == p.DPNr)
|
||||||
.Select(m => m.Modifier)
|
.Select(m => m.ModId)
|
||||||
.ToListAsync(), vm.Modifiers);
|
.ToListAsync(), vm.Modifiers.Select(m => m.ModId).ToList());
|
||||||
|
|
||||||
if (originalMgNr != null && originalMgNr.Value != d.MgNr) {
|
if (originalMgNr != null && originalMgNr.Value != d.MgNr) {
|
||||||
// update origin (KgNr), if default is selected
|
// update origin (KgNr), if default is selected
|
||||||
var newKgNr = (await ctx.Members.FindAsync(d.MgNr))?.DefaultKgNr;
|
var newKgNr = (await ctx.FetchMembers(d.MgNr).SingleOrDefaultAsync())?.DefaultKgNr;
|
||||||
foreach (var part in d.Parts.Where(part => part.DPNr != dpnr && part.KgNr == originalMemberKgNr)) {
|
await ctx.DeliveryParts
|
||||||
part.KgNr = newKgNr;
|
.Where(p => p.Year == d.Year && p.DId == d.DId && p.DPNr != dpnr && p.KgNr == originalMemberKgNr)
|
||||||
ctx.Update(part);
|
.ExecuteUpdateAsync(u => u.SetProperty(p => p.KgNr, newKgNr));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
await tx.CommitAsync();
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
});
|
});
|
||||||
@@ -574,7 +572,10 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
bool anyLeft = false;
|
bool anyLeft = false;
|
||||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
var d = await ctx.Deliveries
|
||||||
|
.Where(d => d.Year == year && d.DId == did)
|
||||||
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
|
.SingleAsync();
|
||||||
var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
|
var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
|
||||||
n = new Delivery {
|
n = new Delivery {
|
||||||
Year = year,
|
Year = year,
|
||||||
@@ -601,7 +602,11 @@ namespace Elwig.Services {
|
|||||||
anyLeft = true;
|
anyLeft = true;
|
||||||
p.Weight -= w;
|
p.Weight -= w;
|
||||||
ctx.Update(p);
|
ctx.Update(p);
|
||||||
var s = ctx.CreateProxy<DeliveryPart>();
|
var s = new DeliveryPart {
|
||||||
|
SortId = null!,
|
||||||
|
QualId = null!,
|
||||||
|
HkId = null!,
|
||||||
|
};
|
||||||
var values = ctx.Entry(p).CurrentValues;
|
var values = ctx.Entry(p).CurrentValues;
|
||||||
ctx.Entry(s).CurrentValues.SetValues(values);
|
ctx.Entry(s).CurrentValues.SetValues(values);
|
||||||
s.Year = n.Year;
|
s.Year = n.Year;
|
||||||
@@ -632,8 +637,11 @@ namespace Elwig.Services {
|
|||||||
Delivery n;
|
Delivery n;
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var anyLeft = false;
|
var anyLeft = false;
|
||||||
n = (await ctx.Deliveries.FirstAsync(d => d.LsNr == lsnr))!;
|
n = (await ctx.Deliveries.Where(d => d.LsNr == lsnr).FirstAsync())!;
|
||||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
var d = await ctx.Deliveries
|
||||||
|
.Where(d => d.Year == year && d.DId == did)
|
||||||
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
|
.SingleAsync();
|
||||||
var dpnr = await ctx.NextDPNr(n.Year, n.DId);
|
var dpnr = await ctx.NextDPNr(n.Year, n.DId);
|
||||||
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
|
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
|
||||||
if (w <= 0) {
|
if (w <= 0) {
|
||||||
@@ -645,7 +653,11 @@ namespace Elwig.Services {
|
|||||||
anyLeft = true;
|
anyLeft = true;
|
||||||
p.Weight -= w;
|
p.Weight -= w;
|
||||||
ctx.Update(p);
|
ctx.Update(p);
|
||||||
var s = ctx.CreateProxy<DeliveryPart>();
|
var s = new DeliveryPart {
|
||||||
|
SortId = null!,
|
||||||
|
QualId = null!,
|
||||||
|
HkId = null!,
|
||||||
|
};
|
||||||
var values = ctx.Entry(p).CurrentValues;
|
var values = ctx.Entry(p).CurrentValues;
|
||||||
ctx.Entry(s).CurrentValues.SetValues(values);
|
ctx.Entry(s).CurrentValues.SetValues(values);
|
||||||
s.Year = n.Year;
|
s.Year = n.Year;
|
||||||
@@ -674,7 +686,10 @@ namespace Elwig.Services {
|
|||||||
public static async Task DepreciateDelivery(int year, int did, int[] weights) {
|
public static async Task DepreciateDelivery(int year, int did, int[] weights) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
var d = await ctx.Deliveries
|
||||||
|
.Where(d => d.Year == year && d.DId == did)
|
||||||
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
|
.SingleAsync();
|
||||||
var dpnr = await ctx.NextDPNr(year, did);
|
var dpnr = await ctx.NextDPNr(year, did);
|
||||||
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
|
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
|
||||||
if (w <= 0) {
|
if (w <= 0) {
|
||||||
@@ -686,7 +701,11 @@ namespace Elwig.Services {
|
|||||||
} else {
|
} else {
|
||||||
p.Weight -= w;
|
p.Weight -= w;
|
||||||
ctx.Update(p);
|
ctx.Update(p);
|
||||||
var n = ctx.CreateProxy<DeliveryPart>();
|
var n = new DeliveryPart {
|
||||||
|
SortId = null!,
|
||||||
|
QualId = null!,
|
||||||
|
HkId = null!,
|
||||||
|
};
|
||||||
var values = ctx.Entry(p).CurrentValues;
|
var values = ctx.Entry(p).CurrentValues;
|
||||||
ctx.Entry(n).CurrentValues.SetValues(values);
|
ctx.Entry(n).CurrentValues.SetValues(values);
|
||||||
n.DPNr = dpnr++;
|
n.DPNr = dpnr++;
|
||||||
@@ -711,10 +730,8 @@ namespace Elwig.Services {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await DeliveryNote.Initialize(year, did);
|
||||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
await Utils.ExportDocument(doc, mode, doc.Delivery.LsNr, (doc.Member, $"{DeliveryNote.Name} Nr. {doc.Delivery.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {doc.Delivery.LsNr}"));
|
||||||
using var doc = new DeliveryNote(d, ctx);
|
|
||||||
await Utils.ExportDocument(doc, mode, d.LsNr, (d.Member, $"{DeliveryNote.Name} Nr. {d.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {d.LsNr}"));
|
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
@@ -792,9 +809,6 @@ namespace Elwig.Services {
|
|||||||
.Select(p => p.Delivery)
|
.Select(p => p.Delivery)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Kg!.Gl)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var wbKgs = list
|
var wbKgs = list
|
||||||
.SelectMany(d => d.Parts)
|
.SelectMany(d => d.Parts)
|
||||||
@@ -937,7 +951,7 @@ namespace Elwig.Services {
|
|||||||
tblTotal.FullName = DeliveryDepreciationList.Name;
|
tblTotal.FullName = DeliveryDepreciationList.Name;
|
||||||
tblTotal.Name = "Gesamt";
|
tblTotal.Name = "Gesamt";
|
||||||
await ods.AddTable(tblTotal);
|
await ods.AddTable(tblTotal);
|
||||||
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
|
foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
|
||||||
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
|
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
|
||||||
tbl.FullName = DeliveryDepreciationList.Name;
|
tbl.FullName = DeliveryDepreciationList.Name;
|
||||||
tbl.Name = branch.Name;
|
tbl.Name = branch.Name;
|
||||||
@@ -1048,16 +1062,23 @@ namespace Elwig.Services {
|
|||||||
var gGrid = new List<(string?, string?, double, double, double)>();
|
var gGrid = new List<(string?, string?, double, double, double)>();
|
||||||
var gText = "-";
|
var gText = "-";
|
||||||
|
|
||||||
var weight = await deliveryParts.SumAsync(p => p.Weight);
|
var stat = (await deliveryParts.GroupBy(p => 0)
|
||||||
wText = $"{weight:N0} kg";
|
.Select(g => new {
|
||||||
wGrid.Add(("Menge", null, weight, null, weight));
|
Weight = g.Sum(p => p.Weight),
|
||||||
|
Min = g.Select(p => (double?)p.Kmw).DefaultIfEmpty().Min(),
|
||||||
|
Avg = g.Sum(p => p.Kmw * p.Weight) / g.Sum(p => p.Weight),
|
||||||
|
Max = g.Select(p => (double?)p.Kmw).DefaultIfEmpty().Max(),
|
||||||
|
})
|
||||||
|
.ToListAsync())
|
||||||
|
.DefaultIfEmpty(new { Weight = 0, Min = (double?)null, Avg = (double)0, Max = (double?)null })
|
||||||
|
.Single();
|
||||||
|
|
||||||
if (await deliveryParts.AnyAsync()) {
|
wText = $"{stat.Weight:N0} kg";
|
||||||
var kmwMin = await deliveryParts.MinAsync(p => p.Kmw);
|
wGrid.Add(("Menge", null, stat.Weight, null, stat.Weight));
|
||||||
var kmwAvg = Utils.AggregateDeliveryPartsKmw(deliveryParts);
|
|
||||||
var kmwMax = await deliveryParts.MaxAsync(p => p.Kmw);
|
if (stat.Min != null && stat.Max != null) {
|
||||||
gText = $"{kmwMin:N1}° / {kmwAvg:N1}° / {kmwMax:N1}°";
|
gText = $"{stat.Min:N1}° / {stat.Avg:N1}° / {stat.Max:N1}°";
|
||||||
gGrid.Add(("Gradation", null, kmwMin, kmwAvg, kmwMax));
|
gGrid.Add(("Gradation", null, stat.Min.Value, stat.Avg, stat.Max.Value));
|
||||||
|
|
||||||
var attrGroups = await deliveryParts
|
var attrGroups = await deliveryParts
|
||||||
.GroupBy(p => new { Attr = p.Attribute!.Name, Cult = p.Cultivation!.Name })
|
.GroupBy(p => new { Attr = p.Attribute!.Name, Cult = p.Cultivation!.Name })
|
||||||
@@ -1108,9 +1129,9 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
foreach (var attrG in attrGroups) {
|
foreach (var attrG in attrGroups) {
|
||||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
||||||
wGrid.Add((name, null, attrG.Weight, attrG.Weight, weight));
|
wGrid.Add((name, null, attrG.Weight, attrG.Weight, stat.Weight));
|
||||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||||
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, weight));
|
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, stat.Weight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var attrG in attrGroups) {
|
foreach (var attrG in attrGroups) {
|
||||||
@@ -1129,12 +1150,12 @@ namespace Elwig.Services {
|
|||||||
gText += $" [{name}]";
|
gText += $" [{name}]";
|
||||||
}
|
}
|
||||||
if (sortGroups.Count > 1 && sortGroups.Count <= 4) {
|
if (sortGroups.Count > 1 && sortGroups.Count <= 4) {
|
||||||
wText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / weight:0%})" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
wText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / stat.Weight:0%})" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
||||||
gText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
gText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (attrGroups.Count <= 4) {
|
} else if (attrGroups.Count <= 4) {
|
||||||
wText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / weight:0%})" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
wText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / stat.Weight:0%})" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
||||||
gText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
gText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ namespace Elwig.Services {
|
|||||||
var c = m.ActiveAreaCommitments(ctx, Utils.CurrentLastSeason);
|
var c = m.ActiveAreaCommitments(ctx, Utils.CurrentLastSeason);
|
||||||
int maxKgPerHa = 10_000;
|
int maxKgPerHa = 10_000;
|
||||||
try {
|
try {
|
||||||
var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year));
|
var s = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||||
if (s != null) maxKgPerHa = s.MaxKgPerHa;
|
if (s != null) maxKgPerHa = s.MaxKgPerHa;
|
||||||
} catch { }
|
} catch { }
|
||||||
var (text, gridData) = await AreaComService.GenerateToolTipData(c, maxKgPerHa);
|
var (text, gridData) = await AreaComService.GenerateToolTipData(c, maxKgPerHa);
|
||||||
@@ -225,8 +225,8 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
var filter = vm.TextFilter;
|
var filter = vm.TextFilter;
|
||||||
if (filter.Count > 0) {
|
if (filter.Count > 0) {
|
||||||
var branches = await ctx.Branches.ToListAsync();
|
var branches = await ctx.FetchBranches().ToListAsync();
|
||||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
var mgnr = await ctx.FetchMembers(includeNotActive: true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||||
var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg);
|
var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg);
|
||||||
var areaComs = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
var areaComs = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
||||||
|
|
||||||
@@ -395,8 +395,7 @@ namespace Elwig.Services {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = new MemberDataSheet(m);
|
||||||
using var doc = new MemberDataSheet(m, ctx);
|
|
||||||
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
|
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
@@ -409,14 +408,12 @@ namespace Elwig.Services {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
var b = new Billing(year);
|
var b = await Billing.Create(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets();
|
await b.CalculateBuckets();
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var doc = new DeliveryConfirmation(year, m, null);
|
||||||
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m);
|
|
||||||
using var doc = new DeliveryConfirmation(ctx, year, m, data);
|
|
||||||
await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}"));
|
await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}"));
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
@@ -429,16 +426,8 @@ namespace Elwig.Services {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await CreditNote.Initialize(year, avnr, m.MgNr, null);
|
||||||
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
|
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {doc.Payment.Variant.Name}", $"Im Anhang finden Sie die Traubengutschrift {doc.Payment.Variant.Name}"));
|
||||||
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, year, avnr);
|
|
||||||
var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!;
|
|
||||||
var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data);
|
|
||||||
|
|
||||||
using var doc = new CreditNote(ctx, p, data[m.MgNr],
|
|
||||||
b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers,
|
|
||||||
await ctx.GetMemberUnderDelivery(year, m.MgNr));
|
|
||||||
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {v.Name}", $"Im Anhang finden Sie die Traubengutschrift {v.Name}"));
|
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
@@ -520,10 +509,8 @@ namespace Elwig.Services {
|
|||||||
try {
|
try {
|
||||||
var members = await query
|
var members = await query
|
||||||
.OrderBy(m => m.MgNr)
|
.OrderBy(m => m.MgNr)
|
||||||
.Include(m => m.BillingAddress)
|
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
using var exporter = new VCard(d.FileName);
|
using var exporter = new VCard(d.FileName);
|
||||||
await exporter.ExportAsync(members);
|
await exporter.ExportAsync(members);
|
||||||
@@ -548,16 +535,13 @@ namespace Elwig.Services {
|
|||||||
try {
|
try {
|
||||||
var members = await query
|
var members = await query
|
||||||
.OrderBy(m => m.MgNr)
|
.OrderBy(m => m.MgNr)
|
||||||
.Include(m => m.BillingAddress)
|
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.Include(m => m.DefaultWbKg!.Gl)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var areaComs = await query
|
var areaComs = await query
|
||||||
.SelectMany(m => m.AreaCommitments)
|
.SelectMany(m => m.AreaCommitments)
|
||||||
.Include(c => c.Rd)
|
.Select(c => c.Contract).Distinct()
|
||||||
.Include(c => c.Kg.Gl)
|
.Include(c => c.Revisions)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var wbKgs = members
|
var wbKgs = members
|
||||||
.Where(m => m.DefaultWbKg != null)
|
.Where(m => m.DefaultWbKg != null)
|
||||||
@@ -681,19 +665,17 @@ namespace Elwig.Services {
|
|||||||
.Where(c => c.MgNr == predecessor && (c.YearTo == null || c.YearTo >= year))
|
.Where(c => c.MgNr == predecessor && (c.YearTo == null || c.YearTo >= year))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var fbNr = await ctx.NextFbNr();
|
ctx.AddRange(await Task.WhenAll(areaComs.Select(async (c, i) => new AreaCom {
|
||||||
ctx.AddRange(areaComs.Select((c, i) => new AreaCom {
|
FbNr = c.FbNr,
|
||||||
FbNr = fbNr + i,
|
RevNr = await ctx.NextRevNr(c.FbNr),
|
||||||
MgNr = m.MgNr,
|
MgNr = m.MgNr,
|
||||||
VtrgId = c.VtrgId,
|
VtrgId = c.VtrgId,
|
||||||
CultId = c.CultId,
|
CultId = c.CultId,
|
||||||
Area = c.Area,
|
Area = c.Area,
|
||||||
KgNr = c.KgNr,
|
|
||||||
GstNr = c.GstNr,
|
GstNr = c.GstNr,
|
||||||
RdNr = c.RdNr,
|
YearFrom = year,
|
||||||
YearFrom = vm.MaintainAreaComYearFrom ? c.YearFrom : year,
|
|
||||||
YearTo = c.YearTo,
|
YearTo = c.YearTo,
|
||||||
}));
|
})));
|
||||||
|
|
||||||
foreach (var ac in areaComs)
|
foreach (var ac in areaComs)
|
||||||
ac.YearTo = year - 1;
|
ac.YearTo = year - 1;
|
||||||
@@ -725,18 +707,20 @@ namespace Elwig.Services {
|
|||||||
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
|
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var l = (await ctx.Members.FindAsync(mgnr))!;
|
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||||
|
var l = await ctx.FetchMembers(mgnr).SingleAsync();
|
||||||
if (deletePaymentData) {
|
if (deletePaymentData) {
|
||||||
ctx.RemoveRange(l.Credits);
|
await ctx.Credits.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
if (deleteDeliveries) {
|
if (deleteDeliveries) {
|
||||||
ctx.RemoveRange(l.Deliveries);
|
await ctx.Deliveries.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
if (deleteAreaComs) {
|
if (deleteAreaComs) {
|
||||||
ctx.RemoveRange(l.AreaCommitments);
|
await ctx.AreaCommitments.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
ctx.Remove(l);
|
ctx.Remove(l);
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
await tx.CommitAsync();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,9 +214,7 @@ namespace Elwig.Services {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await PaymentVariantSummary.Initialize(v.Year, v.AvNr);
|
||||||
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
|
|
||||||
using var doc = new PaymentVariantSummary((await ctx.PaymentVariants.FindAsync(v.Year, v.AvNr))!, data);
|
|
||||||
await Utils.ExportDocument(doc, mode);
|
await Utils.ExportDocument(doc, mode);
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
@@ -365,21 +363,21 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
public static async Task Calculate(int year, int avnr) {
|
public static async Task Calculate(int year, int avnr) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
var b = new BillingVariant(year, avnr);
|
var b = await BillingVariant.Create(year, avnr);
|
||||||
await b.Calculate();
|
await b.Calculate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task Commit(int year, int avnr) {
|
public static async Task Commit(int year, int avnr) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
var b = new BillingVariant(year, avnr);
|
var b = await BillingVariant.Create(year, avnr);
|
||||||
await b.Commit();
|
await b.Commit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task Revert(int year, int avnr) {
|
public static async Task Revert(int year, int avnr) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
var b = new BillingVariant(year, avnr);
|
var b = await BillingVariant.Create(year, avnr);
|
||||||
await b.Revert();
|
await b.Revert();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace Elwig.Services {
|
|||||||
public static class SyncService {
|
public static class SyncService {
|
||||||
|
|
||||||
public static readonly Expression<Func<Member, bool>> ChangedMembers = (m) => ((m.XTime == null && m.MTime > 1751328000) || m.MTime > m.XTime) && (m.ITime == null || m.MTime > m.ITime);
|
public static readonly Expression<Func<Member, bool>> ChangedMembers = (m) => ((m.XTime == null && m.MTime > 1751328000) || m.MTime > m.XTime) && (m.ITime == null || m.MTime > m.ITime);
|
||||||
|
public static readonly Expression<Func<AreaComContract, bool>> ChangedAreaComContracts = (c) => ((c.XTime == null && c.MTime > 1751328000) || c.MTime > c.XTime) && (c.ITime == null || c.MTime > c.ITime);
|
||||||
public static readonly Expression<Func<Delivery, bool>> ChangedDeliveries = (d) => ((d.XTime == null && d.MTime > 1751328000) || d.MTime > d.XTime) && (d.ITime == null || d.MTime > d.ITime);
|
public static readonly Expression<Func<Delivery, bool>> ChangedDeliveries = (d) => ((d.XTime == null && d.MTime > 1751328000) || d.MTime > d.XTime) && (d.ITime == null || d.MTime > d.ITime);
|
||||||
|
|
||||||
public static async Task Upload(string url, string username, string password, IQueryable<Member> query, IEnumerable<string> filterNames) {
|
public static async Task Upload(string url, string username, string password, IQueryable<Member> query, IEnumerable<string> filterNames) {
|
||||||
@@ -24,17 +25,14 @@ namespace Elwig.Services {
|
|||||||
var path = Path.Combine(App.TempPath, filename);
|
var path = Path.Combine(App.TempPath, filename);
|
||||||
var members = await query
|
var members = await query
|
||||||
.OrderBy(m => m.MgNr)
|
.OrderBy(m => m.MgNr)
|
||||||
.Include(m => m.BillingAddress)
|
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.Include(m => m.DefaultWbKg!.Gl)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var areaComs = await query
|
var areaComs = await query
|
||||||
.SelectMany(m => m.AreaCommitments)
|
.SelectMany(m => m.AreaCommitments)
|
||||||
.OrderBy(c => c.MgNr).ThenBy(c => c.FbNr)
|
.Select(c => c.Contract).Distinct()
|
||||||
.Include(c => c.Rd)
|
.OrderBy(c => c.FbNr)
|
||||||
.Include(c => c.Kg.Gl)
|
.Include(c => c.Revisions)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var wbKgs = members
|
var wbKgs = members
|
||||||
.Where(m => m.DefaultWbKg != null)
|
.Where(m => m.DefaultWbKg != null)
|
||||||
@@ -50,7 +48,7 @@ namespace Elwig.Services {
|
|||||||
var exportedAt = DateTime.Now;
|
var exportedAt = DateTime.Now;
|
||||||
await ElwigData.Export(path, members, areaComs, wbKgs, filterNames);
|
await ElwigData.Export(path, members, areaComs, wbKgs, filterNames);
|
||||||
await Utils.UploadExportData(path, url, username, password);
|
await Utils.UploadExportData(path, url, username, password);
|
||||||
await UpdateExportedAt(members, [], exportedAt);
|
await UpdateExportedAt(members, areaComs, [], exportedAt);
|
||||||
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!", "Mitglieder hochgeladen",
|
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!", "Mitglieder hochgeladen",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
}
|
}
|
||||||
@@ -70,10 +68,7 @@ namespace Elwig.Services {
|
|||||||
var list = await query
|
var list = await query
|
||||||
.Select(p => p.Delivery)
|
.Select(p => p.Delivery)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Kg!.Gl)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var wbKgs = list
|
var wbKgs = list
|
||||||
.SelectMany(d => d.Parts)
|
.SelectMany(d => d.Parts)
|
||||||
@@ -89,7 +84,7 @@ namespace Elwig.Services {
|
|||||||
var exportedAt = DateTime.Now;
|
var exportedAt = DateTime.Now;
|
||||||
await ElwigData.Export(path, list, wbKgs, filterNames);
|
await ElwigData.Export(path, list, wbKgs, filterNames);
|
||||||
await Utils.UploadExportData(path, url, username, password);
|
await Utils.UploadExportData(path, url, username, password);
|
||||||
await UpdateExportedAt([], list, exportedAt);
|
await UpdateExportedAt([], [], list, exportedAt);
|
||||||
MessageBox.Show($"Hochladen von {list.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochgeladen",
|
MessageBox.Show($"Hochladen von {list.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochgeladen",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
}
|
}
|
||||||
@@ -106,32 +101,24 @@ namespace Elwig.Services {
|
|||||||
try {
|
try {
|
||||||
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
|
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
|
||||||
List<Member> members;
|
List<Member> members;
|
||||||
List<AreaCom> areaComs;
|
List<AreaComContract> areaComs;
|
||||||
List<Delivery> deliveries;
|
List<Delivery> deliveries;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
members = await ctx.Members
|
members = await ctx.Members
|
||||||
.Where(ChangedMembers)
|
.Where(ChangedMembers)
|
||||||
.Include(m => m.BillingAddress)
|
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.Include(m => m.DefaultWbKg!.Gl)
|
|
||||||
.OrderBy(m => m.MgNr)
|
.OrderBy(m => m.MgNr)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
areaComs = await ctx.Members
|
areaComs = await ctx.AreaCommitmentContracts
|
||||||
.Where(ChangedMembers)
|
.Where(ChangedAreaComContracts)
|
||||||
.SelectMany(m => m.AreaCommitments)
|
.Include(c => c.Revisions)
|
||||||
.Include(c => c.Rd)
|
.OrderBy(c => c.FbNr)
|
||||||
.Include(c => c.Kg.Gl)
|
|
||||||
.OrderBy(c => c.MgNr).ThenBy(c => c.FbNr)
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
deliveries = await ctx.Deliveries
|
deliveries = await ctx.Deliveries
|
||||||
.Where(ChangedDeliveries)
|
.Where(ChangedDeliveries)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Kg).ThenInclude(k => k!.Gl)
|
|
||||||
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString).ThenBy(d => d.LsNr)
|
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString).ThenBy(d => d.LsNr)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
var wbKgs = members
|
var wbKgs = members
|
||||||
@@ -151,13 +138,13 @@ namespace Elwig.Services {
|
|||||||
var exportedAt = DateTime.Now;
|
var exportedAt = DateTime.Now;
|
||||||
await (new ElwigData.ElwigExport {
|
await (new ElwigData.ElwigExport {
|
||||||
Members = (members, ["geändert seit letztem Export"]),
|
Members = (members, ["geändert seit letztem Export"]),
|
||||||
AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
|
AreaComs = (areaComs, ["geändert seit letztem Export"]),
|
||||||
Deliveries = (deliveries, ["geändert seit letzem Export"]),
|
Deliveries = (deliveries, ["geändert seit letzem Export"]),
|
||||||
WbKgs = (wbKgs, ["von exportierten Mitgliedern, Flächenbindungen und Lieferungen"]),
|
WbKgs = (wbKgs, ["von exportierten Mitgliedern, Flächenbindungen und Lieferungen"]),
|
||||||
}).Export(path);
|
}).Export(path);
|
||||||
await Utils.UploadExportData(path, url, username, password);
|
await Utils.UploadExportData(path, url, username, password);
|
||||||
await UpdateExportedAt(members, deliveries, exportedAt);
|
await UpdateExportedAt(members, areaComs, deliveries, exportedAt);
|
||||||
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern und {deliveries.Count:N0} Lieferungen erfolgreich!", "Mitglieder und Lieferungen hochladen",
|
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern, {areaComs.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!", "Mitglieder und Lieferungen hochladen",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
}
|
}
|
||||||
} catch (HttpRequestException exc) {
|
} catch (HttpRequestException exc) {
|
||||||
@@ -176,11 +163,8 @@ namespace Elwig.Services {
|
|||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var deliveries = await ctx.Deliveries
|
var deliveries = await ctx.Deliveries
|
||||||
.Where(d => d.Year == year && d.ZwstId == App.ZwstId)
|
.Where(d => d.Year == year && d.ZwstId == App.ZwstId)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Kg).ThenInclude(k => k!.Gl)
|
|
||||||
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString).ThenBy(d => d.LsNr)
|
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString).ThenBy(d => d.LsNr)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var wbKgs = deliveries
|
var wbKgs = deliveries
|
||||||
.SelectMany(d => d.Parts)
|
.SelectMany(d => d.Parts)
|
||||||
@@ -195,7 +179,7 @@ namespace Elwig.Services {
|
|||||||
var exportedAt = DateTime.Now;
|
var exportedAt = DateTime.Now;
|
||||||
await ElwigData.Export(path, deliveries, wbKgs, [$"{year}", $"Zweigstelle {App.BranchName}"]);
|
await ElwigData.Export(path, deliveries, wbKgs, [$"{year}", $"Zweigstelle {App.BranchName}"]);
|
||||||
await Utils.UploadExportData(path, url, username, password);
|
await Utils.UploadExportData(path, url, username, password);
|
||||||
await UpdateExportedAt([], deliveries, exportedAt);
|
await UpdateExportedAt([], [], deliveries, exportedAt);
|
||||||
MessageBox.Show($"Hochladen von {deliveries.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochladen",
|
MessageBox.Show($"Hochladen von {deliveries.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochladen",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
}
|
}
|
||||||
@@ -251,19 +235,21 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task UpdateExportedAt(IEnumerable<Member> member, IEnumerable<Delivery> deliveries, DateTime dateTime) {
|
private static async Task UpdateExportedAt(IEnumerable<Member> member, IEnumerable<AreaComContract> contracts, IEnumerable<Delivery> deliveries, DateTime dateTime) {
|
||||||
var timestamp = ((DateTimeOffset)dateTime.ToUniversalTime()).ToUnixTimeSeconds();
|
var timestamp = ((DateTimeOffset)dateTime.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
var mgnrs = string.Join(",", member.Select(m => $"{m.MgNr}").Append("0"));
|
var mgnrs = string.Join(",", member.Select(m => $"{m.MgNr}").Append("0"));
|
||||||
|
var fbnrs = string.Join(",", contracts.Select(c => $"{c.FbNr}").Append("0"));
|
||||||
var dids = string.Join(",", deliveries.Select(d => $"({d.Year},{d.DId})").Append("(0,0)"));
|
var dids = string.Join(",", deliveries.Select(d => $"({d.Year},{d.DId})").Append("(0,0)"));
|
||||||
using (var cnx = await AppDbContext.ConnectAsync()) {
|
using (var cnx = await AppDbContext.ConnectAsync()) {
|
||||||
await cnx.ExecuteBatch($"""
|
await cnx.ExecuteBatch($"""
|
||||||
BEGIN;
|
BEGIN;
|
||||||
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
UPDATE member SET xtime = {timestamp} WHERE mgnr IN ({mgnrs});
|
UPDATE member SET xtime = {timestamp} WHERE mgnr IN ({mgnrs});
|
||||||
UPDATE area_commitment SET xtime = {timestamp} WHERE mgnr IN ({mgnrs});
|
UPDATE area_commitment_contract SET xtime = {timestamp} WHERE fbnr IN ({fbnrs});
|
||||||
UPDATE delivery SET xtime = {timestamp} WHERE (year, did) IN ({dids});
|
UPDATE area_commitment SET xtime = {timestamp} WHERE fbnr IN ({fbnrs});
|
||||||
UPDATE delivery_part SET xtime = {timestamp} WHERE (year, did) IN ({dids});
|
UPDATE delivery SET xtime = {timestamp} WHERE (year, did) IN ({dids});
|
||||||
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
UPDATE delivery_part SET xtime = {timestamp} WHERE (year, did) IN ({dids});
|
||||||
|
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
COMMIT;
|
COMMIT;
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@@ -272,7 +258,7 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
||||||
try {
|
try {
|
||||||
return await ctx.Members.AnyAsync(ChangedMembers) || await ctx.Deliveries.AnyAsync(ChangedDeliveries) || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
return await ctx.Members.Where(ChangedMembers).AnyAsync() || await ctx.AreaCommitmentContracts.Where(ChangedAreaComContracts).AnyAsync() || await ctx.Deliveries.Where(ChangedDeliveries).AnyAsync() || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ namespace Elwig.ViewModels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _showOnlyActiveAreaComs;
|
private string? _filterSeasonString;
|
||||||
|
public int? FilterSeason {
|
||||||
|
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||||
|
set => FilterSeasonString = $"{value}";
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _fbNrString;
|
private string? _fbNrString;
|
||||||
@@ -46,6 +50,8 @@ namespace Elwig.ViewModels {
|
|||||||
get => int.TryParse(YearToString, out var year) ? year : null;
|
get => int.TryParse(YearToString, out var year) ? year : null;
|
||||||
set => YearToString = $"{value}";
|
set => YearToString = $"{value}";
|
||||||
}
|
}
|
||||||
|
[ObservableProperty]
|
||||||
|
private string? _period;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AreaComType? _areaComType;
|
private AreaComType? _areaComType;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace Elwig.ViewModels {
|
|||||||
public partial class MemberAdminViewModel : ObservableObject {
|
public partial class MemberAdminViewModel : ObservableObject {
|
||||||
|
|
||||||
public int? TransferPredecessorAreaComs = null;
|
public int? TransferPredecessorAreaComs = null;
|
||||||
public bool MaintainAreaComYearFrom = false;
|
|
||||||
public int? CancelAreaComs = null;
|
public int? CancelAreaComs = null;
|
||||||
|
|
||||||
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
|
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
|
||||||
@@ -21,7 +20,7 @@ namespace Elwig.ViewModels {
|
|||||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _showOnlyActiveMembers;
|
private bool _showOnlyActiveMembers = true;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Member? _selectedMember;
|
private Member? _selectedMember;
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
<Bold>Entwickler:</Bold> Lorenz Stechauner, Thomas Hilscher<LineBreak/>
|
<Bold>Entwickler:</Bold> Lorenz Stechauner, Thomas Hilscher<LineBreak/>
|
||||||
<Bold>Kontakt:</Bold> <Hyperlink NavigateUri="mailto:lorenz.stechauner@necronda.net" RequestNavigate="Hyperlink_RequestNavigate">lorenz.stechauner@necronda.net</Hyperlink>, <Hyperlink NavigateUri="mailto:thomas.hilscher@gmail.com" RequestNavigate="Hyperlink_RequestNavigate">thomas.hilscher@gmail.com</Hyperlink><LineBreak/>
|
<Bold>Kontakt:</Bold> <Hyperlink NavigateUri="mailto:lorenz.stechauner@necronda.net" RequestNavigate="Hyperlink_RequestNavigate">lorenz.stechauner@necronda.net</Hyperlink>, <Hyperlink NavigateUri="mailto:thomas.hilscher@gmail.com" RequestNavigate="Hyperlink_RequestNavigate">thomas.hilscher@gmail.com</Hyperlink><LineBreak/>
|
||||||
<Bold>Quellcode:</Bold> <Hyperlink NavigateUri="https://git.necronda.net/winzer/elwig" RequestNavigate="Hyperlink_RequestNavigate">https://git.necronda.net/winzer/elwig</Hyperlink><LineBreak/>
|
<Bold>Quellcode:</Bold> <Hyperlink NavigateUri="https://git.necronda.net/winzer/elwig" RequestNavigate="Hyperlink_RequestNavigate">https://git.necronda.net/winzer/elwig</Hyperlink><LineBreak/>
|
||||||
<Bold>Entwicklungszeitraum:</Bold> 2022–2025<LineBreak/>
|
<Bold>Entwicklungszeitraum:</Bold> 2022–2026<LineBreak/>
|
||||||
<LineBreak/>
|
<LineBreak/>
|
||||||
<Bold>Verwendete Technologien:</Bold><LineBreak/>
|
<Bold>Verwendete Technologien:</Bold><LineBreak/>
|
||||||
Programmiersprache: C#<LineBreak/>
|
Programmiersprache: C#<LineBreak/>
|
||||||
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
||||||
Datenbank: <Hyperlink NavigateUri="https://sqlite.org/" RequestNavigate="Hyperlink_RequestNavigate">SQLite</Hyperlink><LineBreak/>
|
Datenbank: <Hyperlink NavigateUri="https://sqlite.org/" RequestNavigate="Hyperlink_RequestNavigate">SQLite</Hyperlink><LineBreak/>
|
||||||
PDF-Erstellung: <Hyperlink NavigateUri="https://itextpdf.com/" RequestNavigate="Hyperlink_RequestNavigate">iText</Hyperlink>, <Hyperlink NavigateUri="https://github.com/toddams/RazorLight" RequestNavigate="Hyperlink_RequestNavigate">RazorLight</Hyperlink>, <Hyperlink NavigateUri="https://github.com/bblanchon/pdfium-binaries" RequestNavigate="Hyperlink_RequestNavigate">Pdfium</Hyperlink><LineBreak/>
|
PDF-Erstellung: <Hyperlink NavigateUri="https://itextpdf.com/" RequestNavigate="Hyperlink_RequestNavigate">iText</Hyperlink>, <Hyperlink NavigateUri="https://github.com/bblanchon/pdfium-binaries" RequestNavigate="Hyperlink_RequestNavigate">Pdfium</Hyperlink><LineBreak/>
|
||||||
Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink>
|
Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ namespace Elwig.Windows {
|
|||||||
cb.SelectionChanged += ComboBox_SelectionChanged;
|
cb.SelectionChanged += ComboBox_SelectionChanged;
|
||||||
foreach (var lb in ListBoxInputs)
|
foreach (var lb in ListBoxInputs)
|
||||||
lb.SelectionChanged += ComboBox_SelectionChanged;
|
lb.SelectionChanged += ComboBox_SelectionChanged;
|
||||||
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClosing(object? sender, CancelEventArgs evt) {
|
private void OnClosing(object? sender, CancelEventArgs evt) {
|
||||||
@@ -349,7 +350,6 @@ namespace Elwig.Windows {
|
|||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
list = await ctx.PlzDestinations
|
list = await ctx.PlzDestinations
|
||||||
.Where(p => p.Plz == plz)
|
.Where(p => p.Plz == plz)
|
||||||
.Include(p => p.Ort)
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
Title="{Binding Title}" Height="600" MinHeight="450" Width="1000" MinWidth="860"
|
Title="{Binding Title}" Height="600" MinHeight="550" Width="1000" MinWidth="860">
|
||||||
Loaded="Window_Loaded">
|
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:AreaComAdminViewModel/>
|
<vm:AreaComAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
@@ -57,7 +56,7 @@
|
|||||||
<RowDefinition Height="24"/>
|
<RowDefinition Height="24"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="3*" MinWidth="500"/>
|
<ColumnDefinition Width="2*" MinWidth="500"/>
|
||||||
<ColumnDefinition Width="5"/>
|
<ColumnDefinition Width="5"/>
|
||||||
<ColumnDefinition Width="*" MinWidth="280"/>
|
<ColumnDefinition Width="*" MinWidth="280"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
@@ -78,7 +77,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBox x:Name="SearchInput" Text="{Binding SearchQuery, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<TextBox x:Name="SearchInput" Text="{Binding SearchQuery, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Grid.ColumnSpan="3" Margin="5,5,190,0" IsReadOnly="False"
|
Grid.ColumnSpan="3" Margin="5,5,66,0" IsReadOnly="False"
|
||||||
TextChanged="SearchInput_TextChanged">
|
TextChanged="SearchInput_TextChanged">
|
||||||
<TextBox.ToolTip>
|
<TextBox.ToolTip>
|
||||||
<TextBlock>
|
<TextBlock>
|
||||||
@@ -94,9 +93,10 @@
|
|||||||
</TextBlock>
|
</TextBlock>
|
||||||
</TextBox.ToolTip>
|
</TextBox.ToolTip>
|
||||||
</TextBox>
|
</TextBox>
|
||||||
<CheckBox x:Name="ActiveAreaCommitmentInput" Content="Nur laufende anzeigen (2020)" IsChecked="{Binding ShowOnlyActiveAreaComs}"
|
<ctrl:IntegerUpDown x:Name="SeasonInput" Text="{Binding FilterSeasonString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Checked="ActiveAreaCommitmentInput_Changed" Unchecked="ActiveAreaCommitmentInput_Changed"
|
Grid.ColumnSpan="3" Height="25" Width="56" FontSize="14" Minimum="1900" Maximum="9999"
|
||||||
HorizontalAlignment="Right" Margin="0,10,10,0" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"/>
|
Margin="0,5,5,0" VerticalAlignment="Top" HorizontalAlignment="Right"
|
||||||
|
TextChanged="SeasonInput_TextChanged"/>
|
||||||
|
|
||||||
<DataGrid x:Name="AreaCommitmentList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single"
|
<DataGrid x:Name="AreaCommitmentList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single"
|
||||||
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" SelectionChanged="AreaCommitmentList_SelectionChanged" Grid.Column="0" Grid.Row="1"
|
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" SelectionChanged="AreaCommitmentList_SelectionChanged" Grid.Column="0" Grid.Row="1"
|
||||||
@@ -110,25 +110,24 @@
|
|||||||
</DataGridTextColumn.CellStyle>
|
</DataGridTextColumn.CellStyle>
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="130"/>
|
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="130"/>
|
||||||
<DataGridTextColumn Header="Sorte" Binding="{Binding AreaComType.WineVar.SortId}" Width="50">
|
<DataGridTextColumn Header="Sorte" Binding="{Binding Latest.AreaComType.VtrgId}" Width="50">
|
||||||
<DataGridTextColumn.CellStyle>
|
<DataGridTextColumn.CellStyle>
|
||||||
<Style>
|
<Style>
|
||||||
<Setter Property="TextBlock.Foreground" Value="{Binding AreaComType.WineVar.Color}"/>
|
<Setter Property="TextBlock.Foreground" Value="{Binding Latest.AreaComType.WineVar.Color}"/>
|
||||||
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.CellStyle>
|
</DataGridTextColumn.CellStyle>
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
<DataGridTextColumn Header="Fläche" Binding="{Binding Area, StringFormat='{}{0:N0} m² '}" Width="80">
|
<DataGridTextColumn Header="Fläche" Binding="{Binding Latest.Area, StringFormat='{}{0:N0} m² '}" Width="80">
|
||||||
<DataGridTextColumn.CellStyle>
|
<DataGridTextColumn.CellStyle>
|
||||||
<Style>
|
<Style>
|
||||||
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
|
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.CellStyle>
|
</DataGridTextColumn.CellStyle>
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
<DataGridTextColumn Header="Attribut" Binding="{Binding AreaComType.WineAttr.Name}" Width="100"/>
|
|
||||||
<DataGridTextColumn Header="Ried" Binding="{Binding Rd.Name}" Width="130"/>
|
<DataGridTextColumn Header="Ried" Binding="{Binding Rd.Name}" Width="130"/>
|
||||||
<DataGridTextColumn Header="Parzelle" Binding="{Binding GstNr}" Width="130"/>
|
<DataGridTextColumn Header="Parzelle" Binding="{Binding Latest.GstNr}" Width="130"/>
|
||||||
<DataGridTextColumn Header="Bewirt." Binding="{Binding WineCult.Name}" Width="60"/>
|
<DataGridTextColumn Header="Bewirt." Binding="{Binding Latest.WineCult.Name}" Width="60"/>
|
||||||
<DataGridTextColumn Header="Von" Binding="{Binding YearFrom}" Width="48"/>
|
<DataGridTextColumn Header="Von" Binding="{Binding YearFrom}" Width="48"/>
|
||||||
<DataGridTextColumn Header="Bis" Binding="{Binding YearTo}" Width="48"/>
|
<DataGridTextColumn Header="Bis" Binding="{Binding YearTo}" Width="48"/>
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
@@ -177,91 +176,119 @@
|
|||||||
|
|
||||||
<Grid Grid.Column="2" Grid.Row="1">
|
<Grid Grid.Column="2" Grid.Row="1">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="1.125*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="1*"/>
|
<RowDefinition Height="230"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<GroupBox Header="Vertrag" Grid.Column="2" Grid.Row="0" Grid.RowSpan="1" Margin="5,5,5,5">
|
<GroupBox Header="Vertrag" Grid.Row="0" Margin="5,5,5,5">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="80"/>
|
<ColumnDefinition Width="80"/>
|
||||||
<ColumnDefinition Width="48"/>
|
<ColumnDefinition Width="60"/>
|
||||||
<ColumnDefinition Width="60"/>
|
<ColumnDefinition Width="60"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Label Content="MgNr.:" Margin="10,10,0,0" Grid.Column="0"/>
|
<Label Content="FB-Nr.:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||||
<TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="False"
|
|
||||||
Margin="0,10,0,0" Width="48" HorizontalAlignment="Left" Grid.Column="1" TextAlignment="Right"/>
|
|
||||||
|
|
||||||
<Label Content="FbNr.:" Margin="10,10,0,0" Grid.Column="2"/>
|
|
||||||
<TextBox x:Name="FbNrInput" Text="{Binding FbNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<TextBox x:Name="FbNrInput" Text="{Binding FbNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Margin="0,10,10,0" Width="56" HorizontalAlignment="Left" Grid.Column="3" TextAlignment="Right"
|
Margin="0,10,0,0" Width="56" HorizontalAlignment="Left" Grid.Column="1" TextAlignment="Right"
|
||||||
TextChanged="FbNrInput_TextChanged" LostFocus="FbNrInput_LostFocus"/>
|
TextChanged="FbNrInput_TextChanged" LostFocus="FbNrInput_LostFocus"/>
|
||||||
|
|
||||||
<Label Content="Zeitraum:" Margin="10,40,0,0" Grid.Column="0"/>
|
<Label Content="Laufzeit:" Margin="10,10,0,0" Grid.Column="2"/>
|
||||||
<TextBox x:Name="YearFromInput" Text="{Binding YearFromString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<TextBlock x:Name="Period" Text="{Binding Period}"
|
||||||
Margin="0,40,10,0" Width="40" HorizontalAlignment="Left" Grid.Column="1" Grid.ColumnSpan="2" TextAlignment="Right"
|
Margin="0,14,10,0" Grid.Column="3" TextWrapping="NoWrap" VerticalAlignment="Top"/>
|
||||||
TextChanged="IntegerInput_TextChanged"/>
|
|
||||||
<Label Content="–" Grid.Column="1" Grid.ColumnSpan="3" Margin="45,40,0,0"/>
|
|
||||||
<TextBox x:Name="YearToInput" Text="{Binding YearToString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
|
||||||
Margin="60,40,10,0" Width="40" HorizontalAlignment="Left" Grid.Column="1" Grid.ColumnSpan="3" TextAlignment="Right"
|
|
||||||
TextChanged="IntegerInput_TextChanged"/>
|
|
||||||
|
|
||||||
<Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
|
<Label Content="KG:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||||
<ComboBox x:Name="AreaComTypeInput" SelectedItem="{Binding AreaComType, Mode=TwoWay}" ItemsSource="{Binding AreaComTypeSource, Mode=TwoWay}"
|
<ComboBox x:Name="KgInput" SelectedItem="{Binding Kg, Mode=TwoWay}" ItemsSource="{Binding KgSource, Mode=TwoWay}"
|
||||||
ItemTemplate="{StaticResource AreaCommitmentTypeTemplate}" TextSearch.TextPath="DisplayName"
|
ItemTemplate="{StaticResource KgNrTemplate}" TextSearch.TextPath="Name"
|
||||||
HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1" Grid.ColumnSpan="3"/>
|
HorizontalAlignment="Stretch" Margin="0,40,40,10" Grid.Column="1" Grid.ColumnSpan="3"
|
||||||
<Button x:Name="AreaComTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
SelectionChanged="KgInput_SelectionChanged"/>
|
||||||
Click="AreaComTypeDetailsButton_Click"
|
<Button x:Name="KgDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
||||||
|
Click="KgDetailsButton_Click"
|
||||||
|
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,40,10,10"/>
|
||||||
|
|
||||||
|
<Label Content="Ried:" Margin="10,70,0,0" Grid.Column="0"/>
|
||||||
|
<ComboBox x:Name="RdInput" SelectedItem="{Binding RdObj, Mode=TwoWay}" ItemsSource="{Binding RdSource, Mode=TwoWay}"
|
||||||
|
DisplayMemberPath="Name" TextSearch.TextPath="Name" IsEditable="True"
|
||||||
|
HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1" Grid.ColumnSpan="3"
|
||||||
|
SelectionChanged="RdInput_SelectionChanged"/>
|
||||||
|
<Button x:Name="RdAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0,0,0,0" IsEnabled="False"
|
||||||
|
Click="RdAddButton_Click"
|
||||||
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
|
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
|
||||||
|
|
||||||
<Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
|
<Label Content="Anmerkung:" Margin="10,100,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
|
||||||
<ComboBox x:Name="WineCultivationInput" SelectedItem="{Binding WineCultObj, Mode=TwoWay}" ItemsSource="{Binding WineCultSource, Mode=TwoWay}"
|
|
||||||
DisplayMemberPath="Name" TextSearch.TextPath="Name"
|
|
||||||
HorizontalAlignment="Stretch" Margin="0,100,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
|
||||||
|
|
||||||
<Label Content="Anmerkung:" Margin="10,130,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
|
|
||||||
<TextBox x:Name="CommentInput" Text="{Binding Comment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<TextBox x:Name="CommentInput" Text="{Binding Comment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
TextChanged="TextBox_TextChanged"
|
TextChanged="TextBox_TextChanged"
|
||||||
HorizontalAlignment="Stretch" Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
HorizontalAlignment="Stretch" Margin="0,100,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
||||||
|
|
||||||
|
<ListBox x:Name="RevisionList" Grid.ColumnSpan="4" Margin="5,135,5,5"
|
||||||
|
SelectionChanged="RevisionList_SelectionChanged">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding YearFrom}" Width="28" TextAlignment="Right" Margin="0,0,0,0"/>
|
||||||
|
<TextBlock Text="–" TextAlignment="Center" Margin="0,0,0,0"/>
|
||||||
|
<TextBlock Text="{Binding YearTo}" Width="28" TextAlignment="Left" Margin="0,0,0,0"/>
|
||||||
|
<TextBlock Text="{Binding VtrgId}" Width="40" TextAlignment="Center" Foreground="{Binding AreaComType.WineVar.Color}"/>
|
||||||
|
<TextBlock Text="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/>
|
||||||
|
<TextBlock Text="{Binding Member.AdministrativeName}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Lage" Grid.Column="2" Grid.Row="1" Grid.RowSpan="1" Margin="5,5,5,10">
|
<GroupBox Header="Revision" Grid.Row="1" Margin="5,5,5,10">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="80"/>
|
<ColumnDefinition Width="80"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Label Content="KG:" Margin="10,10,0,0" Grid.Column="0"/>
|
<Label Content="Mitglied:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||||
<ComboBox x:Name="KgInput" SelectedItem="{Binding Kg, Mode=TwoWay}" ItemsSource="{Binding KgSource, Mode=TwoWay}"
|
<TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
ItemTemplate="{StaticResource KgNrTemplate}" TextSearch.TextPath="Name"
|
Width="48" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" TextAlignment="Right"
|
||||||
HorizontalAlignment="Stretch" Margin="0,10,40,10" Grid.Column="1"
|
TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus"/>
|
||||||
SelectionChanged="KgInput_SelectionChanged"/>
|
<ComboBox x:Name="MemberInput"
|
||||||
<Button x:Name="KgDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
Grid.Column="1" Margin="53,10,40,10" IsEditable="True"
|
||||||
Click="KgDetailsButton_Click"
|
ItemTemplate="{StaticResource MemberAdminNameTemplate}" TextSearch.TextPath="AdministrativeName"
|
||||||
Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,10,10,10"/>
|
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||||
|
<Button x:Name="MemberReferenceButton" Grid.Column="1" Height="25" Width="25" FontFamily="Segoe MDL2 Assets" Content="" Padding="0,0,0,0"
|
||||||
|
Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Right" ToolTip="Zu Mitglied springen"
|
||||||
|
Click="MemberReferenceButton_Click"/>
|
||||||
|
|
||||||
<Label Content="Ried:" Margin="10,40,0,0" Grid.Column="0"/>
|
<Label Content="Laufzeit:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||||
<ComboBox x:Name="RdInput" SelectedItem="{Binding RdObj, Mode=TwoWay}" ItemsSource="{Binding RdSource, Mode=TwoWay}"
|
<TextBox x:Name="YearFromInput" Text="{Binding YearFromString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
DisplayMemberPath="Name" TextSearch.TextPath="Name" IsEditable="True"
|
Margin="0,40,10,0" Width="40" HorizontalAlignment="Left" Grid.Column="1" TextAlignment="Right"
|
||||||
HorizontalAlignment="Stretch" Margin="0,40,40,10" Grid.Column="1"
|
TextChanged="IntegerInput_TextChanged"/>
|
||||||
SelectionChanged="RdInput_SelectionChanged"/>
|
<Label Content="–" Grid.Column="1" Margin="45,40,0,0"/>
|
||||||
<Button x:Name="RdAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0,0,0,0" IsEnabled="False"
|
<TextBox x:Name="YearToInput" Text="{Binding YearToString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Click="RdAddButton_Click"
|
Margin="60,40,10,0" Width="40" HorizontalAlignment="Left" Grid.Column="1" TextAlignment="Right"
|
||||||
Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,40,10,10"/>
|
TextChanged="IntegerInput_TextChanged"/>
|
||||||
|
|
||||||
<Label Content="Parzelle(n):" Margin="10,70,0,0" Grid.Column="0"/>
|
<Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0"/>
|
||||||
<TextBox x:Name="GstNrInput" Text="{Binding GstNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<ComboBox x:Name="AreaComTypeInput" SelectedItem="{Binding AreaComType, Mode=TwoWay}" ItemsSource="{Binding AreaComTypeSource, Mode=TwoWay}"
|
||||||
Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Stretch"
|
ItemTemplate="{StaticResource AreaCommitmentTypeTemplate}" TextSearch.TextPath="DisplayName"
|
||||||
TextChanged="TextBox_TextChanged"/>
|
HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1"/>
|
||||||
|
<Button x:Name="AreaComTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
||||||
|
Click="AreaComTypeDetailsButton_Click"
|
||||||
|
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
|
||||||
|
|
||||||
<Label Content="Fläche:" Margin="10,100,0,0" Grid.Column="0"/>
|
<Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0"/>
|
||||||
|
<ComboBox x:Name="WineCultivationInput" SelectedItem="{Binding WineCultObj, Mode=TwoWay}" ItemsSource="{Binding WineCultSource, Mode=TwoWay}"
|
||||||
|
DisplayMemberPath="Name" TextSearch.TextPath="Name"
|
||||||
|
HorizontalAlignment="Stretch" Margin="0,100,10,0" Grid.Column="1"/>
|
||||||
|
|
||||||
|
<Label Content="Fläche:" Margin="10,130,0,0" Grid.Column="0"/>
|
||||||
<ctrl:UnitTextBox x:Name="AreaInput" Unit="m²" Text="{Binding AreaString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<ctrl:UnitTextBox x:Name="AreaInput" Unit="m²" Text="{Binding AreaString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
TextChanged="IntegerInput_TextChanged"
|
TextChanged="IntegerInput_TextChanged"
|
||||||
Grid.Column="1" Width="70" Margin="0,100,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
Grid.Column="1" Width="70" Margin="0,130,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
|
|
||||||
|
<Label Content="Parzelle(n):" Margin="10,160,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="GstNrInput" Text="{Binding GstNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Margin="0,160,10,0" Grid.Column="1" HorizontalAlignment="Stretch"
|
||||||
|
TextChanged="TextBox_TextChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -25,23 +25,18 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||||
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||||
ExemptInputs = [
|
ExemptInputs = [
|
||||||
MgNrInput, AreaCommitmentList, NewAreaCommitmentButton,
|
AreaCommitmentList, RevisionList,
|
||||||
EditAreaCommitmentButton, DeleteAreaCommitmentButton, SaveButton,
|
NewAreaCommitmentButton, EditAreaCommitmentButton, DeleteAreaCommitmentButton, SaveButton,
|
||||||
ResetButton, CancelButton, SearchInput, ActiveAreaCommitmentInput
|
ResetButton, CancelButton, SearchInput, SeasonInput
|
||||||
];
|
];
|
||||||
RequiredInputs = [
|
RequiredInputs = [
|
||||||
FbNrInput, YearFromInput, KgInput, RdInput,
|
FbNrInput, MgNrInput, MemberInput, YearFromInput, KgInput, RdInput,
|
||||||
GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput
|
GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput
|
||||||
];
|
];
|
||||||
|
|
||||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||||
ActiveAreaCommitmentInput.Content = ((string)ActiveAreaCommitmentInput.Content).Replace("2020", $"{Utils.CurrentLastSeason}");
|
ViewModel.FilterSeason = Utils.CurrentYear;
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
|
||||||
ActiveAreaCommitmentInput.IsChecked = true;
|
|
||||||
LockInputs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
|
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
|
||||||
@@ -52,40 +47,49 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
using var ctx = new AppDbContext();
|
var vm = ViewModel;
|
||||||
var (_, areaComQuery, filter) = await ViewModel.GetFilters(ctx);
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
var areaComs = await areaComQuery
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
.Include(a => a.Kg.AtKg)
|
var query = (vm.SearchQuery, vm.FilterSeason);
|
||||||
.Include(a => a.Rd!.Kg.AtKg)
|
var (filter, contracts, areaComs, areaComCount, stat) = await Task.Run(async () => {
|
||||||
.Include(a => a.WineCult)
|
using var ctx = new AppDbContext();
|
||||||
.Include(a => a.AreaComType.WineAttr)
|
var (_, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
||||||
.Include(a => a.AreaComType.WineVar)
|
var contracts = await contractQuery
|
||||||
.ToListAsync();
|
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
||||||
|
.ToListAsync();
|
||||||
|
var areaComs = await areaComQuery.ToListAsync();
|
||||||
|
|
||||||
if (filter.Count > 0 && areaComs.Count > 0) {
|
if (filter.Count > 0 && contracts.Count > 0) {
|
||||||
var dict = areaComs.AsParallel()
|
var dict = contracts.AsParallel()
|
||||||
.ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter))
|
.ToDictionary(d => d, d => d.SearchScore(vm.TextFilter))
|
||||||
.OrderByDescending(c => c.Value);
|
.OrderByDescending(c => c.Value);
|
||||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||||
areaComs = dict
|
contracts = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)
|
.Select(a => a.Key)];
|
||||||
.ToList();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(AreaCommitmentList, areaComs,
|
var areaComCount = await areaComQuery.CountAsync();
|
||||||
AreaCommitmentList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
var season = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||||
|
var stat = await AreaComService.GenerateToolTipData(areaComQuery, season?.MaxKgPerHa ?? 10_000);
|
||||||
|
|
||||||
|
return (filter, contracts, areaComs, areaComCount, stat);
|
||||||
|
});
|
||||||
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
|
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason)) return;
|
||||||
|
|
||||||
|
ControlUtils.RenewItemsSource(AreaCommitmentList, contracts,
|
||||||
|
AreaCommitmentList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
|
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
ViewModel.StatusAreaCommitments = $"{await areaComQuery.CountAsync():N0}";
|
ViewModel.StatusAreaCommitments = $"{areaComCount:N0}";
|
||||||
var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year));
|
var (text, gridData) = stat;
|
||||||
var (text, gridData) = await AreaComService.GenerateToolTipData(areaComQuery, s?.MaxKgPerHa ?? 10_000);
|
|
||||||
ViewModel.StatusArea = text;
|
ViewModel.StatusArea = text;
|
||||||
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
|
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
|
||||||
} else {
|
} else {
|
||||||
ViewModel.StatusAreaCommitments = $"{areaComs.Count:N0}";
|
ViewModel.StatusAreaCommitments = $"{contracts.Count:N0}";
|
||||||
ViewModel.StatusArea = $"{areaComs.Select(a => a.Area).Sum():N0} m²";
|
ViewModel.StatusArea = $"{areaComs.Sum(a => a.Area):N0} m²";
|
||||||
ViewModel.StatusAreaToolTip = null;
|
ViewModel.StatusAreaToolTip = null;
|
||||||
}
|
}
|
||||||
var groups = areaComs.GroupBy(a => $"{a.AreaComType.SortId}{a.AreaComType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
var groups = areaComs.GroupBy(a => $"{a.AreaComType.SortId}{a.AreaComType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
||||||
@@ -94,12 +98,25 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.StatusContracts += $" ({string.Join(", ", groups.Select(g => g.Key))})";
|
ViewModel.StatusContracts += $" ({string.Join(", ", groups.Select(g => g.Key))})";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task RefreshRevisions() {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
if (AreaCommitmentList.SelectedItem is AreaComContract c) {
|
||||||
|
ControlUtils.RenewItemsSource(RevisionList, c.Revisions.OrderByDescending(p => p.RevNr).ToList(), RevisionList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||||
|
} else {
|
||||||
|
RevisionList.ItemsSource = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void RefreshInputs(bool validate = false) {
|
private void RefreshInputs(bool validate = false) {
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
if (AreaCommitmentList.SelectedItem is AreaCom a) {
|
if (RevisionList.SelectedItem is AreaCom a) {
|
||||||
EditAreaCommitmentButton.IsEnabled = true;
|
EditAreaCommitmentButton.IsEnabled = true;
|
||||||
DeleteAreaCommitmentButton.IsEnabled = true;
|
DeleteAreaCommitmentButton.IsEnabled = true;
|
||||||
FillInputs(a);
|
FillInputs(a);
|
||||||
|
} else if (AreaCommitmentList.SelectedItem is AreaComContract c) {
|
||||||
|
EditAreaCommitmentButton.IsEnabled = true;
|
||||||
|
DeleteAreaCommitmentButton.IsEnabled = true;
|
||||||
|
FillInputs(c);
|
||||||
} else {
|
} else {
|
||||||
EditAreaCommitmentButton.IsEnabled = false;
|
EditAreaCommitmentButton.IsEnabled = false;
|
||||||
DeleteAreaCommitmentButton.IsEnabled = false;
|
DeleteAreaCommitmentButton.IsEnabled = false;
|
||||||
@@ -111,7 +128,15 @@ namespace Elwig.Windows {
|
|||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FillInputs(AreaComContract c) {
|
||||||
|
ClearOriginalValues();
|
||||||
|
ClearDefaultValues();
|
||||||
|
ViewModel.FillInputs(c);
|
||||||
|
FinishInputFilling();
|
||||||
|
}
|
||||||
|
|
||||||
private void FillInputs(AreaCom a) {
|
private void FillInputs(AreaCom a) {
|
||||||
|
FillInputs(a.Contract);
|
||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
ViewModel.FillInputs(a);
|
ViewModel.FillInputs(a);
|
||||||
@@ -126,10 +151,15 @@ namespace Elwig.Windows {
|
|||||||
ValidateRequiredInputs();
|
ValidateRequiredInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new protected void ClearInputs(bool validate = false) {
|
||||||
|
ViewModel.ClearInputs();
|
||||||
|
base.ClearInputs(validate);
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
await base.OnRenewContext(ctx);
|
await base.OnRenewContext(ctx);
|
||||||
|
|
||||||
if (await ctx.Members.FindAsync(ViewModel.FilterMember.MgNr) is not Member m) {
|
if (await ctx.FetchMembers(ViewModel.FilterMember.MgNr).SingleOrDefaultAsync() is not Member m) {
|
||||||
Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -146,9 +176,8 @@ namespace Elwig.Windows {
|
|||||||
.Include(c => c.WineAttr)
|
.Include(c => c.WineAttr)
|
||||||
.OrderBy(v => v.VtrgId)
|
.OrderBy(v => v.VtrgId)
|
||||||
.ToListAsync());
|
.ToListAsync());
|
||||||
var cultList = await ctx.WineCultivations
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: true).ToListAsync());
|
||||||
.OrderBy(c => c.Name)
|
var cultList = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||||
.Cast<object>().ToListAsync();
|
|
||||||
cultList.Insert(0, new NullItem());
|
cultList.Insert(0, new NullItem());
|
||||||
ControlUtils.RenewItemsSource(WineCultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(WineCultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
@@ -164,6 +193,7 @@ namespace Elwig.Windows {
|
|||||||
IsCreating = true;
|
IsCreating = true;
|
||||||
AreaCommitmentList.IsEnabled = false;
|
AreaCommitmentList.IsEnabled = false;
|
||||||
AreaCommitmentList.SelectedItem = null;
|
AreaCommitmentList.SelectedItem = null;
|
||||||
|
RevisionList.IsEnabled = false;
|
||||||
HideNewEditDeleteButtons();
|
HideNewEditDeleteButtons();
|
||||||
ShowSaveResetCancelButtons();
|
ShowSaveResetCancelButtons();
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
@@ -184,6 +214,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
IsEditing = true;
|
IsEditing = true;
|
||||||
AreaCommitmentList.IsEnabled = false;
|
AreaCommitmentList.IsEnabled = false;
|
||||||
|
RevisionList.IsEnabled = false;
|
||||||
|
|
||||||
HideNewEditDeleteButtons();
|
HideNewEditDeleteButtons();
|
||||||
ShowSaveResetCancelButtons();
|
ShowSaveResetCancelButtons();
|
||||||
@@ -198,10 +229,10 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) {
|
private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||||
if (AreaCommitmentList.SelectedItem is not AreaCom a)
|
if (RevisionList.SelectedItem is not AreaCom a)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, true);
|
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, true, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||||
if (d.ShowDialog() != true)
|
if (d.ShowDialog() != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -209,7 +240,7 @@ namespace Elwig.Windows {
|
|||||||
try {
|
try {
|
||||||
if (d.YearTo is int yearTo) {
|
if (d.YearTo is int yearTo) {
|
||||||
ViewModel.YearTo = yearTo;
|
ViewModel.YearTo = yearTo;
|
||||||
await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr);
|
await ViewModel.UpdateAreaCommitment(a.FbNr, a.RevNr);
|
||||||
} else {
|
} else {
|
||||||
await AreaComService.DeleteAreaCom(a.FbNr);
|
await AreaComService.DeleteAreaCom(a.FbNr);
|
||||||
}
|
}
|
||||||
@@ -232,42 +263,38 @@ namespace Elwig.Windows {
|
|||||||
SaveButton.IsEnabled = false;
|
SaveButton.IsEnabled = false;
|
||||||
|
|
||||||
int? yearTo = null;
|
int? yearTo = null;
|
||||||
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput)) {
|
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput) || InputHasChanged(MgNrInput)) {
|
||||||
var a = (AreaCommitmentList.SelectedItem as AreaCom)!;
|
var a = (RevisionList.SelectedItem as AreaCom)!;
|
||||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false);
|
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||||
if (d.ShowDialog() != true)
|
if (d.ShowDialog() != true) {
|
||||||
|
SaveButton.IsEnabled = true;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
yearTo = d.YearTo;
|
yearTo = d.YearTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fbnr;
|
int fbnr, revnr;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
try {
|
try {
|
||||||
AreaCom? temp = null;
|
AreaCom? temp = null;
|
||||||
if (yearTo != null && (!ViewModel.YearTo.HasValue || yearTo < ViewModel.YearTo)) {
|
if (yearTo != null && (!ViewModel.YearTo.HasValue || yearTo < ViewModel.YearTo)) {
|
||||||
temp = new AreaCom {
|
temp = new AreaCom {
|
||||||
FbNr = ViewModel.FbNr!.Value,
|
|
||||||
MgNr = ViewModel.MgNr!.Value,
|
MgNr = ViewModel.MgNr!.Value,
|
||||||
YearFrom = ViewModel.YearFrom,
|
YearFrom = ViewModel.YearFrom,
|
||||||
YearTo = ViewModel.YearTo,
|
YearTo = ViewModel.YearTo,
|
||||||
VtrgId = ViewModel.AreaComType!.VtrgId,
|
VtrgId = ViewModel.AreaComType!.VtrgId,
|
||||||
CultId = ViewModel.WineCult?.CultId,
|
CultId = ViewModel.WineCult?.CultId,
|
||||||
Comment = ViewModel.Comment,
|
|
||||||
KgNr = ViewModel.Kg!.KgNr,
|
|
||||||
RdNr = ViewModel.Rd?.RdNr,
|
|
||||||
GstNr = ViewModel.GstNr?.Trim() ?? "-",
|
GstNr = ViewModel.GstNr?.Trim() ?? "-",
|
||||||
Area = ViewModel.Area!.Value,
|
Area = ViewModel.Area!.Value,
|
||||||
};
|
};
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
ViewModel.YearTo = yearTo;
|
ViewModel.YearTo = yearTo;
|
||||||
}
|
}
|
||||||
fbnr = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr);
|
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaComContract)?.FbNr, (RevisionList.SelectedItem as AreaCom)?.RevNr);
|
||||||
if (temp is AreaCom t) {
|
if (temp is AreaCom t) {
|
||||||
await ViewModel.InitInputs();
|
|
||||||
t.FbNr = ViewModel.FbNr!.Value;
|
|
||||||
t.YearFrom = yearTo + 1;
|
t.YearFrom = yearTo + 1;
|
||||||
ViewModel.FillInputs(t);
|
ViewModel.FillInputs(t);
|
||||||
fbnr = await ViewModel.UpdateAreaCommitment(null);
|
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaComContract)?.FbNr, null);
|
||||||
}
|
}
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
@@ -282,16 +309,18 @@ namespace Elwig.Windows {
|
|||||||
IsEditing = false;
|
IsEditing = false;
|
||||||
IsCreating = false;
|
IsCreating = false;
|
||||||
AreaCommitmentList.IsEnabled = true;
|
AreaCommitmentList.IsEnabled = true;
|
||||||
|
RevisionList.IsEnabled = true;
|
||||||
HideSaveResetCancelButtons();
|
HideSaveResetCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
UnlockSearchInputs();
|
UnlockSearchInputs();
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await RefreshList();
|
await EnsureContextRenewed();
|
||||||
RefreshInputs();
|
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault());
|
ViewModel.FilterSeason = ViewModel.YearTo ?? ViewModel.YearFrom ?? ViewModel.FilterSeason;
|
||||||
|
ControlUtils.SelectItemWithPk(AreaCommitmentList, fbnr);
|
||||||
|
ControlUtils.SelectItemWithPk(RevisionList, fbnr, revnr);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ShortcutReset() {
|
protected override void ShortcutReset() {
|
||||||
@@ -313,6 +342,7 @@ namespace Elwig.Windows {
|
|||||||
IsEditing = false;
|
IsEditing = false;
|
||||||
IsCreating = false;
|
IsCreating = false;
|
||||||
AreaCommitmentList.IsEnabled = true;
|
AreaCommitmentList.IsEnabled = true;
|
||||||
|
RevisionList.IsEnabled = true;
|
||||||
HideSaveResetCancelButtons();
|
HideSaveResetCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
@@ -374,34 +404,65 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private void LockSearchInputs() {
|
private void LockSearchInputs() {
|
||||||
SearchInput.IsEnabled = false;
|
SearchInput.IsEnabled = false;
|
||||||
ActiveAreaCommitmentInput.IsEnabled = false;
|
SeasonInput.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnlockSearchInputs() {
|
private void UnlockSearchInputs() {
|
||||||
SearchInput.IsEnabled = true;
|
SearchInput.IsEnabled = true;
|
||||||
ActiveAreaCommitmentInput.IsEnabled = true;
|
SeasonInput.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AreaCommitmentList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
private async void AreaCommitmentList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
||||||
if (AreaCommitmentList.SelectedItem != null)
|
if (AreaCommitmentList.SelectedItem != null)
|
||||||
AreaCommitmentList.ScrollIntoView(AreaCommitmentList.SelectedItem);
|
AreaCommitmentList.ScrollIntoView(AreaCommitmentList.SelectedItem);
|
||||||
RefreshInputs();
|
await RefreshRevisions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AttributesInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
private void RevisionList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
|
RefreshInputs();
|
||||||
|
if (RevisionList.SelectedItem is AreaCom c) {
|
||||||
|
EditAreaCommitmentButton.IsEnabled = true;
|
||||||
|
} else {
|
||||||
|
EditAreaCommitmentButton.IsEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MgNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
var valid = InputTextChanged((TextBox)sender, Validator.CheckMgNr);
|
||||||
|
var text = MgNrInput.Text;
|
||||||
|
var caret = MgNrInput.CaretIndex;
|
||||||
|
ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null);
|
||||||
|
MgNrInput.Text = text;
|
||||||
|
MgNrInput.CaretIndex = caret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
||||||
|
var valid = InputLostFocus((TextBox)sender, Validator.CheckMgNr);
|
||||||
|
ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MemberInput_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
|
var m = MemberInput.SelectedItem as Member;
|
||||||
|
ViewModel.MgNr = m?.MgNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ActiveAreaCommitmentInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void ActiveAreaCommitmentInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
|
var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
|
||||||
binding?.UpdateSource();
|
binding?.UpdateSource();
|
||||||
await RefreshList(true);
|
await RefreshList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded || ViewModel.FilterSeason == null) return;
|
||||||
|
await RefreshList();
|
||||||
|
}
|
||||||
|
|
||||||
private void KgInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
private void KgInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
||||||
if (KgInput.SelectedItem is AT_Kg kg) {
|
if (KgInput.SelectedItem is AT_Kg kg) {
|
||||||
var rdList = kg.WbKg!.Rds.OrderBy(r => r.Name).Cast<object>().ToList();
|
var rdList = kg.WbKg!.Rds.OrderBy(r => r.Name).Cast<object>().ToList();
|
||||||
@@ -439,12 +500,12 @@ namespace Elwig.Windows {
|
|||||||
RdInput.SelectedIndex = s.Count();
|
RdInput.SelectedIndex = s.Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaCom?, ValidationResult> checker) {
|
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaComContract?, ValidationResult> checker) {
|
||||||
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaCom)AreaCommitmentList.SelectedItem));
|
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaComContract)AreaCommitmentList.SelectedItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaCom?, ValidationResult> checker, string? msg = null) {
|
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaComContract?, ValidationResult> checker, string? msg = null) {
|
||||||
InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaCom)AreaCommitmentList.SelectedItem), msg);
|
InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaComContract)AreaCommitmentList.SelectedItem), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FbNrInput_TextChanged(object sender, RoutedEventArgs evt) {
|
private void FbNrInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||||
@@ -454,5 +515,10 @@ namespace Elwig.Windows {
|
|||||||
private void FbNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
private void FbNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
||||||
InputLostFocus((TextBox)sender, Validator.CheckFbNr);
|
InputLostFocus((TextBox)sender, Validator.CheckFbNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
if (MemberInput.SelectedItem is not Member m) return;
|
||||||
|
App.FocusMember(m.MgNr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Stammdaten - Elwig" Height="520" MinHeight="400" Width="860" MinWidth="810"
|
Title="Stammdaten - Elwig" Height="520" MinHeight="400" Width="860" MinWidth="810">
|
||||||
Loaded="Window_Loaded">
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Label">
|
<Style TargetType="Label">
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ namespace Elwig.Windows {
|
|||||||
private async Task AreaCommitmentTypesInitEditing(AppDbContext ctx) {
|
private async Task AreaCommitmentTypesInitEditing(AppDbContext ctx) {
|
||||||
_actList = new(await ctx.AreaCommitmentTypes
|
_actList = new(await ctx.AreaCommitmentTypes
|
||||||
.OrderBy(v => v.VtrgId)
|
.OrderBy(v => v.VtrgId)
|
||||||
.Include(t => t.WineVar)
|
|
||||||
.Include(t => t.WineAttr)
|
|
||||||
.ToListAsync());
|
.ToListAsync());
|
||||||
_acts = _actList.ToDictionary(v => v.VtrgId, v => (string?)v.VtrgId);
|
_acts = _actList.ToDictionary(v => v.VtrgId, v => (string?)v.VtrgId);
|
||||||
_actIds = _actList.ToDictionary(v => v, v => v.VtrgId);
|
_actIds = _actList.ToDictionary(v => v, v => v.VtrgId);
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ namespace Elwig.Windows {
|
|||||||
private bool _branchUpdate = false;
|
private bool _branchUpdate = false;
|
||||||
|
|
||||||
private async Task BranchesInitEditing(AppDbContext ctx) {
|
private async Task BranchesInitEditing(AppDbContext ctx) {
|
||||||
_branchList = new(await ctx.Branches
|
_branchList = new(await ctx.FetchBranches().ToListAsync());
|
||||||
.OrderBy(b => b.Name)
|
|
||||||
.Include(b => b.PostalDest!.AtPlz)
|
|
||||||
.ToListAsync());
|
|
||||||
_branches = _branchList.ToDictionary(b => b.ZwstId, b => (string?)b.ZwstId);
|
_branches = _branchList.ToDictionary(b => b.ZwstId, b => (string?)b.ZwstId);
|
||||||
_branchIds = _branchList.ToDictionary(b => b, b => b.ZwstId);
|
_branchIds = _branchList.ToDictionary(b => b, b => b.ZwstId);
|
||||||
ControlUtils.RenewItemsSource(BranchList, _branchList);
|
ControlUtils.RenewItemsSource(BranchList, _branchList);
|
||||||
@@ -30,10 +27,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task BranchesFinishEditing(AppDbContext ctx) {
|
private async Task BranchesFinishEditing(AppDbContext ctx) {
|
||||||
ControlUtils.RenewItemsSource(BranchList, await ctx.Branches
|
ControlUtils.RenewItemsSource(BranchList, await ctx.FetchBranches().ToListAsync());
|
||||||
.OrderBy(b => b.Name)
|
|
||||||
.Include(b => b.PostalDest!.AtPlz)
|
|
||||||
.ToListAsync());
|
|
||||||
_branchList = null;
|
_branchList = null;
|
||||||
_branches = null;
|
_branches = null;
|
||||||
_branchIds = null;
|
_branchIds = null;
|
||||||
@@ -47,9 +41,10 @@ namespace Elwig.Windows {
|
|||||||
if (!_branchChanged || _branchList == null || _branches == null || _branchIds == null)
|
if (!_branchChanged || _branchList == null || _branches == null || _branchIds == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var (zwstid, _) in _branches.Where(b => b.Value == null)) {
|
var tx = await ctx.Database.BeginTransactionAsync();
|
||||||
ctx.Remove(ctx.Branches.Find(zwstid)!);
|
var deleteZwstIds = _branches.Where(b => b.Value == null).Select(b => b.Key).ToList();
|
||||||
}
|
await ctx.Branches.Where(b => deleteZwstIds.Contains(b.ZwstId)).ExecuteDeleteAsync();
|
||||||
|
|
||||||
foreach (var (branch, old) in _branchIds) {
|
foreach (var (branch, old) in _branchIds) {
|
||||||
branch.ZwstId = old;
|
branch.ZwstId = old;
|
||||||
}
|
}
|
||||||
@@ -61,13 +56,13 @@ namespace Elwig.Windows {
|
|||||||
foreach (var (old, zwstid) in _branches.Where(b => b.Value != null)) {
|
foreach (var (old, zwstid) in _branches.Where(b => b.Value != null)) {
|
||||||
await ctx.Database.ExecuteSqlAsync($"UPDATE branch SET zwstid = {zwstid} WHERE zwstid = {old}");
|
await ctx.Database.ExecuteSqlAsync($"UPDATE branch SET zwstid = {zwstid} WHERE zwstid = {old}");
|
||||||
}
|
}
|
||||||
await ctx.SaveChangesAsync();
|
|
||||||
|
|
||||||
foreach (var branch in _branchList.Where(b => !_branchIds.ContainsKey(b))) {
|
foreach (var branch in _branchList.Where(b => !_branchIds.ContainsKey(b))) {
|
||||||
if (branch.ZwstId == null) continue;
|
if (branch.ZwstId == null) continue;
|
||||||
ctx.Add(branch);
|
ctx.Add(branch);
|
||||||
}
|
}
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
await tx.CommitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BranchList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
private void BranchList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ namespace Elwig.Windows {
|
|||||||
private async Task ModifiersInitEditing(AppDbContext ctx) {
|
private async Task ModifiersInitEditing(AppDbContext ctx) {
|
||||||
SeasonList.IsEnabled = false;
|
SeasonList.IsEnabled = false;
|
||||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||||
_modList = new(await ctx.Modifiers
|
_modList = new(await ctx.FetchModifiers(year ?? 0).ToListAsync());
|
||||||
.Where(m => m.Year == year)
|
|
||||||
.OrderBy(m => m.Ordering)
|
|
||||||
.ToListAsync());
|
|
||||||
_mods = _modList.ToDictionary(m => m.ModId, m => (string?)m.ModId);
|
_mods = _modList.ToDictionary(m => m.ModId, m => (string?)m.ModId);
|
||||||
_modIds = _modList.ToDictionary(m => m, m => m.ModId);
|
_modIds = _modList.ToDictionary(m => m, m => m.ModId);
|
||||||
ControlUtils.RenewItemsSource(SeasonModifierList, _modList);
|
ControlUtils.RenewItemsSource(SeasonModifierList, _modList);
|
||||||
@@ -34,10 +31,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private async Task ModifiersFinishEditing(AppDbContext ctx) {
|
private async Task ModifiersFinishEditing(AppDbContext ctx) {
|
||||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||||
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.Modifiers
|
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.FetchModifiers(year ?? 0).ToListAsync());
|
||||||
.Where(m => m.Year == year)
|
|
||||||
.OrderBy(m => m.Ordering)
|
|
||||||
.ToListAsync());
|
|
||||||
_modList = null;
|
_modList = null;
|
||||||
_mods = null;
|
_mods = null;
|
||||||
_modIds = null;
|
_modIds = null;
|
||||||
|
|||||||
@@ -19,22 +19,14 @@ namespace Elwig.Windows {
|
|||||||
private async Task SeasonsInitEditing(AppDbContext ctx) {
|
private async Task SeasonsInitEditing(AppDbContext ctx) {
|
||||||
SeasonAddButton.IsEnabled = false;
|
SeasonAddButton.IsEnabled = false;
|
||||||
SeasonRemoveButton.IsEnabled = false;
|
SeasonRemoveButton.IsEnabled = false;
|
||||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.Seasons
|
ControlUtils.RenewItemsSource(SeasonList, await ctx.FetchSeasons(includeModifiers: true).ToListAsync());
|
||||||
.OrderByDescending(s => s.Year)
|
|
||||||
.Include(s => s.Modifiers)
|
|
||||||
.Include(s => s.Currency)
|
|
||||||
.ToListAsync());
|
|
||||||
SeasonList_SelectionChanged(null, null);
|
SeasonList_SelectionChanged(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SeasonsFinishEditing(AppDbContext ctx) {
|
private async Task SeasonsFinishEditing(AppDbContext ctx) {
|
||||||
SeasonAddButton.IsEnabled = true;
|
SeasonAddButton.IsEnabled = true;
|
||||||
SeasonRemoveButton.IsEnabled = true;
|
SeasonRemoveButton.IsEnabled = true;
|
||||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.Seasons
|
ControlUtils.RenewItemsSource(SeasonList, await ctx.FetchSeasons(includeModifiers: true).ToListAsync());
|
||||||
.OrderByDescending(s => s.Year)
|
|
||||||
.Include(s => s.Modifiers)
|
|
||||||
.Include(s => s.Currency)
|
|
||||||
.ToListAsync());
|
|
||||||
_seasonChanged = false;
|
_seasonChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ namespace Elwig.Windows {
|
|||||||
private bool _attrUpdate = false;
|
private bool _attrUpdate = false;
|
||||||
|
|
||||||
private async Task WineAttributesInitEditing(AppDbContext ctx) {
|
private async Task WineAttributesInitEditing(AppDbContext ctx) {
|
||||||
_attrList = new(await ctx.WineAttributes
|
_attrList = new(await ctx.FetchWineAttributes().ToListAsync());
|
||||||
.OrderBy(a => a.Name)
|
|
||||||
.ToListAsync());
|
|
||||||
_attrs = _attrList.ToDictionary(a => a.AttrId, a => (string?)a.AttrId);
|
_attrs = _attrList.ToDictionary(a => a.AttrId, a => (string?)a.AttrId);
|
||||||
_attrIds = _attrList.ToDictionary(a => a, a => a.AttrId);
|
_attrIds = _attrList.ToDictionary(a => a, a => a.AttrId);
|
||||||
ControlUtils.RenewItemsSource(WineAttributeList, _attrList);
|
ControlUtils.RenewItemsSource(WineAttributeList, _attrList);
|
||||||
@@ -29,9 +27,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task WineAttributesFinishEditing(AppDbContext ctx) {
|
private async Task WineAttributesFinishEditing(AppDbContext ctx) {
|
||||||
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.WineAttributes
|
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.FetchWineAttributes().ToListAsync());
|
||||||
.OrderBy(a => a.Name)
|
|
||||||
.ToListAsync());
|
|
||||||
_attrList = null;
|
_attrList = null;
|
||||||
_attrs = null;
|
_attrs = null;
|
||||||
_attrIds = null;
|
_attrIds = null;
|
||||||
@@ -45,9 +41,9 @@ namespace Elwig.Windows {
|
|||||||
if (!_attrChanged || _attrList == null || _attrs == null || _attrIds == null)
|
if (!_attrChanged || _attrList == null || _attrs == null || _attrIds == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var (attrid, _) in _attrs.Where(a => a.Value == null)) {
|
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||||
ctx.Remove(ctx.WineAttributes.Find(attrid)!);
|
var deleteAttrIds = _attrs.Where(a => a.Value == null).Select(a => a.Key).ToList();
|
||||||
}
|
await ctx.WineAttributes.Where(a => deleteAttrIds.Contains(a.AttrId)).ExecuteDeleteAsync();
|
||||||
foreach (var (attr, old) in _attrIds) {
|
foreach (var (attr, old) in _attrIds) {
|
||||||
attr.AttrId = old;
|
attr.AttrId = old;
|
||||||
}
|
}
|
||||||
@@ -61,13 +57,13 @@ namespace Elwig.Windows {
|
|||||||
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment_type SET vtrgid = (sortid || COALESCE(attrid, '') || COALESCE(disc, '')) WHERE attrid = {attrid}");
|
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.Database.ExecuteSqlRawAsync($"UPDATE payment_variant SET data = REPLACE(REPLACE(data, '/{old}\"', '/{attrid}\"'), '/{old}-', '/{attrid}-')");
|
||||||
}
|
}
|
||||||
await ctx.SaveChangesAsync();
|
|
||||||
|
|
||||||
foreach (var attr in _attrList.Where(a => !_attrIds.ContainsKey(a))) {
|
foreach (var attr in _attrList.Where(a => !_attrIds.ContainsKey(a))) {
|
||||||
if (attr.AttrId == null) continue;
|
if (attr.AttrId == null) continue;
|
||||||
ctx.Add(attr);
|
ctx.Add(attr);
|
||||||
}
|
}
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
await tx.CommitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WineAttributeList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
private void WineAttributeList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ namespace Elwig.Windows {
|
|||||||
private bool _cultUpdate = false;
|
private bool _cultUpdate = false;
|
||||||
|
|
||||||
private async Task WineCultivationsInitEditing(AppDbContext ctx) {
|
private async Task WineCultivationsInitEditing(AppDbContext ctx) {
|
||||||
_cultList = new(await ctx.WineCultivations
|
_cultList = new(await ctx.FetchWineCultivations().ToListAsync());
|
||||||
.OrderBy(c => c.Name)
|
|
||||||
.ToListAsync());
|
|
||||||
_cults = _cultList.ToDictionary(c => c.CultId, c => (string?)c.CultId);
|
_cults = _cultList.ToDictionary(c => c.CultId, c => (string?)c.CultId);
|
||||||
_cultIds = _cultList.ToDictionary(c => c, c => c.CultId);
|
_cultIds = _cultList.ToDictionary(c => c, c => c.CultId);
|
||||||
ControlUtils.RenewItemsSource(WineCultivationList, _cultList);
|
ControlUtils.RenewItemsSource(WineCultivationList, _cultList);
|
||||||
@@ -29,9 +27,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task WineCultivationsFinishEditing(AppDbContext ctx) {
|
private async Task WineCultivationsFinishEditing(AppDbContext ctx) {
|
||||||
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.WineCultivations
|
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.FetchWineCultivations().ToListAsync());
|
||||||
.OrderBy(c => c.Name)
|
|
||||||
.ToListAsync());
|
|
||||||
_cultList = null;
|
_cultList = null;
|
||||||
_cults = null;
|
_cults = null;
|
||||||
_cultIds = null;
|
_cultIds = null;
|
||||||
@@ -45,9 +41,9 @@ namespace Elwig.Windows {
|
|||||||
if (!_cultChanged || _cultList == null || _cults == null || _cultIds == null)
|
if (!_cultChanged || _cultList == null || _cults == null || _cultIds == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var (cultid, _) in _cults.Where(c => c.Value == null)) {
|
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||||
ctx.Remove(ctx.WineCultivations.Find(cultid)!);
|
var deleteCultIds = _cults.Where(c => c.Value == null).Select(c => c.Key).ToList();
|
||||||
}
|
await ctx.WineCultivations.Where(c => deleteCultIds.Contains(c.CultId)).ExecuteDeleteAsync();
|
||||||
foreach (var (cult, old) in _cultIds) {
|
foreach (var (cult, old) in _cultIds) {
|
||||||
cult.CultId = old;
|
cult.CultId = old;
|
||||||
}
|
}
|
||||||
@@ -60,13 +56,13 @@ namespace Elwig.Windows {
|
|||||||
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.Database.ExecuteSqlRawAsync($"UPDATE payment_variant SET data = REPLACE(data, '-{old}\"', '-{cultid}\"')");
|
||||||
}
|
}
|
||||||
await ctx.SaveChangesAsync();
|
|
||||||
|
|
||||||
foreach (var cult in _cultList.Where(c => !_cultIds.ContainsKey(c))) {
|
foreach (var cult in _cultList.Where(c => !_cultIds.ContainsKey(c))) {
|
||||||
if (cult.CultId == null) continue;
|
if (cult.CultId == null) continue;
|
||||||
ctx.Add(cult);
|
ctx.Add(cult);
|
||||||
}
|
}
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
await tx.CommitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WineCultivationList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
private void WineCultivationList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
|
|||||||
@@ -153,44 +153,22 @@ namespace Elwig.Windows {
|
|||||||
ParameterExportEbicsAddress.IsEnabled = true;
|
ParameterExportEbicsAddress.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
|
||||||
LockInputs();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
await base.OnRenewContext(ctx);
|
await base.OnRenewContext(ctx);
|
||||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.Seasons
|
ControlUtils.RenewItemsSource(SeasonList, await ctx.FetchSeasons(includeModifiers: true).ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||||
.OrderByDescending(s => s.Year)
|
|
||||||
.Include(s => s.Modifiers)
|
|
||||||
.Include(s => s.Currency)
|
|
||||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
|
||||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||||
ControlUtils.RenewItemsSource(BranchList, await ctx.Branches
|
ControlUtils.RenewItemsSource(BranchList, await ctx.FetchBranches().ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||||
.OrderBy(b => b.Name)
|
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.FetchWineAttributes().ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||||
.Include(b => b.PostalDest!.AtPlz)
|
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineVariantInput, await ctx.FetchWineVarieties().ToListAsync());
|
||||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
var attrList = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||||
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.WineAttributes
|
|
||||||
.OrderBy(a => a.Name)
|
|
||||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
|
||||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineVariantInput, await ctx.WineVarieties
|
|
||||||
.OrderBy(s => s.Name)
|
|
||||||
.ToListAsync());
|
|
||||||
var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
|
||||||
attrList.Insert(0, new NullItem(""));
|
attrList.Insert(0, new NullItem(""));
|
||||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineAttributeInput, attrList);
|
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineAttributeInput, attrList);
|
||||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeList, await ctx.AreaCommitmentTypes
|
ControlUtils.RenewItemsSource(AreaCommitmentTypeList, await ctx.AreaCommitmentTypes
|
||||||
.OrderBy(t => t.VtrgId)
|
.OrderBy(t => t.VtrgId)
|
||||||
.Include(t => t.WineVar)
|
|
||||||
.Include(t => t.WineAttr)
|
|
||||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
|
||||||
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.WineCultivations
|
|
||||||
.OrderBy(c => c.Name)
|
|
||||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
|
||||||
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.Modifiers
|
|
||||||
.Where(m => m.Year == year)
|
|
||||||
.OrderBy(m => m.Ordering)
|
|
||||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||||
|
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.FetchWineCultivations().ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||||
|
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.FetchModifiers(year ?? 0).ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateButtons() {
|
protected override void UpdateButtons() {
|
||||||
@@ -286,7 +264,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +284,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +320,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +408,7 @@ namespace Elwig.Windows {
|
|||||||
private async Task UpdateParameters(int year) {
|
private async Task UpdateParameters(int year) {
|
||||||
try {
|
try {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
if (await ctx.Seasons.FindAsync(year) is not Season s)
|
if (await ctx.FetchSeasons(year).SingleOrDefaultAsync() is not Season s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s.Billing_AllowAttrsIntoLower = ParameterAllowAttrIntoLowerInput.IsChecked ?? false;
|
s.Billing_AllowAttrsIntoLower = ParameterAllowAttrIntoLowerInput.IsChecked ?? false;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Auszahlung - Elwig" Height="700" Width="1500" MinWidth="1000" MinHeight="500"
|
Title="Auszahlung - Elwig" Height="700" Width="1500" MinWidth="1000" MinHeight="500"
|
||||||
Loaded="Window_Loaded"
|
|
||||||
Closing="Window_Closing">
|
Closing="Window_Closing">
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
|
|||||||
@@ -80,9 +80,6 @@ namespace Elwig.Windows {
|
|||||||
LockContext = true;
|
LockContext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||||
if (HasChanged) {
|
if (HasChanged) {
|
||||||
var r = MessageBox.Show("Soll das Fenster wirklich geschlossen werden? Nicht gespeicherte Änderungen werden NICHT übernommen!", "Schließen bestätigen",
|
var r = MessageBox.Show("Soll das Fenster wirklich geschlossen werden? Nicht gespeicherte Änderungen werden NICHT übernommen!", "Schließen bestätigen",
|
||||||
@@ -101,17 +98,17 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private async Task RefreshGraphList(AppDbContext ctx) {
|
private async Task RefreshGraphList(AppDbContext ctx) {
|
||||||
PaymentVar = await ctx.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
PaymentVar = await ctx.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
||||||
Season = await ctx.Seasons.FindAsync(Year) ?? throw new ArgumentException("Season not found");
|
Season = await ctx.FetchSeasons(Year).SingleOrDefaultAsync() ?? throw new ArgumentException("Season not found");
|
||||||
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
||||||
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
||||||
GebundenFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
GebundenFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var data = EditBillingData.FromJson(PaymentVar.Data, Utils.GetVaributes(ctx, Year));
|
var data = EditBillingData.FromJson(PaymentVar.Data, await Utils.GetVaributes(ctx, Year));
|
||||||
var paymentEntries = data.GetPaymentGraphEntries(ctx, Season);
|
var paymentEntries = await data.GetPaymentGraphEntries(ctx, Season);
|
||||||
GraphEntries = [
|
GraphEntries = [
|
||||||
..paymentEntries,
|
..paymentEntries,
|
||||||
..data.GetQualityGraphEntries(ctx, Season, paymentEntries.Any() ? paymentEntries.Max(e => e.Id) : 0)
|
..await data.GetQualityGraphEntries(ctx, Season, paymentEntries.Any() ? paymentEntries.Max(e => e.Id) : 0)
|
||||||
];
|
];
|
||||||
} catch (KeyNotFoundException ex) {
|
} catch (KeyNotFoundException ex) {
|
||||||
var key = ex.Message.Split('\'')[1].Split('\'')[0];
|
var key = ex.Message.Split('\'')[1].Split('\'')[0];
|
||||||
@@ -126,7 +123,7 @@ namespace Elwig.Windows {
|
|||||||
MessageBox.Show("Fehler beim Laden der Auszahlungsvariante:\n\n" + ex.Message, "Fehler",
|
MessageBox.Show("Fehler beim Laden der Auszahlungsvariante:\n\n" + ex.Message, "Fehler",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
Vaributes = Utils.GetVaributeList(ctx, Year);
|
Vaributes = await Utils.GetVaributeList(ctx, Year);
|
||||||
GraphEntries.ForEach(e => {
|
GraphEntries.ForEach(e => {
|
||||||
e.Vaributes.ForEach(v => {
|
e.Vaributes.ForEach(v => {
|
||||||
var found = Vaributes.Find(a => a.Variety?.SortId == v.Variety?.SortId && a.Attribute?.AttrId == v.Attribute?.AttrId && a.Cultivation?.CultId == v.Cultivation?.CultId);
|
var found = Vaributes.Find(a => a.Variety?.SortId == v.Variety?.SortId && a.Attribute?.AttrId == v.Attribute?.AttrId && a.Cultivation?.CultId == v.Cultivation?.CultId);
|
||||||
@@ -645,7 +642,7 @@ namespace Elwig.Windows {
|
|||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var origData = BillingData.FromJson(PaymentVar.Data);
|
var origData = BillingData.FromJson(PaymentVar.Data);
|
||||||
var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(ctx, Year),
|
var data = BillingData.FromGraphEntries(GraphEntries, origData, await Utils.GetVaributes(ctx, Year),
|
||||||
AllVaributesAssigned, AllVaributesAssignedAbgew);
|
AllVaributesAssigned, AllVaributesAssignedAbgew);
|
||||||
|
|
||||||
PaymentVar.Data = data.ToJsonString();
|
PaymentVar.Data = data.ToJsonString();
|
||||||
@@ -663,7 +660,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
var b = new BillingVariant(PaymentVar.Year, PaymentVar.AvNr);
|
var b = await BillingVariant.Create(PaymentVar.Year, PaymentVar.AvNr);
|
||||||
await b.Calculate(false);
|
await b.Calculate(false);
|
||||||
});
|
});
|
||||||
} catch (KeyNotFoundException exc) {
|
} catch (KeyNotFoundException exc) {
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ namespace Elwig.Windows {
|
|||||||
set {
|
set {
|
||||||
_lockContext = value;
|
_lockContext = value;
|
||||||
if (!_lockContext && _renewPending) {
|
if (!_lockContext && _renewPending) {
|
||||||
Dispatcher.BeginInvoke(async () => await RenewContext());
|
Dispatcher.BeginInvoke(async () => await EnsureContextRenewed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool HasContextLoaded { get; private set; }
|
||||||
|
|
||||||
private bool _renewPending = false;
|
private bool _renewPending = false;
|
||||||
|
|
||||||
private readonly RoutedCommand CtrlR = new("CtrlR", typeof(ContextWindow), [new KeyGesture(Key.R, ModifierKeys.Control)]);
|
private readonly RoutedCommand CtrlR = new("CtrlR", typeof(ContextWindow), [new KeyGesture(Key.R, ModifierKeys.Control)]);
|
||||||
@@ -30,26 +32,40 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async void ForceContextReload(object sender, EventArgs evt) {
|
public async void ForceContextReload(object sender, EventArgs evt) {
|
||||||
await HintContextChange();
|
await ForceContextReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task HintContextChange() {
|
public async Task ForceContextReload() {
|
||||||
|
HintContextChange();
|
||||||
|
await TryContextReload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HintContextChange() {
|
||||||
_renewPending = true;
|
_renewPending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task TryContextReload() {
|
||||||
if (LockContext) return;
|
if (LockContext) return;
|
||||||
await RenewContext();
|
await EnsureContextRenewed();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
|
protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
|
||||||
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
await OnRenewContext(ctx);
|
||||||
|
HasContextLoaded = true;
|
||||||
|
await OnInit(ctx);
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task EnsureContextRenewed() {
|
||||||
|
if (!_renewPending) return;
|
||||||
|
_renewPending = false;
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
await OnRenewContext(ctx);
|
await OnRenewContext(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task RenewContext() {
|
virtual protected async Task OnInit(AppDbContext ctx) { }
|
||||||
if (!_renewPending) return;
|
|
||||||
using var ctx = new AppDbContext();
|
|
||||||
await OnRenewContext(ctx);
|
|
||||||
_renewPending = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected Task OnRenewContext(AppDbContext ctx);
|
abstract protected Task OnRenewContext(AppDbContext ctx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="{Binding Title}" Height="720" Width="1150" MinHeight="720" MinWidth="1000"
|
Title="{Binding Title}" Height="720" Width="1150" MinHeight="720" MinWidth="1000">
|
||||||
Loaded="Window_Loaded">
|
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryAdminViewModel/>
|
<vm:DeliveryAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ namespace Elwig.Windows {
|
|||||||
private readonly Button[] WeighingButtons;
|
private readonly Button[] WeighingButtons;
|
||||||
|
|
||||||
private List<WineQualLevel> WineQualityLevels = [];
|
private List<WineQualLevel> WineQualityLevels = [];
|
||||||
|
private Dictionary<int, List<Modifier>> Modifiers = [];
|
||||||
|
|
||||||
public DeliveryAdminWindow(bool receipt = false) {
|
public DeliveryAdminWindow(bool receipt = false) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -122,20 +123,20 @@ namespace Elwig.Windows {
|
|||||||
Menu_Export_UploadSeason.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Export_UploadSeason.IsEnabled = App.Config.SyncUrl != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeliveryAdminWindow(int mgnr) : this() {
|
public DeliveryAdminWindow(int mgnr) :
|
||||||
|
this() {
|
||||||
ViewModel.FilterMember = DeliveryService.GetMember(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
ViewModel.FilterMember = DeliveryService.GetMember(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||||
ViewModel.EnableAllSeasons = true;
|
ViewModel.EnableAllSeasons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
protected override async Task OnInit(AppDbContext ctx) {
|
||||||
|
await base.OnInit(ctx);
|
||||||
OnSecondPassed(null, null);
|
OnSecondPassed(null, null);
|
||||||
SecondsTimer.Start();
|
SecondsTimer.Start();
|
||||||
LockInputs();
|
|
||||||
if (ViewModel.IsReceipt) {
|
if (ViewModel.IsReceipt) {
|
||||||
NewDeliveryButton_Click(null, null);
|
NewDeliveryButton_Click(null, null);
|
||||||
using var ctx = new AppDbContext();
|
if (await ctx.FetchSeasons(Utils.CurrentYear).SingleOrDefaultAsync() == null) {
|
||||||
if (ctx.Seasons.Find(Utils.CurrentYear) == null) {
|
|
||||||
MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n(Stammdaten -> Saisons -> Neu anlegen...)",
|
MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n(Stammdaten -> Saisons -> Neu anlegen...)",
|
||||||
"Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Warning);
|
"Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
}
|
}
|
||||||
@@ -285,17 +286,17 @@ namespace Elwig.Windows {
|
|||||||
await ViewModel.GenerateDeliveryDataList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
|
await ViewModel.GenerateDeliveryDataList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
|
||||||
|
|
||||||
private async void Menu_BulkAction_SetAttribute_Click(object sender, RoutedEventArgs evt) {
|
private async void Menu_BulkAction_SetAttribute_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (sender is not MenuItem item) return;
|
if (IsEditing || IsCreating || sender is not MenuItem item) return;
|
||||||
await ViewModel.BulkSetAttribute(item.Header as string);
|
await ViewModel.BulkSetAttribute(item.Header as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Menu_BulkAction_AddModifier_Click(object sender, RoutedEventArgs evt) {
|
private async void Menu_BulkAction_AddModifier_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (sender is not MenuItem item || item.Header is not string name) return;
|
if (IsEditing || IsCreating || sender is not MenuItem item || item.Header is not string name) return;
|
||||||
await ViewModel.BulkAddModifier(name);
|
await ViewModel.BulkAddModifier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Menu_BulkAction_RemoveModifier_Click(object sender, RoutedEventArgs evt) {
|
private async void Menu_BulkAction_RemoveModifier_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (sender is not MenuItem item || item.Header is not string name) return;
|
if (IsEditing || IsCreating || sender is not MenuItem item || item.Header is not string name) return;
|
||||||
await ViewModel.BulkRemoveModifier(name);
|
await ViewModel.BulkRemoveModifier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,45 +421,55 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
using var ctx = new AppDbContext();
|
var vm = ViewModel;
|
||||||
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await ViewModel.GetFilters(ctx);
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
var deliveries = await deliveryQuery
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterAllSeasons, vm.FilterTodayOnly);
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Attribute)
|
var (filter, deliveries, deliveryPartsNum, varieties, members, stat) = await Task.Run(async () => {
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Cultivation)
|
using var ctx = new AppDbContext();
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Variety)
|
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
||||||
.Include(d => d.Member.EmailAddresses)
|
var deliveries = await deliveryQuery
|
||||||
.AsSplitQuery()
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||||
.ToListAsync();
|
.Include(d => d.Parts).ThenInclude(p => p.Variety)
|
||||||
deliveries.Reverse();
|
.IgnoreAutoIncludes()
|
||||||
|
.AsSplitQuery()
|
||||||
|
.ToListAsync();
|
||||||
|
deliveries.Reverse();
|
||||||
|
|
||||||
if (filter.Count > 0 && deliveries.Count > 0) {
|
if (filter.Count > 0 && deliveries.Count > 0) {
|
||||||
var dict = deliveries.AsParallel()
|
var dict = deliveries.AsParallel()
|
||||||
.ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter))
|
.ToDictionary(d => d, d => d.SearchScore(vm.TextFilter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.DateTime);
|
.ThenBy(a => a.Key.DateTime);
|
||||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||||
deliveries = dict
|
deliveries = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)
|
.Select(a => a.Key)];
|
||||||
.ToList();
|
}
|
||||||
}
|
|
||||||
|
deliveries.ForEach(d => { d.PartFilter = predicate; });
|
||||||
|
|
||||||
|
var deliveryPartsNum = await deliveryPartsQuery.CountAsync();
|
||||||
|
var varieties = await deliveryPartsQuery.Select(d => d.SortId).Distinct().ToListAsync();
|
||||||
|
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
||||||
|
var stat = await DeliveryService.GenerateToolTipData(deliveryPartsQuery);
|
||||||
|
|
||||||
|
return (filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
||||||
|
});
|
||||||
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
|
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterAllSeasons, ViewModel.FilterTodayOnly)) return;
|
||||||
|
|
||||||
deliveries.ForEach(d => { d.PartFilter = predicate; });
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
||||||
DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
await RefreshDeliveryParts();
|
await RefreshDeliveryParts();
|
||||||
|
|
||||||
var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList();
|
|
||||||
ViewModel.StatusMembers = $"{members.Count:N0}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
|
ViewModel.StatusMembers = $"{members.Count:N0}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
|
||||||
ViewModel.StatusDeliveries = $"{deliveries.Count:N0}";
|
ViewModel.StatusDeliveries = $"{deliveries.Count:N0}";
|
||||||
|
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
var deliveryParts = deliveryPartsQuery;
|
ViewModel.StatusDeliveries = $"{deliveries.Count:N0} ({deliveryPartsNum:N0})";
|
||||||
ViewModel.StatusDeliveries = $"{deliveries.Count:N0} ({await deliveryParts.CountAsync():N0})";
|
|
||||||
var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync();
|
|
||||||
ViewModel.StatusVarieties = $"{varieties.Count:N0}" + (varieties.Count > 0 && varieties.Count <= 10 ? $" ({string.Join(", ", varieties)})" : "");
|
ViewModel.StatusVarieties = $"{varieties.Count:N0}" + (varieties.Count > 0 && varieties.Count <= 10 ? $" ({string.Join(", ", varieties)})" : "");
|
||||||
var (wText, wData, gText, gData) = await DeliveryService.GenerateToolTipData(deliveryParts);
|
var (wText, wData, gText, gData) = stat;
|
||||||
ViewModel.StatusWeight = wText;
|
ViewModel.StatusWeight = wText;
|
||||||
ViewModel.StatusGradation = gText;
|
ViewModel.StatusGradation = gText;
|
||||||
(ViewModel.StatusWeightToolTip, ViewModel.StatusGradationToolTip) = DeliveryService.GenerateToolTip(wData, gData);
|
(ViewModel.StatusWeightToolTip, ViewModel.StatusGradationToolTip) = DeliveryService.GenerateToolTip(wData, gData);
|
||||||
@@ -486,7 +497,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
int year = 0;
|
int year = 0;
|
||||||
Menu_Bki_SaveList.Items.Clear();
|
Menu_Bki_SaveList.Items.Clear();
|
||||||
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
|
foreach (var s in await ctx.FetchSeasons().ToListAsync()) {
|
||||||
if (s.Year > year) year = s.Year;
|
if (s.Year > year) year = s.Year;
|
||||||
var i = new MenuItem {
|
var i = new MenuItem {
|
||||||
Header = $"Saison {s.Year}",
|
Header = $"Saison {s.Year}",
|
||||||
@@ -495,6 +506,9 @@ namespace Elwig.Windows {
|
|||||||
Menu_Bki_SaveList.Items.Add(i);
|
Menu_Bki_SaveList.Items.Add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var attributes = await ctx.FetchWineAttributes(!IsCreating).ToListAsync();
|
||||||
|
Modifiers = await ctx.FetchModifiers(null).GroupBy(m => m.Year).ToDictionaryAsync(g => g.Key, g => g.ToList());
|
||||||
|
|
||||||
var font = new FontFamily("Segoe MDL2 Assets");
|
var font = new FontFamily("Segoe MDL2 Assets");
|
||||||
Menu_BulkAction_SetAttribute.Items.Clear();
|
Menu_BulkAction_SetAttribute.Items.Clear();
|
||||||
var noAttr = new MenuItem {
|
var noAttr = new MenuItem {
|
||||||
@@ -503,7 +517,7 @@ namespace Elwig.Windows {
|
|||||||
};
|
};
|
||||||
noAttr.Click += Menu_BulkAction_SetAttribute_Click;
|
noAttr.Click += Menu_BulkAction_SetAttribute_Click;
|
||||||
Menu_BulkAction_SetAttribute.Items.Add(noAttr);
|
Menu_BulkAction_SetAttribute.Items.Add(noAttr);
|
||||||
foreach (var attr in await ctx.WineAttributes.OrderBy(a => a.AttrId).ToListAsync()) {
|
foreach (var attr in attributes) {
|
||||||
var i = new MenuItem {
|
var i = new MenuItem {
|
||||||
Header = attr.Name,
|
Header = attr.Name,
|
||||||
};
|
};
|
||||||
@@ -513,7 +527,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
Menu_BulkAction_AddModifier.Items.Clear();
|
Menu_BulkAction_AddModifier.Items.Clear();
|
||||||
Menu_BulkAction_RemoveModifier.Items.Clear();
|
Menu_BulkAction_RemoveModifier.Items.Clear();
|
||||||
foreach (var mod in await ctx.Modifiers.Where(m => m.Year == year).OrderBy(m => m.ModId).ToListAsync()) {
|
foreach (var mod in Modifiers.GetValueOrDefault(ViewModel.SelectedDelivery?.Year ?? 0, []).Where(m => m.IsActive || !IsCreating)) {
|
||||||
var i1 = new MenuItem {
|
var i1 = new MenuItem {
|
||||||
Header = mod.Name,
|
Header = mod.Name,
|
||||||
};
|
};
|
||||||
@@ -527,44 +541,34 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
var d = DeliveryList.SelectedItem as Delivery;
|
|
||||||
var y = d?.Year ?? ViewModel.FilterSeason;
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: !IsCreating, includeContactInfo: true).ToListAsync());
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
||||||
.Where(m => m.IsActive || !IsCreating)
|
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.FetchWineVarieties().ToListAsync());
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
var attrList = attributes.Cast<object>().ToList();
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ToListAsync());
|
|
||||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
|
|
||||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync());
|
|
||||||
var attrList = await ctx.WineAttributes.Where(a => !IsCreating || a.IsActive).OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
|
||||||
attrList.Insert(0, new NullItem(""));
|
attrList.Insert(0, new NullItem(""));
|
||||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
var cultList = await ctx.WineCultivations.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
var cultList = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||||
cultList.Insert(0, new NullItem(""));
|
cultList.Insert(0, new NullItem(""));
|
||||||
ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
WineQualityLevels = await ctx.WineQualityLevels.ToListAsync();
|
WineQualityLevels = await ctx.FetchWineQualityLevels().ToListAsync();
|
||||||
ControlUtils.RenewItemsSource(WineQualityLevelInput, WineQualityLevels);
|
ControlUtils.RenewItemsSource(WineQualityLevelInput, WineQualityLevels);
|
||||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
ControlUtils.RenewItemsSource(ModifiersInput, Modifiers.GetValueOrDefault(year, []).Where(m => m.IsActive || !IsCreating).ToList());
|
||||||
.Where(m => m.Year == y && (!IsCreating || m.IsActive))
|
var origins = await ctx.WineOrigins.ToListAsync();
|
||||||
.OrderBy(m => m.Ordering)
|
origins.ForEach(o => { origins.FirstOrDefault(p => p.HkId == o.ParentHkId)?.Children.Add(o); });
|
||||||
.Include(m => m.Season.Currency)
|
origins = [.. origins.OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId)];
|
||||||
.ToListAsync());
|
ControlUtils.RenewItemsSource(WineOriginInput, origins);
|
||||||
ControlUtils.RenewItemsSource(WineOriginInput, (await ctx.WineOrigins.ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId));
|
|
||||||
var kgList = (await ctx.Katastralgemeinden
|
var kgList = (await ctx.Katastralgemeinden
|
||||||
.Where(k => k.WbKg != null)
|
.Where(k => k.WbKg != null)
|
||||||
.Include(k => k.WbKg)
|
.Include(k => k.WbKg)
|
||||||
.Include(k => k.Gem.WbGem)
|
.Include(k => k.Gem.WbGem)
|
||||||
.OrderBy(k => k.Name)
|
.OrderBy(k => k.Name)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync()).Cast<object>().ToList();
|
.ToListAsync()).Cast<object>().ToList();
|
||||||
kgList.Insert(0, new NullItem());
|
kgList.Insert(0, new NullItem());
|
||||||
ControlUtils.RenewItemsSource(WineKgInput, kgList);
|
ControlUtils.RenewItemsSource(WineKgInput, kgList);
|
||||||
UpdateRdInput();
|
UpdateRdInput();
|
||||||
if (IsCreating) await UpdateLsNr();
|
if (IsCreating) await UpdateLsNr();
|
||||||
|
|
||||||
await RefreshDeliveryParts();
|
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,30 +580,22 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshDeliveryParts() {
|
private async Task RefreshDeliveryParts() {
|
||||||
using var ctx = new AppDbContext();
|
|
||||||
if (DeliveryList.SelectedItem is Delivery d) {
|
if (DeliveryList.SelectedItem is Delivery d) {
|
||||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
ControlUtils.RenewItemsSource(ModifiersInput, Modifiers.GetValueOrDefault(d.Year, []).Where(m => m.IsActive || !IsCreating).ToList());
|
||||||
.Where(m => m.Year == d.Year && (!IsCreating || m.IsActive))
|
ControlUtils.RenewItemsSource(DeliveryPartList, d.Parts, DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||||
.OrderBy(m => m.Ordering)
|
|
||||||
.Include(m => m.Season.Currency)
|
|
||||||
.ToListAsync());
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryPartList, d.FilteredParts.OrderBy(p => p.DPNr).ToList(), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
|
||||||
} else {
|
} else {
|
||||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
ControlUtils.RenewItemsSource(ModifiersInput, Modifiers.GetValueOrDefault(ViewModel.FilterSeason ?? 0, []).Where(m => m.IsActive || !IsCreating).ToList());
|
||||||
.Where(m => m.Year == ViewModel.FilterSeason && (!IsCreating || m.IsActive))
|
|
||||||
.OrderBy(m => m.Ordering)
|
|
||||||
.Include(m => m.Season.Currency)
|
|
||||||
.ToListAsync());
|
|
||||||
DeliveryPartList.ItemsSource = null;
|
DeliveryPartList.ItemsSource = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshInputs(bool validate = false) {
|
private void RefreshInputs(bool validate = false) {
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
if (DeliveryPartList.SelectedItem is DeliveryPart p) {
|
if (DeliveryList.SelectedItem is Delivery d) {
|
||||||
FillInputs(p);
|
|
||||||
} else if (DeliveryList.SelectedItem is Delivery d) {
|
|
||||||
FillInputs(d);
|
FillInputs(d);
|
||||||
|
if (DeliveryPartList.SelectedItem is DeliveryPart p) {
|
||||||
|
FillInputs(p);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
@@ -617,7 +613,6 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void FillInputs(DeliveryPart p) {
|
private void FillInputs(DeliveryPart p) {
|
||||||
FillInputs(p.Delivery);
|
|
||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
ViewModel.FillInputs(p);
|
ViewModel.FillInputs(p);
|
||||||
@@ -681,17 +676,19 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList(true);
|
await RefreshList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
if (ViewModel.FilterSeason == null || TodayOnlyInput == null || AllSeasonsInput == null) return;
|
if (!HasContextLoaded || ViewModel.FilterSeason == null || TodayOnlyInput == null || AllSeasonsInput == null) return;
|
||||||
TodayOnlyInput.IsChecked = false;
|
TodayOnlyInput.IsChecked = false;
|
||||||
AllSeasonsInput.IsChecked = false;
|
AllSeasonsInput.IsChecked = false;
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
if (TodayOnlyInput.IsChecked == true && AllSeasonsInput.IsChecked == false) {
|
if (TodayOnlyInput.IsChecked == true && AllSeasonsInput.IsChecked == false) {
|
||||||
ViewModel.FilterSeason = Utils.Today.Year;
|
ViewModel.FilterSeason = Utils.Today.Year;
|
||||||
ViewModel.FilterTodayOnly = true;
|
ViewModel.FilterTodayOnly = true;
|
||||||
@@ -700,6 +697,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void AllSeasonsInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void AllSeasonsInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
if (AllSeasonsInput.IsChecked == true) {
|
if (AllSeasonsInput.IsChecked == true) {
|
||||||
SeasonInput.IsEnabled = false;
|
SeasonInput.IsEnabled = false;
|
||||||
ViewModel.FilterSeason = null;
|
ViewModel.FilterSeason = null;
|
||||||
@@ -719,7 +717,7 @@ namespace Elwig.Windows {
|
|||||||
Menu_DeliveryNote_Show.IsEnabled = !IsEditing && !IsCreating;
|
Menu_DeliveryNote_Show.IsEnabled = !IsEditing && !IsCreating;
|
||||||
Menu_DeliveryNote_SavePdf.IsEnabled = !IsEditing && !IsCreating;
|
Menu_DeliveryNote_SavePdf.IsEnabled = !IsEditing && !IsCreating;
|
||||||
Menu_DeliveryNote_Print.IsEnabled = !IsEditing && !IsCreating;
|
Menu_DeliveryNote_Print.IsEnabled = !IsEditing && !IsCreating;
|
||||||
Menu_DeliveryNote_Email.IsEnabled = !IsEditing && !IsCreating && App.Config.Smtp != null && d.Member.EmailAddresses.Count > 0;
|
Menu_DeliveryNote_Email.IsEnabled = !IsEditing && !IsCreating && App.Config.Smtp != null && ViewModel.Member?.EmailAddresses.Count > 0;
|
||||||
Menu_Export_ExportSelected.IsEnabled = !IsEditing && !IsCreating;
|
Menu_Export_ExportSelected.IsEnabled = !IsEditing && !IsCreating;
|
||||||
Menu_Export_UploadSelected.IsEnabled = !IsEditing && !IsCreating && App.Config.SyncUrl != null;
|
Menu_Export_UploadSelected.IsEnabled = !IsEditing && !IsCreating && App.Config.SyncUrl != null;
|
||||||
} else {
|
} else {
|
||||||
@@ -812,13 +810,12 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmptyScale();
|
EmptyScale();
|
||||||
await RefreshList();
|
|
||||||
await RefreshDeliveryParts();
|
await EnsureContextRenewed();
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
ControlUtils.SelectItem(DeliveryList, p?.Delivery);
|
ControlUtils.SelectItemWithPk(DeliveryList, p?.Year, p?.DId);
|
||||||
DeliveryPartList.SelectedItem = null;
|
DeliveryPartList.SelectedItem = null;
|
||||||
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().Last());
|
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().LastOrDefault());
|
||||||
RefreshInputs();
|
|
||||||
InitialInputs();
|
InitialInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,27 +848,22 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmptyScale();
|
EmptyScale();
|
||||||
await RefreshList();
|
|
||||||
await RefreshDeliveryParts();
|
|
||||||
if (p?.Delivery != null) {
|
|
||||||
try {
|
|
||||||
using var ctx = new AppDbContext();
|
|
||||||
using var doc = new DeliveryNote((await ctx.Deliveries.FindAsync(p.Year, p.DId))!, ctx);
|
|
||||||
await doc.Generate();
|
|
||||||
if (App.Config.Debug) {
|
|
||||||
doc.Show();
|
|
||||||
} else {
|
|
||||||
await doc.Print(2);
|
|
||||||
}
|
|
||||||
} catch (Exception exc) {
|
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Utils.RunBackground("Lieferschein drucken", async () => {
|
||||||
|
using var doc = await DeliveryNote.Initialize(p.Year, p.DId);
|
||||||
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
|
if (App.Config.Debug) {
|
||||||
|
doc.Show();
|
||||||
|
} else {
|
||||||
|
await doc.Print(2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await EnsureContextRenewed();
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
DeliveryList.SelectedItem = null;
|
DeliveryList.SelectedItem = null;
|
||||||
await RenewContext();
|
|
||||||
RefreshInputs();
|
|
||||||
InitInputs();
|
InitInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,16 +875,10 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
var attrList = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||||
attrList.Insert(0, new NullItem(""));
|
attrList.Insert(0, new NullItem(""));
|
||||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: !ViewModel.IsReceipt, includeContactInfo: true).ToListAsync());
|
||||||
.Where(m => m.IsActive || !ViewModel.IsReceipt)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ToListAsync());
|
|
||||||
if (DeliveryList.SelectedItem is not Delivery d) {
|
if (DeliveryList.SelectedItem is not Delivery d) {
|
||||||
// switch away from creating mode
|
// switch away from creating mode
|
||||||
IsCreating = false;
|
IsCreating = false;
|
||||||
@@ -902,7 +888,7 @@ namespace Elwig.Windows {
|
|||||||
DisableWeighingButtons();
|
DisableWeighingButtons();
|
||||||
HideFinishNewPartDeliveryCancelButtons();
|
HideFinishNewPartDeliveryCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
await RenewContext();
|
await EnsureContextRenewed();
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
@@ -924,21 +910,11 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.FilterTodayOnly = true;
|
ViewModel.FilterTodayOnly = true;
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var attrList = await ctx.WineAttributes.Where(a => a.IsActive).OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
var attrList = await ctx.FetchWineAttributes(false).Cast<object>().ToListAsync();
|
||||||
attrList.Insert(0, new NullItem(""));
|
attrList.Insert(0, new NullItem(""));
|
||||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
ControlUtils.RenewItemsSource(ModifiersInput, Modifiers.GetValueOrDefault(ViewModel.FilterSeason ?? 0, []).Where(m => m.IsActive).ToList());
|
||||||
.Where(m => m.Year == ViewModel.FilterSeason && m.IsActive)
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: !ViewModel.IsReceipt, includeContactInfo: true).ToListAsync());
|
||||||
.OrderBy(m => m.Ordering)
|
|
||||||
.Include(m => m.Season.Currency)
|
|
||||||
.ToListAsync());
|
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
|
||||||
.Where(m => m.IsActive || !ViewModel.IsReceipt)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ToListAsync());
|
|
||||||
IsCreating = true;
|
IsCreating = true;
|
||||||
DeliveryList.IsEnabled = false;
|
DeliveryList.IsEnabled = false;
|
||||||
DeliveryPartList.IsEnabled = false;
|
DeliveryPartList.IsEnabled = false;
|
||||||
@@ -1082,9 +1058,7 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
UnlockSearchInputs();
|
UnlockSearchInputs();
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await RefreshList();
|
await EnsureContextRenewed();
|
||||||
await RefreshDeliveryParts();
|
|
||||||
RefreshInputs();
|
|
||||||
|
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
DepreciateButton.IsEnabled = true;
|
DepreciateButton.IsEnabled = true;
|
||||||
@@ -1184,6 +1158,9 @@ namespace Elwig.Windows {
|
|||||||
SeasonInput.IsEnabled = false;
|
SeasonInput.IsEnabled = false;
|
||||||
TodayOnlyInput.IsEnabled = false;
|
TodayOnlyInput.IsEnabled = false;
|
||||||
AllSeasonsInput.IsEnabled = false;
|
AllSeasonsInput.IsEnabled = false;
|
||||||
|
Menu_BulkAction_SetAttribute.IsEnabled = false;
|
||||||
|
Menu_BulkAction_AddModifier.IsEnabled = false;
|
||||||
|
Menu_BulkAction_RemoveModifier.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnlockSearchInputs() {
|
private void UnlockSearchInputs() {
|
||||||
@@ -1191,6 +1168,9 @@ namespace Elwig.Windows {
|
|||||||
SeasonInput.IsEnabled = true;
|
SeasonInput.IsEnabled = true;
|
||||||
TodayOnlyInput.IsEnabled = true;
|
TodayOnlyInput.IsEnabled = true;
|
||||||
AllSeasonsInput.IsEnabled = (ViewModel.FilterMember != null);
|
AllSeasonsInput.IsEnabled = (ViewModel.FilterMember != null);
|
||||||
|
Menu_BulkAction_SetAttribute.IsEnabled = true;
|
||||||
|
Menu_BulkAction_AddModifier.IsEnabled = true;
|
||||||
|
Menu_BulkAction_RemoveModifier.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
new protected void UnlockInputs() {
|
new protected void UnlockInputs() {
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Anmeldungen - Elwig" Height="700" Width="980" MinWidth="600" MinHeight="400"
|
Title="Anmeldungen - Elwig" Height="700" Width="980" MinWidth="600" MinHeight="400">
|
||||||
Loaded="Window_Loaded">
|
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryAncmtAdminViewModel/>
|
<vm:DeliveryAncmtAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -36,11 +36,7 @@ namespace Elwig.Windows {
|
|||||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||||
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
|
||||||
ViewModel.FilterOnlyUpcoming = true;
|
ViewModel.FilterOnlyUpcoming = true;
|
||||||
LockInputs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Input_KeyUp(object sender, KeyEventArgs evt) {
|
private void Input_KeyUp(object sender, KeyEventArgs evt) {
|
||||||
@@ -85,7 +81,6 @@ namespace Elwig.Windows {
|
|||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var list = await ctx.DeliverySchedules
|
var list = await ctx.DeliverySchedules
|
||||||
.Where(s => s.Year == ViewModel.FilterSeason)
|
.Where(s => s.Year == ViewModel.FilterSeason)
|
||||||
.Include(s => s.Branch)
|
|
||||||
.OrderBy(s => s.DateString)
|
.OrderBy(s => s.DateString)
|
||||||
.ThenBy(s => s.Branch.Name)
|
.ThenBy(s => s.Branch.Name)
|
||||||
.ThenBy(s => s.Description)
|
.ThenBy(s => s.Description)
|
||||||
@@ -103,36 +98,41 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
using var ctx = new AppDbContext();
|
var vm = ViewModel;
|
||||||
var (_, deliveryAncmtQuery, filter) = await ViewModel.GetFilters(ctx);
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
var deliveryAncmts = await deliveryAncmtQuery
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
.Include(a => a.Member.BillingAddress)
|
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterOnlyUpcoming, vm.FilterOnlyUpcoming);
|
||||||
.Include(a => a.Schedule)
|
var (filter, deliveryAncmts, stat) = await Task.Run(async () => {
|
||||||
.Include(a => a.Variety)
|
using var ctx = new AppDbContext();
|
||||||
.AsSplitQuery()
|
var (_, deliveryAncmtQuery, filter) = await vm.GetFilters(ctx);
|
||||||
.ToListAsync();
|
var deliveryAncmts = await deliveryAncmtQuery.ToListAsync();
|
||||||
|
|
||||||
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
||||||
var dict = deliveryAncmts.AsParallel()
|
var dict = deliveryAncmts.AsParallel()
|
||||||
.ToDictionary(a => a, a => a.SearchScore(filter))
|
.ToDictionary(a => a, a => a.SearchScore(filter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.Schedule.DateString)
|
.ThenBy(a => a.Key.Schedule.DateString)
|
||||||
.ThenBy(a => a.Key.Member.Name)
|
.ThenBy(a => a.Key.Member.Name)
|
||||||
.ThenBy(a => a.Key.Member.GivenName)
|
.ThenBy(a => a.Key.Member.GivenName)
|
||||||
.ThenBy(a => a.Key.Member.MgNr);
|
.ThenBy(a => a.Key.Member.MgNr);
|
||||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||||
deliveryAncmts = dict
|
deliveryAncmts = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)
|
.Select(a => a.Key)];
|
||||||
.ToList();
|
} else {
|
||||||
} else {
|
deliveryAncmts = [.. deliveryAncmts
|
||||||
deliveryAncmts = deliveryAncmts
|
.OrderBy(a => a.Schedule.DateString)
|
||||||
.OrderBy(a => a.Schedule.DateString)
|
.ThenBy(a => a.Member.Name)
|
||||||
.ThenBy(a => a.Member.Name)
|
.ThenBy(a => a.Member.GivenName)
|
||||||
.ThenBy(a => a.Member.GivenName)
|
.ThenBy(a => a.Member.MgNr)];
|
||||||
.ThenBy(a => a.Member.MgNr)
|
}
|
||||||
.ToList();
|
|
||||||
}
|
var stat = await DeliveryAncmtService.GenerateToolTipData(deliveryAncmtQuery);
|
||||||
|
|
||||||
|
return (filter, deliveryAncmts, stat);
|
||||||
|
});
|
||||||
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
|
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterOnlyUpcoming, ViewModel.FilterOnlyUpcoming)) return;
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryAncmtList, deliveryAncmts,
|
ControlUtils.RenewItemsSource(DeliveryAncmtList, deliveryAncmts,
|
||||||
DeliveryAncmtList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryAncmtList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
@@ -141,9 +141,9 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
ViewModel.StatusAncmts = $"{deliveryAncmts.Count:N0}";
|
ViewModel.StatusAncmts = $"{deliveryAncmts.Count:N0}";
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
var (text, grid) = await DeliveryAncmtService.GenerateToolTip(deliveryAncmtQuery);
|
var (text, data) = stat;
|
||||||
ViewModel.StatusWeight = text;
|
ViewModel.StatusWeight = text;
|
||||||
ViewModel.StatusWeightToolTip = grid;
|
ViewModel.StatusWeightToolTip = DeliveryAncmtService.GenerateToolTip(data);
|
||||||
} else {
|
} else {
|
||||||
ViewModel.StatusWeight = $"{deliveryAncmts.Sum(a => a.Weight):N0} kg";
|
ViewModel.StatusWeight = $"{deliveryAncmts.Sum(a => a.Weight):N0} kg";
|
||||||
ViewModel.StatusWeightToolTip = null;
|
ViewModel.StatusWeightToolTip = null;
|
||||||
@@ -177,15 +177,8 @@ namespace Elwig.Windows {
|
|||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
await base.OnRenewContext(ctx);
|
await base.OnRenewContext(ctx);
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: !IsCreating).ToListAsync());
|
||||||
.Where(m => m.IsActive || !IsCreating)
|
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.FetchWineVarieties().ToListAsync());
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ThenBy(m => m.MgNr)
|
|
||||||
.ToListAsync());
|
|
||||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync());
|
|
||||||
|
|
||||||
await RefreshDeliveryScheduleList();
|
await RefreshDeliveryScheduleList();
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
@@ -196,6 +189,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void DeliveryScheduleList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
private async void DeliveryScheduleList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
if (DeliveryScheduleList.SelectedItem is DeliverySchedule s) {
|
if (DeliveryScheduleList.SelectedItem is DeliverySchedule s) {
|
||||||
Menu_DeliveryAncmtList_SaveSelected.IsEnabled = !IsEditing && !IsCreating;
|
Menu_DeliveryAncmtList_SaveSelected.IsEnabled = !IsEditing && !IsCreating;
|
||||||
@@ -217,11 +211,13 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshDeliveryScheduleList();
|
await RefreshDeliveryScheduleList();
|
||||||
await RefreshList(true);
|
await RefreshList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void FromAllSchedulesInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void FromAllSchedulesInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
if (ViewModel.FilterFromAllSchedules) {
|
if (ViewModel.FilterFromAllSchedules) {
|
||||||
DeliveryScheduleList.SelectedItem = null;
|
DeliveryScheduleList.SelectedItem = null;
|
||||||
} else if (DeliveryScheduleList.SelectedItem == null) {
|
} else if (DeliveryScheduleList.SelectedItem == null) {
|
||||||
@@ -231,11 +227,12 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void SearchInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private async void SearchInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList(true);
|
await RefreshList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
if (ViewModel.FilterSeason == null) return;
|
if (!HasContextLoaded || ViewModel.FilterSeason == null) return;
|
||||||
ViewModel.FilterOnlyUpcoming = false;
|
ViewModel.FilterOnlyUpcoming = false;
|
||||||
await RefreshDeliveryScheduleList();
|
await RefreshDeliveryScheduleList();
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
@@ -274,14 +271,7 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.SelectedDeliveryAncmt = null;
|
ViewModel.SelectedDeliveryAncmt = null;
|
||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: !IsCreating).ToListAsync());
|
||||||
.Where(m => m.IsActive || !IsCreating)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ThenBy(m => m.MgNr)
|
|
||||||
.ToListAsync());
|
|
||||||
|
|
||||||
HideNewEditDeleteButtons();
|
HideNewEditDeleteButtons();
|
||||||
ShowSaveResetCancelButtons();
|
ShowSaveResetCancelButtons();
|
||||||
@@ -374,8 +364,7 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
ViewModel.EnableSearchInputs = true;
|
ViewModel.EnableSearchInputs = true;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await RefreshList();
|
await EnsureContextRenewed();
|
||||||
RefreshInputs();
|
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
ControlUtils.SelectItemWithPk(DeliveryScheduleList, year, dsnr);
|
ControlUtils.SelectItemWithPk(DeliveryScheduleList, year, dsnr);
|
||||||
if (sortid != null)
|
if (sortid != null)
|
||||||
@@ -404,14 +393,7 @@ namespace Elwig.Windows {
|
|||||||
DeliveryAncmtList.IsEnabled = true;
|
DeliveryAncmtList.IsEnabled = true;
|
||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: !IsCreating).ToListAsync());
|
||||||
.Where(m => m.IsActive || !IsCreating)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ThenBy(m => m.MgNr)
|
|
||||||
.ToListAsync());
|
|
||||||
|
|
||||||
HideSaveResetCancelButtons();
|
HideSaveResetCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Leseplanung - Elwig" Height="600" Width="850" MinHeight="450" MinWidth="800"
|
Title="Leseplanung - Elwig" Height="600" Width="850" MinHeight="450" MinWidth="800">
|
||||||
Loaded="Window_Loaded">
|
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryScheduleAdminViewModel/>
|
<vm:DeliveryScheduleAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -30,41 +30,43 @@ namespace Elwig.Windows {
|
|||||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||||
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
|
||||||
ViewModel.FilterOnlyUpcoming = true;
|
ViewModel.FilterOnlyUpcoming = true;
|
||||||
LockInputs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
using var ctx = new AppDbContext();
|
var vm = ViewModel;
|
||||||
var (_, deliveryScheduleQuery, filter) = await ViewModel.GetFilters(ctx);
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
var deliverySchedules = await deliveryScheduleQuery
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
.Include(s => s.Varieties)
|
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterOnlyUpcoming);
|
||||||
.Include(s => s.Branch)
|
var deliverySchedules = await Task.Run(async () => {
|
||||||
.AsSplitQuery()
|
using var ctx = new AppDbContext();
|
||||||
.ToListAsync();
|
var (_, deliveryScheduleQuery, filter) = await vm.GetFilters(ctx);
|
||||||
|
var deliverySchedules = await deliveryScheduleQuery
|
||||||
|
.Include(s => s.Varieties)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
if (filter.Count > 0 && deliverySchedules.Count > 0) {
|
if (filter.Count > 0 && deliverySchedules.Count > 0) {
|
||||||
var dict = deliverySchedules.AsParallel()
|
var dict = deliverySchedules.AsParallel()
|
||||||
.ToDictionary(s => s, s => s.SearchScore(filter))
|
.ToDictionary(s => s, s => s.SearchScore(filter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.DateString)
|
.ThenBy(a => a.Key.DateString)
|
||||||
.ThenBy(a => a.Key.Branch.Name)
|
.ThenBy(a => a.Key.Branch.Name)
|
||||||
.ThenBy(a => a.Key.Description);
|
.ThenBy(a => a.Key.Description);
|
||||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||||
deliverySchedules = dict
|
deliverySchedules = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)
|
.Select(a => a.Key)];
|
||||||
.ToList();
|
} else {
|
||||||
} else {
|
deliverySchedules = [.. deliverySchedules
|
||||||
deliverySchedules = deliverySchedules
|
.OrderBy(s => s.DateString)
|
||||||
.OrderBy(s => s.DateString)
|
.ThenBy(s => s.Branch.Name)
|
||||||
.ThenBy(s => s.Branch.Name)
|
.ThenBy(s => s.Description)];
|
||||||
.ThenBy(s => s.Description)
|
}
|
||||||
.ToList();
|
|
||||||
}
|
return deliverySchedules;
|
||||||
|
});
|
||||||
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
|
if (query != ((ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterOnlyUpcoming))) return;
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryScheduleList, deliverySchedules,
|
ControlUtils.RenewItemsSource(DeliveryScheduleList, deliverySchedules,
|
||||||
DeliveryScheduleList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryScheduleList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
@@ -99,14 +101,14 @@ namespace Elwig.Windows {
|
|||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
await base.OnRenewContext(ctx);
|
await base.OnRenewContext(ctx);
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
|
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
||||||
var varieties = await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync();
|
var varieties = await ctx.FetchWineVarieties().ToListAsync();
|
||||||
ControlUtils.RenewItemsSource(MainWineVarietiesInput, varieties);
|
ControlUtils.RenewItemsSource(MainWineVarietiesInput, varieties);
|
||||||
ControlUtils.RenewItemsSource(OtherWineVarietiesInput, varieties);
|
ControlUtils.RenewItemsSource(OtherWineVarietiesInput, varieties);
|
||||||
var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
var attrList = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||||
attrList.Insert(0, new NullItem("- Keine Angabe -"));
|
attrList.Insert(0, new NullItem("- Keine Angabe -"));
|
||||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
var cultList = await ctx.WineCultivations.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
var cultList = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||||
cultList.Insert(0, new NullItem("- Kein Angabe -"));
|
cultList.Insert(0, new NullItem("- Kein Angabe -"));
|
||||||
ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||||
|
|
||||||
@@ -118,15 +120,17 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SearchInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private async void SearchInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList(true);
|
await RefreshList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
if (ViewModel.FilterSeason == null) return;
|
if (!HasContextLoaded || ViewModel.FilterSeason == null) return;
|
||||||
ViewModel.FilterOnlyUpcoming = false;
|
ViewModel.FilterOnlyUpcoming = false;
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
}
|
}
|
||||||
@@ -225,8 +229,7 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
ViewModel.EnableSearchInputs = true;
|
ViewModel.EnableSearchInputs = true;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await RefreshList();
|
await EnsureContextRenewed();
|
||||||
RefreshInputs();
|
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ namespace Elwig.Windows {
|
|||||||
public MailWindow(int? year = null) {
|
public MailWindow(int? year = null) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Year = year ?? ctx.Seasons.OrderBy(s => s.Year).LastOrDefault()?.Year ?? Utils.Today.Year;
|
Year = year ?? ctx.Seasons.OrderByDescending(s => s.Year).FirstOrDefault()?.Year ?? Utils.Today.Year;
|
||||||
Title = $"Rundschreiben - Lese {Year} - Elwig";
|
Title = $"Rundschreiben - Lese {Year} - Elwig";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
var season = await ctx.Seasons.FindAsync(Year);
|
var season = await ctx.Seasons.Include(s => s.PaymentVariants).Where(s => s.Year == Year).SingleOrDefaultAsync();
|
||||||
var l = new List<string> {
|
var l = new List<string> {
|
||||||
MemberDataSheet.Name
|
MemberDataSheet.Name
|
||||||
};
|
};
|
||||||
@@ -165,10 +165,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
AvaiableDocumentsList.ItemsSource = l;
|
AvaiableDocumentsList.ItemsSource = l;
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(MemberBranchInput, await ctx.Branches
|
ControlUtils.RenewItemsSource(MemberBranchInput, await ctx.FetchBranches(includeWithoutMembers: false).ToListAsync(), MemberInput_SelectionChanged);
|
||||||
.Where(b => b.Members.Count != 0)
|
|
||||||
.OrderBy(b => b.Name)
|
|
||||||
.ToListAsync(), MemberInput_SelectionChanged);
|
|
||||||
if (MemberBranchInput.SelectedItems.Count == 0) {
|
if (MemberBranchInput.SelectedItems.Count == 0) {
|
||||||
MemberBranchInput.SelectionChanged -= MemberInput_SelectionChanged;
|
MemberBranchInput.SelectionChanged -= MemberInput_SelectionChanged;
|
||||||
MemberBranchInput.SelectAll();
|
MemberBranchInput.SelectAll();
|
||||||
@@ -207,13 +204,8 @@ namespace Elwig.Windows {
|
|||||||
.OrderBy(m => m.Name)
|
.OrderBy(m => m.Name)
|
||||||
.ThenBy(m => m.GivenName)
|
.ThenBy(m => m.GivenName)
|
||||||
.Include(m => m.Branch)
|
.Include(m => m.Branch)
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
|
||||||
.ToListAsync(), MemberInput_SelectionChanged);
|
.ToListAsync(), MemberInput_SelectionChanged);
|
||||||
if (MemberCustomInput.SelectedItems.Count == 0) {
|
if (MemberCustomInput.SelectedItems.Count == 0) {
|
||||||
MemberCustomInput.SelectionChanged -= MemberInput_SelectionChanged;
|
MemberCustomInput.SelectionChanged -= MemberInput_SelectionChanged;
|
||||||
@@ -373,7 +365,7 @@ namespace Elwig.Windows {
|
|||||||
RecipientsDeliveryMembersInput.IsChecked = true;
|
RecipientsDeliveryMembersInput.IsChecked = true;
|
||||||
} else if (idx >= 2) {
|
} else if (idx >= 2) {
|
||||||
var name = s.Split(" – ")[^1];
|
var name = s.Split(" – ")[^1];
|
||||||
var pv = await ctx.PaymentVariants.SingleAsync(v => v.Year == Year && v.Name == name)!;
|
var pv = await ctx.PaymentVariants.Where(v => v.Year == Year && v.Name == name).SingleAsync();
|
||||||
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
||||||
RecipientsCreditMembersInput.IsChecked = true;
|
RecipientsCreditMembersInput.IsChecked = true;
|
||||||
}
|
}
|
||||||
@@ -492,13 +484,8 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
Recipients = await query
|
Recipients = await query
|
||||||
.Include(m => m.Branch)
|
.Include(m => m.Branch)
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
UpdatePostalEmailRecipients();
|
UpdatePostalEmailRecipients();
|
||||||
@@ -615,12 +602,16 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeDocs() {
|
private void DisposeDocs() {
|
||||||
PrintDocument?.Dispose();
|
try {
|
||||||
PrintDocument = null;
|
PrintDocument?.Dispose();
|
||||||
|
PrintDocument = null;
|
||||||
|
} catch { }
|
||||||
if (EmailDocuments != null) {
|
if (EmailDocuments != null) {
|
||||||
foreach (var (m, docs) in EmailDocuments) {
|
foreach (var (m, docs) in EmailDocuments) {
|
||||||
foreach (var d in docs) {
|
foreach (var d in docs) {
|
||||||
d.Dispose();
|
try {
|
||||||
|
d.Dispose();
|
||||||
|
} catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EmailDocuments = null;
|
EmailDocuments = null;
|
||||||
@@ -699,7 +690,7 @@ namespace Elwig.Windows {
|
|||||||
PrintButton.IsEnabled = PrintDocument != null && !hasPreviewDocs;
|
PrintButton.IsEnabled = PrintDocument != null && !hasPreviewDocs;
|
||||||
EmailButton.IsEnabled = EmailDocuments != null && !hasPreviewDocs && App.Config.Smtp != null;
|
EmailButton.IsEnabled = EmailDocuments != null && !hasPreviewDocs && App.Config.Smtp != null;
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
MessageBox.Show(exc.ToString(), "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
} finally {
|
} finally {
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
@@ -721,7 +712,7 @@ namespace Elwig.Windows {
|
|||||||
foreach (var doc in docs) {
|
foreach (var doc in docs) {
|
||||||
if (doc.Type == DocType.DeliveryConfirmation) {
|
if (doc.Type == DocType.DeliveryConfirmation) {
|
||||||
var year = (int)doc.Details!;
|
var year = (int)doc.Details!;
|
||||||
var b = new Billing(year);
|
var b = await Billing.Create(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets();
|
await b.CalculateBuckets();
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
@@ -751,10 +742,13 @@ namespace Elwig.Windows {
|
|||||||
Member = m,
|
Member = m,
|
||||||
Docs = docs.SelectMany<SelectedDoc, GeneratedDoc>(doc => {
|
Docs = docs.SelectMany<SelectedDoc, GeneratedDoc>(doc => {
|
||||||
try {
|
try {
|
||||||
|
App.MainDispatcher.Invoke(() => {
|
||||||
|
ProgressBar.Value = offset + 100.0 * i / 2 / totalNum;
|
||||||
|
});
|
||||||
if (doc.Type == DocType.Custom) {
|
if (doc.Type == DocType.Custom) {
|
||||||
return [new GeneratedDoc((string)doc.Details!)];
|
return [new GeneratedDoc((string)doc.Details!)];
|
||||||
} else if (doc.Type == DocType.MemberDataSheet) {
|
} else if (doc.Type == DocType.MemberDataSheet) {
|
||||||
return [new GeneratedDoc(new MemberDataSheet(m, ctx) { Date = postalDate })];
|
return [new GeneratedDoc(new MemberDataSheet(m) { Date = postalDate })];
|
||||||
} else if (doc.Type == DocType.DeliveryConfirmation) {
|
} else if (doc.Type == DocType.DeliveryConfirmation) {
|
||||||
var year = (int)doc.Details!;
|
var year = (int)doc.Details!;
|
||||||
DeliveryConfirmationDeliveryData data;
|
DeliveryConfirmationDeliveryData data;
|
||||||
@@ -765,21 +759,14 @@ namespace Elwig.Windows {
|
|||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return [new GeneratedDoc(new DeliveryConfirmation(ctx, year, m, data) { Date = postalDate })];
|
return [new GeneratedDoc(new DeliveryConfirmation(year, m, postalDate, data) { Date = postalDate })];
|
||||||
} else if (doc.Type == DocType.CreditNote) {
|
} else if (doc.Type == DocType.CreditNote) {
|
||||||
var details = ((int, int))doc.Details!;
|
var details = ((int, int))doc.Details!;
|
||||||
var year = details.Item1;
|
var year = details.Item1;
|
||||||
var avnr = details.Item2;
|
var avnr = details.Item2;
|
||||||
var data = cnData[(year, avnr)];
|
var data = cnData[(year, avnr)];
|
||||||
try {
|
try {
|
||||||
return [new GeneratedDoc(new CreditNote(
|
return [new GeneratedDoc(new CreditNote(data.Item2[m.MgNr], postalDate, data.Item3, data.Item1[m.MgNr]) { Date = postalDate })];
|
||||||
ctx, data.Item2[m.MgNr], data.Item1[m.MgNr],
|
|
||||||
data.Item3.ConsiderContractPenalties,
|
|
||||||
data.Item3.ConsiderTotalPenalty,
|
|
||||||
data.Item3.ConsiderAutoBusinessShares,
|
|
||||||
data.Item3.ConsiderCustomModifiers,
|
|
||||||
ctx.GetMemberUnderDelivery(year, m.MgNr).GetAwaiter().GetResult()
|
|
||||||
) { Date = postalDate })];
|
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -823,7 +810,7 @@ namespace Elwig.Windows {
|
|||||||
var emailRecipients = email.Select(d => d.Key.MgNr).ToHashSet();
|
var emailRecipients = email.Select(d => d.Key.MgNr).ToHashSet();
|
||||||
foreach (var item1 in email.Select((e, i) => new { Index = i, e.Key, e.Value })) {
|
foreach (var item1 in email.Select((e, i) => new { Index = i, e.Key, e.Value })) {
|
||||||
foreach (var item2 in item1.Value.Select((d, i) => new { Index = i, Doc = d })) {
|
foreach (var item2 in item1.Value.Select((d, i) => new { Index = i, Doc = d })) {
|
||||||
await item2.Doc.Generate(CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
await item2.Doc.Generate(ctx, CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
||||||
ProgressBar.Value = offset + v * (item2.Index + 1) / item1.Value.Count / totalNum + 100.0 * item1.Index / totalNum;
|
ProgressBar.Value = offset + v * (item2.Index + 1) / item1.Value.Count / totalNum + 100.0 * item1.Index / totalNum;
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
@@ -857,7 +844,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
if (printDocs.Count > 0) {
|
if (printDocs.Count > 0) {
|
||||||
var print = Document.Merge(printDocs);
|
var print = Document.Merge(printDocs);
|
||||||
await print.Generate(CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
await print.Generate(ctx, CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
||||||
ProgressBar.Value = offset + v * printNum / totalNum;
|
ProgressBar.Value = offset + v * printNum / totalNum;
|
||||||
})));
|
})));
|
||||||
PrintDocument = print;
|
PrintDocument = print;
|
||||||
@@ -1010,7 +997,7 @@ namespace Elwig.Windows {
|
|||||||
return;
|
return;
|
||||||
var name = s.Split(" – ")[^1];
|
var name = s.Split(" – ")[^1];
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var pv = ctx.PaymentVariants.Single(v => v.Year == Year && v.Name == name)!;
|
var pv = ctx.PaymentVariants.Where(v => v.Year == Year && v.Name == name).Single();
|
||||||
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
||||||
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
||||||
RecipientsCreditMembersInput.IsChecked = true;
|
RecipientsCreditMembersInput.IsChecked = true;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Elwig" Height="390" Width="520" ResizeMode="CanMinimize"
|
Title="Elwig" Height="390" Width="520" ResizeMode="CanMinimize"
|
||||||
Loaded="Window_Loaded" Closing="Window_Closing">
|
Closing="Window_Closing">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Button">
|
<Style TargetType="Button">
|
||||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ namespace Elwig.Windows {
|
|||||||
SyncButton.Visibility = App.Config.SyncUrl != null ? Visibility.Visible : Visibility.Hidden;
|
SyncButton.Visibility = App.Config.SyncUrl != null ? Visibility.Visible : Visibility.Hidden;
|
||||||
Menu_Database_Upload.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Database_Upload.IsEnabled = App.Config.SyncUrl != null;
|
||||||
Menu_Database_Download.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Database_Download.IsEnabled = App.Config.SyncUrl != null;
|
||||||
|
SeasonInput.Value = Utils.CurrentLastSeason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
protected override async Task OnInit(AppDbContext ctx) {
|
||||||
SeasonInput.Value = Utils.CurrentLastSeason;
|
await base.OnInit(ctx);
|
||||||
|
|
||||||
if (Utils.HasInternetConnectivity()) {
|
if (Utils.HasInternetConnectivity()) {
|
||||||
CheckSync(200);
|
CheckSync(200);
|
||||||
}
|
}
|
||||||
@@ -405,7 +405,7 @@ namespace Elwig.Windows {
|
|||||||
private async void SeasonInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
|
private async void SeasonInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var year = SeasonInput.Value;
|
var year = SeasonInput.Value;
|
||||||
var s0 = await ctx.Seasons.FindAsync(year);
|
var s0 = await ctx.FetchSeasons(year).SingleOrDefaultAsync();
|
||||||
var valid = (s0 != null);
|
var valid = (s0 != null);
|
||||||
DeliveryConfirmationButton.IsEnabled = valid;
|
DeliveryConfirmationButton.IsEnabled = valid;
|
||||||
PaymentButton.IsEnabled = valid;
|
PaymentButton.IsEnabled = valid;
|
||||||
@@ -469,7 +469,7 @@ namespace Elwig.Windows {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
var b = new Billing(year);
|
var b = await Billing.Create(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets();
|
await b.CalculateBuckets();
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
@@ -502,7 +502,7 @@ namespace Elwig.Windows {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
var b = new Billing(year);
|
var b = await Billing.Create(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets();
|
await b.CalculateBuckets();
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
@@ -511,7 +511,7 @@ namespace Elwig.Windows {
|
|||||||
using var ods = new OdsFile(d.FileName);
|
using var ods = new OdsFile(d.FileName);
|
||||||
var tblTotal = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year);
|
var tblTotal = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year);
|
||||||
await ods.AddTable(tblTotal);
|
await ods.AddTable(tblTotal);
|
||||||
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
|
foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
|
||||||
var tbl = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year, branch);
|
var tbl = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year, branch);
|
||||||
await ods.AddTable(tbl);
|
await ods.AddTable(tbl);
|
||||||
}
|
}
|
||||||
@@ -537,7 +537,7 @@ namespace Elwig.Windows {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
var b = new Billing(year);
|
var b = await Billing.Create(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets();
|
await b.CalculateBuckets();
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
@@ -568,7 +568,7 @@ namespace Elwig.Windows {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
try {
|
try {
|
||||||
var b = new Billing(year);
|
var b = await Billing.Create(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets();
|
await b.CalculateBuckets();
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150"
|
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150">
|
||||||
Loaded="Window_Loaded">
|
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:MemberAdminViewModel/>
|
<vm:MemberAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -82,12 +82,9 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null;
|
||||||
Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null;
|
||||||
}
|
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
|
||||||
ViewModel.ShowOnlyActiveMembers = true;
|
ViewModel.ShowOnlyActiveMembers = true;
|
||||||
|
|
||||||
UpdateContactInfoVisibility();
|
UpdateContactInfoVisibility();
|
||||||
LockInputs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FocusMember(int mgnr) {
|
public void FocusMember(int mgnr) {
|
||||||
@@ -113,46 +110,52 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
using var ctx = new AppDbContext();
|
var vm = ViewModel;
|
||||||
var (_, memberQuery, filter) = await ViewModel.GetFilters(ctx);
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
var members = await memberQuery
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
.Include(m => m.Branch)
|
var query = (vm.SearchQuery, vm.ShowOnlyActiveMembers);
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
var (members, totalMemberCount, totalBusinessShares) = await Task.Run(async () => {
|
||||||
.Include(m => m.EmailAddresses)
|
using var ctx = new AppDbContext();
|
||||||
.Include(m => m.TelephoneNumbers)
|
var (_, memberQuery, filter) = await vm.GetFilters(ctx);
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
var members = await memberQuery
|
||||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
.Include(m => m.EmailAddresses)
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
.AsSplitQuery()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
if (filter.Count > 0 && members.Count > 0) {
|
if (filter.Count > 0 && members.Count > 0) {
|
||||||
var dict = members.AsParallel()
|
var dict = members.AsParallel()
|
||||||
.ToDictionary(m => m, m => m.SearchScore(filter))
|
.ToDictionary(m => m, m => m.SearchScore(filter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.Name)
|
.ThenBy(a => a.Key.Name)
|
||||||
.ThenBy(a => a.Key.GivenName)
|
.ThenBy(a => a.Key.GivenName)
|
||||||
.ThenBy(a => a.Key.MgNr);
|
.ThenBy(a => a.Key.MgNr);
|
||||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||||
members = dict
|
members = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)
|
.Select(a => a.Key)];
|
||||||
.ToList();
|
} else {
|
||||||
} else {
|
members = [.. members
|
||||||
members = members
|
.OrderBy(m => m.Name)
|
||||||
.OrderBy(m => m.Name)
|
.ThenBy(m => m.GivenName)
|
||||||
.ThenBy(m => m.GivenName)
|
.ThenBy(m => m.MgNr)];
|
||||||
.ThenBy(m => m.MgNr)
|
}
|
||||||
.ToList();
|
|
||||||
}
|
var totalMemberCount = await ctx.Members.CountAsync();
|
||||||
|
var totalBusinessShares = await ctx.Members.SumAsync(m => m.BusinessShares);
|
||||||
|
|
||||||
|
return (members, totalMemberCount, totalBusinessShares);
|
||||||
|
});
|
||||||
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
|
if (query != (ViewModel.SearchQuery, ViewModel.ShowOnlyActiveMembers)) return;
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(MemberList, members,
|
ControlUtils.RenewItemsSource(MemberList, members,
|
||||||
MemberList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
MemberList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
if (updateSort && MemberList.SelectedItem != null)
|
if (updateSort && MemberList.SelectedItem != null)
|
||||||
MemberList.ScrollIntoView(MemberList.SelectedItem);
|
MemberList.ScrollIntoView(MemberList.SelectedItem);
|
||||||
|
|
||||||
ViewModel.StatusMembers = $"{members.Count:N0} ({await ctx.Members.CountAsync():N0})";
|
ViewModel.StatusMembers = $"{members.Count:N0} ({totalMemberCount:N0})";
|
||||||
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.BusinessShares):N0} ({await ctx.Members.SumAsync(m => m.BusinessShares):N0})";
|
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.BusinessShares):N0} ({totalBusinessShares:N0})";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshInputs(bool validate = false) {
|
private void RefreshInputs(bool validate = false) {
|
||||||
@@ -184,12 +187,12 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
await base.OnRenewContext(ctx);
|
await base.OnRenewContext(ctx);
|
||||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
|
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
||||||
ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync());
|
ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync());
|
||||||
|
|
||||||
var font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets");
|
var font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets");
|
||||||
MenuItem? temp = null;
|
MenuItem? temp = null;
|
||||||
var seasons = await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync();
|
var seasons = await ctx.Seasons.Include(s => s.PaymentVariants).OrderByDescending(s => s.Year).ToListAsync();
|
||||||
Menu_DeliveryConfirmation.Items.Clear();
|
Menu_DeliveryConfirmation.Items.Clear();
|
||||||
foreach (var s in seasons) {
|
foreach (var s in seasons) {
|
||||||
var i = new MenuItem {
|
var i = new MenuItem {
|
||||||
@@ -328,6 +331,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,10 +388,9 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
int areaComs = 0, deliveries = 0, credits = 0;
|
int areaComs = 0, deliveries = 0, credits = 0;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
var l = (await ctx.Members.FindAsync(m.MgNr))!;
|
areaComs = await ctx.AreaCommitments.Where(c => c.MgNr == m.MgNr).CountAsync();
|
||||||
areaComs = l.AreaCommitments.Count;
|
deliveries = await ctx.Deliveries.Where(d => d.MgNr == m.MgNr).CountAsync();
|
||||||
deliveries = l.Deliveries.Count;
|
credits = await ctx.Credits.Where(c => c.MgNr == m.MgNr).CountAsync();
|
||||||
credits = l.Credits.Count;
|
|
||||||
}
|
}
|
||||||
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits);
|
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits);
|
||||||
if (d.ShowDialog() == true) {
|
if (d.ShowDialog() == true) {
|
||||||
@@ -436,8 +439,7 @@ namespace Elwig.Windows {
|
|||||||
UpdateContactInfoVisibility();
|
UpdateContactInfoVisibility();
|
||||||
ViewModel.EnableSearchInputs = true;
|
ViewModel.EnableSearchInputs = true;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await RefreshList();
|
await EnsureContextRenewed();
|
||||||
RefreshInputs();
|
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
if (mgnr is int m)
|
if (mgnr is int m)
|
||||||
@@ -485,6 +487,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!HasContextLoaded) return;
|
||||||
await RefreshList(true);
|
await RefreshList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +502,9 @@ namespace Elwig.Windows {
|
|||||||
try {
|
try {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var doc = new Letterhead(m);
|
using var doc = new Letterhead(m);
|
||||||
await doc.Generate();
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
if (!App.Config.Debug) {
|
if (!App.Config.Debug) {
|
||||||
await doc.Print();
|
await doc.Print();
|
||||||
} else {
|
} else {
|
||||||
@@ -788,7 +793,7 @@ namespace Elwig.Windows {
|
|||||||
if (areaComs.Count == 0)
|
if (areaComs.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var oldMember = (await ctx.Members.FindAsync(mgnr))!;
|
var oldMember = await ctx.FetchMembers(mgnr).SingleAsync();
|
||||||
var newName = $"{ViewModel.Name?.Replace('ß', 'ẞ').ToUpper()} " +
|
var newName = $"{ViewModel.Name?.Replace('ß', 'ẞ').ToUpper()} " +
|
||||||
$"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" +
|
$"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" +
|
||||||
$"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" +
|
$"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" +
|
||||||
@@ -797,7 +802,6 @@ namespace Elwig.Windows {
|
|||||||
if (d.ShowDialog() != true)
|
if (d.ShowDialog() != true)
|
||||||
return;
|
return;
|
||||||
ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason;
|
ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason;
|
||||||
ViewModel.MaintainAreaComYearFrom = d.MaintainYearFrom;
|
|
||||||
if (IsEditing)
|
if (IsEditing)
|
||||||
SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save
|
SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
|
|||||||
@@ -21,12 +21,11 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
var origins = (await ctx.WineOrigins
|
var origins = await ctx.WineOrigins
|
||||||
.Include("Gems.AtGem.Kgs.WbKg.Gl")
|
.Include(o => o.Gems).ThenInclude(g => g.AtGem.Kgs).ThenInclude(k => k.WbKg!.Gl)
|
||||||
.AsSplitQuery()
|
.ToListAsync();
|
||||||
.ToListAsync())
|
origins.ForEach(o => { origins.FirstOrDefault(p => p.HkId == o.ParentHkId)?.Children.Add(o); });
|
||||||
.OrderByDescending(o => o.SortKey)
|
origins = [.. origins.OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId)];
|
||||||
.ThenBy(o => o.HkId);
|
|
||||||
ControlUtils.RenewItemsSource(WineOrigins, origins, WineOrigins_SelectionChanged);
|
ControlUtils.RenewItemsSource(WineOrigins, origins, WineOrigins_SelectionChanged);
|
||||||
if (WineOrigins.SelectedItem == null) {
|
if (WineOrigins.SelectedItem == null) {
|
||||||
var hkid = await ctx.WbKgs
|
var hkid = await ctx.WbKgs
|
||||||
@@ -39,8 +38,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
var gls = await ctx.WbGls
|
var gls = await ctx.WbGls
|
||||||
.OrderBy(g => g.GlNr)
|
.OrderBy(g => g.GlNr)
|
||||||
.Include("Kgs.Rds")
|
.Include(g => g.Kgs).ThenInclude(k => k.Rds)
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
ControlUtils.RenewItemsSource(WbGls, gls, WbGls_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(WbGls, gls, WbGls_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||||
UpdateWbGems();
|
UpdateWbGems();
|
||||||
@@ -100,8 +98,8 @@ namespace Elwig.Windows {
|
|||||||
var allMembers = await ctx.Members.Where(m => m.DefaultKgNr == k.KgNr).CountAsync();
|
var allMembers = await ctx.Members.Where(m => m.DefaultKgNr == k.KgNr).CountAsync();
|
||||||
StatusDefaultKgs.Text += $"{activeMembers:N0} ({allMembers:N0})";
|
StatusDefaultKgs.Text += $"{activeMembers:N0} ({allMembers:N0})";
|
||||||
var year = Utils.CurrentNextSeason;
|
var year = Utils.CurrentNextSeason;
|
||||||
var activeAreaComs = await Utils.ActiveAreaCommitments(ctx.AreaCommitments.Where(c => c.KgNr == k.KgNr), year).CountAsync();
|
var activeAreaComs = await Utils.ActiveAreaCommitments(ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr), year).CountAsync();
|
||||||
var allAreaComs = await ctx.AreaCommitments.Where(c => c.KgNr == k.KgNr).CountAsync();
|
var allAreaComs = await ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr).CountAsync();
|
||||||
StatusAreaCommitments.Text += $"{activeAreaComs:N0} ({allAreaComs:N0})";
|
StatusAreaCommitments.Text += $"{activeAreaComs:N0} ({allAreaComs:N0})";
|
||||||
var deliveryParts = await ctx.DeliveryParts.Where(p => p.KgNr == k.KgNr).CountAsync();
|
var deliveryParts = await ctx.DeliveryParts.Where(p => p.KgNr == k.KgNr).CountAsync();
|
||||||
var deliveries = await ctx.Deliveries.Where(d => d.Parts.Any(p => p.KgNr == k.KgNr)).CountAsync();
|
var deliveries = await ctx.Deliveries.Where(d => d.Parts.Any(p => p.KgNr == k.KgNr)).CountAsync();
|
||||||
@@ -214,7 +212,7 @@ namespace Elwig.Windows {
|
|||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
ControlUtils.SelectItemWithPk(WbKgs, k.KgNr);
|
ControlUtils.SelectItemWithPk(WbKgs, k.KgNr);
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
await HintContextChange();
|
await ForceContextReload();
|
||||||
var str = "Der Eintrag konnte nicht aus der Datenbank gelöscht werden!\n\n" + exc.Message;
|
var str = "Der Eintrag konnte nicht aus der Datenbank gelöscht 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;
|
||||||
MessageBox.Show(str, "Katastralgemeinde deaktivieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(str, "Katastralgemeinde deaktivieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
var members = await ctx.Members
|
var members = await ctx.FetchMembers(includeNotActive: true)
|
||||||
.Select(m => new {
|
.Select(m => new {
|
||||||
m.MgNr,
|
m.MgNr,
|
||||||
m.Name,
|
m.Name,
|
||||||
@@ -48,11 +48,8 @@ namespace Elwig.Windows {
|
|||||||
m.BusinessShares,
|
m.BusinessShares,
|
||||||
m.IsActive,
|
m.IsActive,
|
||||||
})
|
})
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ThenBy(m => m.MgNr)
|
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var season = (await ctx.Seasons.FindAsync(Year))!;
|
var season = await ctx.FetchSeasons(Year).SingleAsync();
|
||||||
var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
|
var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
|
||||||
|
|
||||||
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year);
|
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year);
|
||||||
@@ -145,11 +142,7 @@ namespace Elwig.Windows {
|
|||||||
TotalModifiers.Text = $"{list.Count(r => r.Total != 0)} Mg. / {list.Sum(r => r.Total):N2} {sym}";
|
TotalModifiers.Text = $"{list.Count(r => r.Total != 0)} Mg. / {list.Sum(r => r.Total):N2} {sym}";
|
||||||
NonDeliveries.Text = $"{list.Count(r => r.Weight == 0):N0}";
|
NonDeliveries.Text = $"{list.Count(r => r.Weight == 0):N0}";
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(includeNotActive: true).ToListAsync());
|
||||||
.OrderBy(m => m.Name)
|
|
||||||
.ThenBy(m => m.GivenName)
|
|
||||||
.ThenBy(m => m.MgNr)
|
|
||||||
.ToListAsync());
|
|
||||||
CustomAmountInput.Unit = sym;
|
CustomAmountInput.Unit = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +163,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
await App.Client.UpdateValues();
|
await App.Client.UpdateValues();
|
||||||
var b = new Billing(Year);
|
var b = await Billing.Create(Year);
|
||||||
await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, bs ?? default, kgPerBs ?? default, percent / 100.0 ?? default, minBs ?? default);
|
await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, bs ?? default, kgPerBs ?? default, percent / 100.0 ?? default, minBs ?? default);
|
||||||
});
|
});
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
@@ -186,7 +179,7 @@ namespace Elwig.Windows {
|
|||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
try {
|
try {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
var b = new Billing(Year);
|
var b = await Billing.Create(Year);
|
||||||
await b.UnAdjustBusinessShares();
|
await b.UnAdjustBusinessShares();
|
||||||
});
|
});
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ namespace Elwig.Windows {
|
|||||||
ControlUtils.RenewItemsSource(PaymentVariantList, await ctx.PaymentVariants
|
ControlUtils.RenewItemsSource(PaymentVariantList, await ctx.PaymentVariants
|
||||||
.Where(v => v.Year == Year)
|
.Where(v => v.Year == Year)
|
||||||
.OrderBy(v => v.AvNr)
|
.OrderBy(v => v.AvNr)
|
||||||
.Include(v => v.Season.Currency)
|
|
||||||
.ToListAsync());
|
.ToListAsync());
|
||||||
if (PaymentVariantList.SelectedItem == null && PaymentVariantList.Items.Count > 0) {
|
if (PaymentVariantList.SelectedItem == null && PaymentVariantList.Items.Count > 0) {
|
||||||
PaymentVariantList.SelectedIndex = PaymentVariantList.Items.Count - 1;
|
PaymentVariantList.SelectedIndex = PaymentVariantList.Items.Count - 1;
|
||||||
@@ -256,13 +255,13 @@ namespace Elwig.Windows {
|
|||||||
await ViewModel.UpdatePaymentVariant(v.Year, v.AvNr);
|
await ViewModel.UpdatePaymentVariant(v.Year, v.AvNr);
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
await HintContextChange();
|
await ForceContextReload();
|
||||||
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;
|
||||||
MessageBox.Show(str, "Auszahlungsvariante aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(str, "Auszahlungsvariante aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
await HintContextChange();
|
await EnsureContextRenewed();
|
||||||
CommentInput_TextChanged(null, null);
|
CommentInput_TextChanged(null, null);
|
||||||
DateInput_TextChanged(null, null);
|
DateInput_TextChanged(null, null);
|
||||||
TransferDateInput_TextChanged(null, null);
|
TransferDateInput_TextChanged(null, null);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="WixToolset.Sdk/6">
|
<Project Sdk="WixToolset.Sdk/7">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<HarvestFileSuppressUniqueIds>false</HarvestFileSuppressUniqueIds>
|
<HarvestFileSuppressUniqueIds>false</HarvestFileSuppressUniqueIds>
|
||||||
<HarvestFileGenerateGuidsNow>true</HarvestFileGenerateGuidsNow>
|
<HarvestFileGenerateGuidsNow>true</HarvestFileGenerateGuidsNow>
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
<BuildProjectReferences>False</BuildProjectReferences>
|
<BuildProjectReferences>False</BuildProjectReferences>
|
||||||
<OutputName>Elwig</OutputName>
|
<OutputName>Elwig</OutputName>
|
||||||
<Cultures>de-AT</Cultures>
|
<Cultures>de-AT</Cultures>
|
||||||
|
<AcceptEula>wix7</AcceptEula>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<UsingTask TaskName="GetFileVersion" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
<UsingTask TaskName="GetFileVersion" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
||||||
<ParameterGroup>
|
<ParameterGroup>
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -13,17 +13,17 @@ About
|
|||||||
**Product:** Elwig
|
**Product:** Elwig
|
||||||
**Description:** Electronic Management for Vintners' Cooperatives
|
**Description:** Electronic Management for Vintners' Cooperatives
|
||||||
**Type:** ERP system
|
**Type:** ERP system
|
||||||
**Version:** 1.0.3.4 ([Changelog](./CHANGELOG.md))
|
**Version:** 1.0.5.0 ([Changelog](./CHANGELOG.md))
|
||||||
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||||
**Website:** https://elwig.at/
|
**Website:** https://elwig.at/
|
||||||
**Source code:** https://git.necronda.net/winzer/elwig
|
**Source code:** https://git.necronda.net/winzer/elwig
|
||||||
**Developement period:** 2022–2025
|
**Developement period:** 2022–2026
|
||||||
|
|
||||||
**Technology Stack:**
|
**Technology Stack:**
|
||||||
Language: C#
|
Language: C#
|
||||||
Framework: Windows Presentation Framework (WPF)
|
Framework: Windows Presentation Framework (WPF)
|
||||||
Database: [SQLite](https://sqlite.org/)
|
Database: [SQLite](https://sqlite.org/)
|
||||||
PDF creation: [WeasyPrint](https://weasyprint.org/), [RazorLight](https://github.com/toddams/RazorLight), [PdfiumViewer](https://github.com/pvginkel/PdfiumViewer)
|
PDF creation: [iText](https://itextpdf.com/), [Pdfium](https://github.com/bblanchon/pdfium-binaries)
|
||||||
Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||||
|
|
||||||
|
|
||||||
@@ -33,15 +33,15 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
|||||||
**Produkt:** Elwig
|
**Produkt:** Elwig
|
||||||
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
||||||
**Typ:** Warenwirtschaftssystem (ERP-System)
|
**Typ:** Warenwirtschaftssystem (ERP-System)
|
||||||
**Version:** 1.0.3.4 ([Änderungsprotokoll](./CHANGELOG.md))
|
**Version:** 1.0.5.0 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||||
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||||
**Website:** https://elwig.at/
|
**Website:** https://elwig.at/
|
||||||
**Quellcode:** https://git.necronda.net/winzer/elwig
|
**Quellcode:** https://git.necronda.net/winzer/elwig
|
||||||
**Entwicklungszeitraum:** 2022–2025
|
**Entwicklungszeitraum:** 2022–2026
|
||||||
|
|
||||||
**Verwendete Technologien:**
|
**Verwendete Technologien:**
|
||||||
Programmiersprache: C#
|
Programmiersprache: C#
|
||||||
Framework: Windows Presentation Framework (WPF)
|
Framework: Windows Presentation Framework (WPF)
|
||||||
Datenbank: [SQLite](https://sqlite.org/)
|
Datenbank: [SQLite](https://sqlite.org/)
|
||||||
PDF-Erstellung: [iText](https://itextpdf.com/), [RazorLight](https://github.com/toddams/RazorLight), [Pdfium](https://github.com/bblanchon/pdfium-binaries)
|
PDF-Erstellung: [iText](https://itextpdf.com/), [Pdfium](https://github.com/bblanchon/pdfium-binaries)
|
||||||
Paketierung: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
Paketierung: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<Project Sdk="WixToolset.Sdk/6">
|
<Project Sdk="WixToolset.Sdk/7">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Bundle</OutputType>
|
<OutputType>Bundle</OutputType>
|
||||||
<OutputName>Elwig</OutputName>
|
<OutputName>Elwig</OutputName>
|
||||||
<Cultures>de-AT</Cultures>
|
<Cultures>de-AT</Cultures>
|
||||||
|
<AcceptEula>wix7</AcceptEula>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
||||||
<Exec Command="curl --fail -s -L "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -z "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe" -o "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe"" />
|
<Exec Command="curl --fail -s -L "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -z "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe" -o "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe"" />
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
</Target>
|
</Target>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Installer\Installer.wixproj" />
|
<ProjectReference Include="..\Installer\Installer.wixproj" />
|
||||||
<PackageReference Include="WixToolset.Bal.wixext" Version="6.0.2" />
|
<PackageReference Include="WixToolset.Bal.wixext" Version="7.0.0" />
|
||||||
<PackageReference Include="WixToolset.Util.wixext" Version="6.0.2" />
|
<PackageReference Include="WixToolset.Util.wixext" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -2,6 +2,7 @@ using Elwig;
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using Elwig.Helpers.Billing;
|
using Elwig.Helpers.Billing;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Tests {
|
namespace Tests {
|
||||||
@@ -22,7 +23,7 @@ namespace Tests {
|
|||||||
public void Setup_2_Client() {
|
public void Setup_2_Client() {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
App.Client = new ClientParameters(ctx);
|
App.Client = new ClientParameters(ctx);
|
||||||
App.SetBranch(ctx.Branches.Single());
|
App.SetBranch(ctx.Branches.Include(b => b.PostalDest).Single());
|
||||||
}
|
}
|
||||||
|
|
||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ namespace Tests.E2ETests {
|
|||||||
|
|
||||||
Window.FindElement(By.WpfId("SaveButton")).Click();
|
Window.FindElement(By.WpfId("SaveButton")).Click();
|
||||||
|
|
||||||
|
Thread.Sleep(500);
|
||||||
Window.FindElement(By.WpfId("SearchInput")).SendKeys("9999");
|
Window.FindElement(By.WpfId("SearchInput")).SendKeys("9999");
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
var memberListRow = Window.FindElement(By.WpfId("MemberList")).FindElement(By.ClassName("DataGridRow"));
|
var memberListRow = Window.FindElement(By.WpfId("MemberList")).FindElement(By.ClassName("DataGridRow"));
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
DELETE FROM credit;
|
DELETE FROM credit;
|
||||||
DELETE FROM payment_variant;
|
DELETE FROM payment_variant;
|
||||||
DELETE FROM delivery;
|
DELETE FROM delivery;
|
||||||
DELETE FROM area_commitment;
|
DELETE FROM area_commitment_contract;
|
||||||
DELETE FROM area_commitment_type;
|
DELETE FROM area_commitment_type;
|
||||||
DELETE FROM season;
|
DELETE FROM season;
|
||||||
DELETE FROM wine_attribute;
|
DELETE FROM wine_attribute;
|
||||||
|
|||||||
@@ -22,10 +22,15 @@ INSERT INTO area_commitment_type (vtrgid, sortid, attrid, disc, min_kg_per_ha, p
|
|||||||
('GVQ', 'GV', 'Q', NULL, 5000, 1000, 1000000, NULL),
|
('GVQ', 'GV', 'Q', NULL, 5000, 1000, 1000000, NULL),
|
||||||
('GVR', 'GV', 'R', NULL, 5000, 1000, 1000000, NULL);
|
('GVR', 'GV', 'R', NULL, 5000, 1000, 1000000, NULL);
|
||||||
|
|
||||||
INSERT INTO area_commitment (fbnr, mgnr, vtrgid, cultid, area, kgnr, gstnr, rdnr, year_from, year_to) VALUES
|
INSERT INTO area_commitment_contract (fbnr, kgnr, rdnr) VALUES
|
||||||
( 1, 101, 'GV', 'KIP', 10000, 06109, '123/4', NULL, 2000, 2019),
|
( 1, 06109, NULL),
|
||||||
( 2, 101, 'GV', 'KIP', 10000, 06109, '123/5', NULL, 2025, 2030),
|
( 2, 06109, NULL),
|
||||||
( 3, 101, 'GV', 'KIP', 10000, 06109, '123/6', NULL, 2021, 2031);
|
( 3, 06109, NULL);
|
||||||
|
|
||||||
|
INSERT INTO area_commitment (fbnr, revnr, mgnr, vtrgid, cultid, area, gstnr, year_from, year_to) VALUES
|
||||||
|
( 1, 1, 101, 'GV', 'KIP', 10000, '123/4', 2000, 2019),
|
||||||
|
( 2, 1, 101, 'GV', 'KIP', 10000, '123/5', 2025, 2030),
|
||||||
|
( 3, 1, 101, 'GV', 'KIP', 10000, '123/6', 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
|
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
|
||||||
(2020, 'EUR', 1000, 2000, NULL, NULL, NULL, NULL, NULL),
|
(2020, 'EUR', 1000, 2000, NULL, NULL, NULL, NULL, NULL),
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ INSERT INTO delivery_part (year, did, dpnr, sortid, attrid, cultid, weight, kmw,
|
|||||||
(2020, 12, 1, 'BP', NULL, NULL, 2410, 18.0, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
(2020, 12, 1, 'BP', NULL, NULL, 2410, 18.0, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||||
(2020, 12, 2, 'BP', NULL, NULL, 2313, 18.1, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL);
|
(2020, 12, 2, 'BP', NULL, NULL, 2313, 18.1, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
INSERT INTO delivery_part_modifier (year, did, dpnr, modid) VALUES
|
||||||
|
(2020, 2, 1, 'S'),
|
||||||
|
(2020, 2, 2, 'A');
|
||||||
|
|
||||||
INSERT INTO delivery_part_bucket (year, did, dpnr, bktnr, discr, value) VALUES
|
INSERT INTO delivery_part_bucket (year, did, dpnr, bktnr, discr, value) VALUES
|
||||||
(2020, 1, 1, 0, '_', 3219),
|
(2020, 1, 1, 0, '_', 3219),
|
||||||
(2020, 3, 1, 0, '_', 2561),
|
(2020, 3, 1, 0, '_', 2561),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ DELETE FROM credit;
|
|||||||
DELETE FROM payment_variant;
|
DELETE FROM payment_variant;
|
||||||
DELETE FROM delivery;
|
DELETE FROM delivery;
|
||||||
DELETE FROM season;
|
DELETE FROM season;
|
||||||
DELETE FROM area_commitment;
|
DELETE FROM area_commitment_contract;
|
||||||
DELETE FROM area_commitment_type;
|
DELETE FROM area_commitment_type;
|
||||||
DELETE FROM member WHERE mgnr >= 200;
|
DELETE FROM member WHERE mgnr >= 200;
|
||||||
DELETE FROM wine_cultivation;
|
DELETE FROM wine_cultivation;
|
||||||
|
|||||||
@@ -29,11 +29,17 @@ INSERT INTO member_email_address (mgnr, nr, address, comment) VALUES
|
|||||||
INSERT INTO area_commitment_type (vtrgid, sortid, attrid, disc, min_kg_per_ha, penalty_per_kg, penalty_amount, penalty_none) VALUES
|
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);
|
('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
|
INSERT INTO area_commitment_contract (fbnr, kgnr, rdnr) VALUES
|
||||||
( 1, 203, 'GV', NULL, 10000, 15224, '321/9', NULL, NULL, NULL),
|
( 1, 15224, NULL),
|
||||||
( 2, 204, 'GV', NULL, 10000, 15224, '123/1', NULL, 2000, 2019),
|
( 2, 15224, NULL),
|
||||||
( 3, 204, 'GV', NULL, 10000, 15224, '123/2', NULL, 2025, 2030),
|
( 3, 15224, NULL),
|
||||||
( 4, 204, 'GV', NULL, 10000, 15224, '123/3', NULL, 2021, 2031);
|
( 4, 15224, NULL);
|
||||||
|
|
||||||
|
INSERT INTO area_commitment (fbnr, revnr, mgnr, vtrgid, cultid, area, gstnr, year_from, year_to) VALUES
|
||||||
|
( 1, 1, 203, 'GV', NULL, 10000, '321/9', NULL, NULL),
|
||||||
|
( 2, 1, 204, 'GV', NULL, 10000, '123/1', 2000, 2019),
|
||||||
|
( 3, 1, 204, 'GV', NULL, 10000, '123/2', 2025, 2030),
|
||||||
|
( 4, 1, 204, 'GV', NULL, 10000, '123/3', 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
|
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
|
||||||
|
|||||||
@@ -19,16 +19,16 @@
|
|||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.4.0" />
|
||||||
<PackageReference Include="Appium.WebDriver" Version="4.4.5" />
|
<PackageReference Include="Appium.WebDriver" Version="4.4.5" />
|
||||||
<PackageReference Include="NReco.PdfRenderer" Version="1.6.0" />
|
<PackageReference Include="NReco.PdfRenderer" Version="1.6.0" />
|
||||||
<PackageReference Include="NUnit" Version="4.5.1" />
|
<PackageReference Include="NUnit" Version="4.5.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.12.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.12.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="8.0.0">
|
<PackageReference Include="coverlet.collector" Version="8.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers;
|
|
||||||
using Elwig.Models.Dtos;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Tests.UnitTests.DocumentTests {
|
namespace Tests.UnitTests.DocumentTests {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
@@ -9,12 +6,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_VirtualCreditNote() {
|
public async Task Test_01_VirtualCreditNote() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await CreditNote.Initialize(2020, 1, 101, null);
|
||||||
var m = await ctx.Members.FindAsync(101);
|
|
||||||
var p = await ctx.MemberPayments.Where(p => p.Year == 2020 && p.AvNr == 1).SingleAsync();
|
|
||||||
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, 2020, 1);
|
|
||||||
using var doc = new CreditNote(ctx, p, data[m!.MgNr], false, false, false, false,
|
|
||||||
ctx.GetMemberUnderDelivery(2020, m!.MgNr).GetAwaiter().GetResult());
|
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_SimpleDeliveryConfirmation() {
|
public async Task Test_01_SimpleDeliveryConfirmation() {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var m = await ctx.Members.FindAsync(101);
|
var m = await ctx.FetchMembers(101).SingleAsync();
|
||||||
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, 2020, m!);
|
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, 2020, m!);
|
||||||
using var doc = new DeliveryConfirmation(ctx, 2020, m!, data);
|
using var doc = new DeliveryConfirmation(2020, m!, null, data);
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers;
|
|
||||||
|
|
||||||
namespace Tests.UnitTests.DocumentTests {
|
namespace Tests.UnitTests.DocumentTests {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
@@ -7,9 +6,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_OneDeliveryPart() {
|
public async Task Test_01_OneDeliveryPart() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await DeliveryNote.Initialize(2020, 1);
|
||||||
var d = await ctx.Deliveries.FindAsync(2020, 1);
|
|
||||||
using var doc = new DeliveryNote(d!, ctx);
|
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
@@ -19,7 +16,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
"""));
|
"""));
|
||||||
Assert.That(text, Contains.Substring("0123463")); // Betriebsnummer
|
Assert.That(text, Contains.Substring("0123463")); // Betriebsnummer
|
||||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X001"));
|
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X001"));
|
||||||
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("""
|
||||||
@@ -34,9 +31,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_02_TwoDeliveryParts() {
|
public async Task Test_02_TwoDeliveryParts() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await DeliveryNote.Initialize(2020, 4);
|
||||||
var d = await ctx.Deliveries.FindAsync(2020, 4);
|
|
||||||
using var doc = new DeliveryNote(d!, ctx);
|
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
@@ -47,7 +42,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
"""));
|
"""));
|
||||||
Assert.That(text, Contains.Substring("0123471")); // Betriebsnummer
|
Assert.That(text, Contains.Substring("0123471")); // Betriebsnummer
|
||||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X004"));
|
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X004"));
|
||||||
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("""
|
||||||
@@ -68,9 +63,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_03_DeliveryPartsWithAttribute() {
|
public async Task Test_03_DeliveryPartsWithAttribute() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await DeliveryNote.Initialize(2020, 3);
|
||||||
var d = await ctx.Deliveries.FindAsync(2020, 3);
|
|
||||||
using var doc = new DeliveryNote(d!, ctx);
|
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
@@ -80,7 +73,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
"""));
|
"""));
|
||||||
Assert.That(text, Contains.Substring("0123463")); // Betriebsnummer
|
Assert.That(text, Contains.Substring("0123463")); // Betriebsnummer
|
||||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||||
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("""
|
||||||
@@ -107,9 +100,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_04_DeliveryPartsWithCultivation() {
|
public async Task Test_04_DeliveryPartsWithCultivation() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await DeliveryNote.Initialize(2020, 7);
|
||||||
var d = await ctx.Deliveries.FindAsync(2020, 7);
|
|
||||||
using var doc = new DeliveryNote(d!, ctx);
|
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
@@ -119,7 +110,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
"""));
|
"""));
|
||||||
Assert.That(text, Contains.Substring("0123480")); // Betriebsnummer
|
Assert.That(text, Contains.Substring("0123480")); // Betriebsnummer
|
||||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||||
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("""
|
||||||
@@ -139,5 +130,37 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
Assert.That(text, Contains.Substring("Gesamt: 78 15,9 5 332"));
|
Assert.That(text, Contains.Substring("Gesamt: 78 15,9 5 332"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_05_DeliveryPartsWithModifier() {
|
||||||
|
using var doc = await DeliveryNote.Initialize(2020, 2);
|
||||||
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
|
Assert.Multiple(() => {
|
||||||
|
Assert.That(text, Contains.Substring("""
|
||||||
|
W&B Weinbauer GesbR
|
||||||
|
WEINBAUER Wernhardt
|
||||||
|
Winzerstraße 2
|
||||||
|
2223 Hohenruppersdorf
|
||||||
|
"""));
|
||||||
|
Assert.That(text, Contains.Substring("0123471")); // Betriebsnummer
|
||||||
|
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||||
|
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||||
|
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X002"));
|
||||||
|
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||||
|
Assert.That(text, Contains.Substring("""
|
||||||
|
1 Grüner Veltliner Kabinett Kabinett 86 17,5 2 987
|
||||||
|
Herkunft: Österreich / Weinland / Niederösterreich
|
||||||
|
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
|
||||||
|
Zu-/Abschläge: Geschädigte Trauben −10,00 %
|
||||||
|
Waage: ?, ID: ? (gerebelt gewogen)
|
||||||
|
2 Grüner Veltliner Kabinett Kabinett 87 17,7 1 873
|
||||||
|
Herkunft: Österreich / Weinland / Niederösterreich
|
||||||
|
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
|
||||||
|
Zu-/Abschläge: Keine Voranmeldung −0,1000 €/kg
|
||||||
|
Waage: ?, ID: ? (gerebelt gewogen)
|
||||||
|
Gesamt: 87 17,6 4 860
|
||||||
|
"""));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_SimpleLetterhead() {
|
public async Task Test_01_SimpleLetterhead() {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var m = await ctx.Members.FindAsync(104);
|
var m = await ctx.FetchMembers(104).SingleAsync();
|
||||||
using var doc = new Letterhead(m!);
|
using var doc = new Letterhead(m!);
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers;
|
|
||||||
|
|
||||||
namespace Tests.UnitTests.DocumentTests {
|
namespace Tests.UnitTests.DocumentTests {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
@@ -7,9 +6,7 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_SimpleMember() {
|
public async Task Test_01_SimpleMember() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await MemberDataSheet.Initialize(104);
|
||||||
var m = await ctx.Members.FindAsync(104);
|
|
||||||
using var doc = new MemberDataSheet(m!, ctx);
|
|
||||||
var text = await Utils.GeneratePdfText(doc);
|
var text = await Utils.GeneratePdfText(doc);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("""
|
Assert.That(text, Contains.Substring("""
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers;
|
|
||||||
using Elwig.Models.Dtos;
|
|
||||||
|
|
||||||
namespace Tests.UnitTests.DocumentTests {
|
namespace Tests.UnitTests.DocumentTests {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
@@ -8,16 +6,13 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_PaymentVariant2020() {
|
public async Task Test_01_PaymentVariant2020() {
|
||||||
using var ctx = new AppDbContext();
|
using var doc = await PaymentVariantSummary.Initialize(2020, 1);
|
||||||
var v = (await ctx.PaymentVariants.FindAsync(2020, 1))!;
|
|
||||||
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
|
|
||||||
using var doc = new PaymentVariantSummary(v, data);
|
|
||||||
var text = await Utils.GeneratePdfText(doc, true);
|
var text = await Utils.GeneratePdfText(doc, true);
|
||||||
var table = Utils.ExtractTable(text);
|
var table = Utils.ExtractTable(text);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
Assert.That(text, Contains.Substring("Auszahlungsvariante"));
|
Assert.That(text, Contains.Substring("Auszahlungsvariante"));
|
||||||
Assert.That(text, Contains.Substring(v.Name));
|
Assert.That(text, Contains.Substring(doc.Variant.Name));
|
||||||
Assert.That(table.Skip(17).ToArray(), Is.EqualTo(new string[][] {
|
Assert.That(table.Skip(19).ToArray(), Is.EqualTo(new string[][] {
|
||||||
["Sorte/Attr./Bewirt.", "Gradation", "ungebunden", "attributlos gebunden", "gebunden", "Gesamt" ],
|
["Sorte/Attr./Bewirt.", "Gradation", "ungebunden", "attributlos gebunden", "gebunden", "Gesamt" ],
|
||||||
["Qualitätsstufe", "[°Oe]", "[kg]", "[€/kg]", "[kg]", "[€/kg]", "[kg]", "[€/kg]", "[€]" ],
|
["Qualitätsstufe", "[°Oe]", "[kg]", "[€/kg]", "[kg]", "[€/kg]", "[kg]", "[€/kg]", "[€]" ],
|
||||||
["Grüner Veltliner", "3 219", "0", "0", "1 609,50"],
|
["Grüner Veltliner", "3 219", "0", "0", "1 609,50"],
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
|
using Elwig.Helpers;
|
||||||
using NReco.PdfRenderer;
|
using NReco.PdfRenderer;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
@@ -8,7 +9,9 @@ namespace Tests.UnitTests.DocumentTests {
|
|||||||
private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf");
|
private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf");
|
||||||
|
|
||||||
public static async Task<string> GeneratePdfText(Document doc, bool preserveLayout = false) {
|
public static async Task<string> GeneratePdfText(Document doc, bool preserveLayout = false) {
|
||||||
await doc.Generate();
|
using (var ctx = new AppDbContext()) {
|
||||||
|
await doc.Generate(ctx);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
doc.SaveTo(FileName);
|
doc.SaveTo(FileName);
|
||||||
var conv = new PdfToTextConverter { CustomArgs = preserveLayout ? "-layout " : "-raw " };
|
var conv = new PdfToTextConverter { CustomArgs = preserveLayout ? "-layout " : "-raw " };
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ namespace Tests.UnitTests.HelperTests {
|
|||||||
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||||
});
|
});
|
||||||
|
|
||||||
BillingVariant b = new(year, 1);
|
var b = await BillingVariant.Create(year, 1);
|
||||||
await b.CalculateBuckets(false, false, false);
|
await b.CalculateBuckets(false, false, false);
|
||||||
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
@@ -179,7 +179,7 @@ namespace Tests.UnitTests.HelperTests {
|
|||||||
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||||
});
|
});
|
||||||
|
|
||||||
BillingVariant b = new(year, 1);
|
var b = await BillingVariant.Create(year, 1);
|
||||||
await b.CalculateBuckets(false, false, false, Connection);
|
await b.CalculateBuckets(false, false, false, Connection);
|
||||||
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
@@ -225,7 +225,7 @@ namespace Tests.UnitTests.HelperTests {
|
|||||||
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||||
});
|
});
|
||||||
|
|
||||||
BillingVariant b = new(year, 1);
|
var b = await BillingVariant.Create(year, 1);
|
||||||
await b.CalculateBuckets(true, false, false, Connection);
|
await b.CalculateBuckets(true, false, false, Connection);
|
||||||
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Tests.UnitTests.HelperTests {
|
|||||||
DateString = "2021-01-31",
|
DateString = "2021-01-31",
|
||||||
};
|
};
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var members = ctx.Members.ToList();
|
var members = await ctx.FetchMembers().ToListAsync();
|
||||||
Assert.That(members, Has.Count.GreaterThan(0));
|
Assert.That(members, Has.Count.GreaterThan(0));
|
||||||
using var exporter = new Ebics(v, FileName, version, mode);
|
using var exporter = new Ebics(v, FileName, version, mode);
|
||||||
await exporter.ExportAsync(members.Select(m => new Transaction(m, 1234.56m, "EUR", m.MgNr % 100)));
|
await exporter.ExportAsync(members.Select(m => new Transaction(m, 1234.56m, "EUR", m.MgNr % 100)));
|
||||||
|
|||||||
@@ -10,19 +10,19 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
|
|
||||||
private static async Task InitViewModel(DeliveryAdminViewModel vm) {
|
private static async Task InitViewModel(DeliveryAdminViewModel vm) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
vm.MemberSource = await ctx.Members.ToListAsync();
|
vm.MemberSource = await ctx.FetchMembers(includeNotActive: true).ToListAsync();
|
||||||
vm.BranchSource = await ctx.Branches.ToListAsync();
|
vm.BranchSource = await ctx.FetchBranches().ToListAsync();
|
||||||
vm.WineVarSource = await ctx.WineVarieties.ToListAsync();
|
vm.WineVarSource = await ctx.FetchWineVarieties().ToListAsync();
|
||||||
List<object> attrs = (await ctx.WineAttributes.ToListAsync()).Cast<object>().ToList();
|
List<object> attrs = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||||
attrs.Insert(0, new NullItem());
|
attrs.Insert(0, new NullItem());
|
||||||
vm.WineAttrSource = attrs;
|
vm.WineAttrSource = attrs;
|
||||||
List<object> cults = (await ctx.WineCultivations.ToListAsync()).Cast<object>().ToList();
|
List<object> cults = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||||
cults.Insert(0, new NullItem());
|
cults.Insert(0, new NullItem());
|
||||||
vm.WineCultSource = cults;
|
vm.WineCultSource = cults;
|
||||||
vm.WineQualityLevelSource = await ctx.WineQualityLevels.ToListAsync();
|
vm.WineQualityLevelSource = await ctx.FetchWineQualityLevels().ToListAsync();
|
||||||
vm.WineOriginSource = await ctx.WineOrigins.ToListAsync();
|
vm.WineOriginSource = await ctx.WineOrigins.ToListAsync();
|
||||||
vm.WineKgSource = await ctx.Katastralgemeinden.ToListAsync();
|
vm.WineKgSource = await ctx.Katastralgemeinden.ToListAsync();
|
||||||
vm.ModifiersSource = await ctx.Modifiers.Where(m => m.Year == 2022).ToListAsync();
|
vm.ModifiersSource = await ctx.FetchModifiers(2022).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Delivery?> GetDelivery(string lsnr) {
|
private static async Task<Delivery?> GetDelivery(string lsnr) {
|
||||||
@@ -32,7 +32,6 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
.Include(d => d.Parts)
|
.Include(d => d.Parts)
|
||||||
.ThenInclude(p => p.PartModifiers)
|
.ThenInclude(p => p.PartModifiers)
|
||||||
.ThenInclude(m => m.Modifier)
|
.ThenInclude(m => m.Modifier)
|
||||||
.AsSplitQuery()
|
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
|
|
||||||
private static async Task InitViewModel(MemberAdminViewModel vm) {
|
private static async Task InitViewModel(MemberAdminViewModel vm) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
vm.BranchSource = await ctx.Branches.ToListAsync();
|
vm.BranchSource = await ctx.FetchBranches().ToListAsync();
|
||||||
vm.DefaultKgSource = await ctx.Katastralgemeinden.ToListAsync();
|
vm.DefaultKgSource = await ctx.Katastralgemeinden.ToListAsync();
|
||||||
vm.OrtSource = await ctx.PlzDestinations.Include(p => p.Ort).ToListAsync();
|
vm.OrtSource = await ctx.PlzDestinations.ToListAsync();
|
||||||
vm.BillingOrtSource = await ctx.PlzDestinations.Include(p => p.Ort).ToListAsync();
|
vm.BillingOrtSource = await ctx.PlzDestinations.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -31,22 +31,14 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
|
|
||||||
Assert.That(vm.MgNr, Is.EqualTo(205));
|
Assert.That(vm.MgNr, Is.EqualTo(205));
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Assert.That(await ctx.Members.FindAsync(205), Is.Null);
|
Assert.That(await ctx.FetchMembers(205, includeNotActive: true).SingleOrDefaultAsync(), Is.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||||
|
|
||||||
Member? m;
|
Member m;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
m = await ctx.Members
|
m = await ctx.FetchMembers(vm.MgNr, includeNotActive: true, includeContactInfo: true).SingleAsync();
|
||||||
.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.That(m, Is.Not.Null);
|
||||||
@@ -119,22 +111,14 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
vm.IsFunktionär = true;
|
vm.IsFunktionär = true;
|
||||||
|
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Assert.That(await ctx.Members.FindAsync(999), Is.Null);
|
Assert.That(await ctx.FetchMembers(999, includeNotActive: true).SingleOrDefaultAsync(), Is.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||||
|
|
||||||
Member? m;
|
Member m;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
m = await ctx.Members
|
m = await ctx.FetchMembers(vm.MgNr, includeNotActive: true, includeContactInfo: true).SingleAsync();
|
||||||
.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.That(m, Is.Not.Null);
|
||||||
@@ -234,15 +218,7 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
var vm = new MemberAdminViewModel();
|
var vm = new MemberAdminViewModel();
|
||||||
await InitViewModel(vm);
|
await InitViewModel(vm);
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
vm.FillInputs(await ctx.Members
|
vm.FillInputs(await ctx.FetchMembers(202, includeNotActive: true, includeContactInfo: true).SingleAsync());
|
||||||
.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);
|
Assert.That(vm.IsActive, Is.True);
|
||||||
@@ -253,17 +229,9 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
|
|
||||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(202));
|
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(202));
|
||||||
|
|
||||||
Member? m;
|
Member m;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
m = await ctx.Members
|
m = await ctx.FetchMembers(202, includeNotActive: true, includeContactInfo: true).SingleAsync();
|
||||||
.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.That(m, Is.Not.Null);
|
||||||
@@ -286,15 +254,7 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
var vm = new MemberAdminViewModel();
|
var vm = new MemberAdminViewModel();
|
||||||
await InitViewModel(vm);
|
await InitViewModel(vm);
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
vm.FillInputs(await ctx.Members
|
vm.FillInputs(await ctx.FetchMembers(203, includeNotActive: true, includeContactInfo: true).SingleAsync());
|
||||||
.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.Multiple(() => {
|
||||||
@@ -306,17 +266,9 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
vm.MgNr = 210;
|
vm.MgNr = 210;
|
||||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
|
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
|
||||||
|
|
||||||
Member? m;
|
Member m;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
m = await ctx.Members
|
m = await ctx.FetchMembers(210, includeNotActive: true, includeContactInfo: true).SingleAsync();
|
||||||
.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);
|
Assert.That(m, Is.Not.Null);
|
||||||
@@ -334,27 +286,27 @@ namespace Tests.UnitTests.ServiceTests {
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task TestDelete_01_NoReferences() {
|
public async Task TestDelete_01_NoReferences() {
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Assert.That(await ctx.Members.FindAsync(201), Is.Not.Null);
|
Assert.That(await ctx.FetchMembers(201, includeNotActive: true).SingleOrDefaultAsync(), Is.Not.Null);
|
||||||
}
|
}
|
||||||
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false));
|
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false));
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Assert.That(await ctx.Members.FindAsync(201), Is.Null);
|
Assert.That(await ctx.FetchMembers(201, includeNotActive: true).SingleOrDefaultAsync(), Is.Null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task TestDelete_02_AllReferences() {
|
public async Task TestDelete_02_AllReferences() {
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Assert.That(await ctx.Members.FindAsync(204), Is.Not.Null);
|
Assert.That(await ctx.FetchMembers(204, includeNotActive: true).SingleOrDefaultAsync(), Is.Not.Null);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0));
|
Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0));
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
Assert.That(await ctx.Members.FindAsync(204), Is.Not.Null);
|
Assert.That(await ctx.FetchMembers(204, includeNotActive: true).SingleOrDefaultAsync(), Is.Not.Null);
|
||||||
}
|
}
|
||||||
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true));
|
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true));
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
Assert.That(await ctx.Members.FindAsync(204), Is.Null);
|
Assert.That(await ctx.FetchMembers(204, includeNotActive: true).SingleOrDefaultAsync(), Is.Null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
curl --fail -s -L "https://elwig.at/files/create.sql?v=36" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"
|
curl --fail -s -L "https://elwig.at/files/create.sql?v=38" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"
|
||||||
|
|||||||
Reference in New Issue
Block a user