Compare commits

...

24 Commits
v0.13.6 ... dev

Author SHA1 Message Date
2ff53c67c3 [#57] MainWindow: Use Task.Run() 2025-05-05 10:36:30 +02:00
3e1f8a910b [#57] AreaComAdminWindow: Use Task.Run() 2025-05-05 10:36:30 +02:00
ca1fb0f5e8 BaseDataWindow: Use Cursors.Wait instead of Cursors.AppStarting 2025-05-05 10:36:30 +02:00
39d749ad2d [#57] DeliveryAdminWindow: Use Task.Run() 2025-05-05 10:36:30 +02:00
31c491d956 [#57] MemberAdminWinodw: Use Task.Run() 2025-05-05 10:36:30 +02:00
41c5288fc5 Elwig: Update dependencies
Some checks failed
Test / Run tests (push) Failing after 14s
2025-05-05 10:36:30 +02:00
e50e7337e6 Helpers/Utils: Automatically change URL to sync.elwig.at when applicable 2025-05-05 10:36:30 +02:00
ffe85d471c README: Add text 2025-04-24 16:05:41 +02:00
d1c07ee92a Installer/Setup: Update to WiX 6
All checks were successful
Test / Run tests (push) Successful in 2m43s
2025-04-24 14:35:40 +02:00
4af2fa256e Tests: Update dependencies 2025-04-24 14:31:36 +02:00
bf0db37872 Elwig: Update dependencies 2025-04-24 14:31:27 +02:00
3161351a30 Bump version to 0.13.8
All checks were successful
Test / Run tests (push) Successful in 2m19s
Deploy / Build and Deploy (push) Successful in 2m1s
2025-02-21 12:05:34 +01:00
aa98909c0a DeliveryAdminWindow: Fix Handlese/Gerebelt Gewogen input behaviour
All checks were successful
Test / Run tests (push) Successful in 1m51s
2025-02-20 17:06:40 +01:00
775bb08e95 Elwig: Update dependencies
All checks were successful
Test / Run tests (push) Successful in 2m29s
2025-02-20 16:08:52 +01:00
fe0a7dab2a Tests: Update dependencies 2025-02-20 16:08:42 +01:00
138dae715e DeliveryAdminWindow: Allow Gr.Inzersdorf to select LesewagenInput 2025-02-20 15:56:26 +01:00
28af7f8dd3 CHANGELOG: Fix unser anchor names 2025-01-22 16:19:24 +01:00
7cc2f75e7c Bump version to 0.13.7
All checks were successful
Test / Run tests (push) Successful in 2m15s
Deploy / Build and Deploy (push) Successful in 2m23s
2025-01-21 11:59:54 +01:00
c7a2f2241d Billing: Handle negative credit amount in following credits
Some checks failed
Test / Run tests (push) Has been cancelled
2025-01-21 11:58:08 +01:00
bd4ebb8c35 PaymentVariantsWindow: Allow user to change date
All checks were successful
Test / Run tests (push) Successful in 2m35s
2025-01-21 11:03:54 +01:00
6d88c5645c PaymentVariantsWindow: Warn user about negative credit exports 2025-01-21 11:01:56 +01:00
5d017cc8ea MailLogWindow: Fix crash when opening
All checks were successful
Test / Run tests (push) Successful in 2m52s
2025-01-19 17:00:31 +01:00
0b8a1b321f BillingData: Fix collapsing tested with permutations
All checks were successful
Test / Run tests (push) Successful in 3m7s
2025-01-18 12:19:33 +01:00
95927c3f1a ChartWindow: Remove old commented-out code
All checks were successful
Test / Run tests (push) Successful in 2m42s
2025-01-16 09:09:28 +01:00
27 changed files with 733 additions and 517 deletions

View File

@ -3,15 +3,50 @@ Changelog
========= =========
[v0.13.8][v0.13.8] (2025-02-21) {#v0.13.8}
------------------------------------------
### Behobene Fehler {#v0.13.8-bugfixes}
* Details im Lieferungen-Fenster (`DeliveryAdminWindow`) für die WG Weinland richtiggestellt (Lesweagen, Verhalten bei _Gerebelt gewogen_). (138dae715e, aa98909c0a)
### Sonstiges {#v0.13.8-misc}
* Abhängigkeiten aktualisiert. (fe0a7dab2a, 775bb08e95)
[v0.13.8]: https://git.necronda.net/winzer/elwig/releases/tag/v0.13.8
[v0.13.7][v0.13.7] (2025-01-21) {#v0.13.7}
------------------------------------------
### Behobene Fehler {#v0.13.7-bugfixes}
* In seltenen Fällen konnten im Auszahlungsvariante-Fenster (`ChartWindow`) manche (Sorten-/Attribut-/Bewirtschaftungsart-)Zuordnungen zu Kurven nicht richtig gespeichert werden. (0b8a1b321f)
* Beim Öffnen des Ausgangs-Protokoll-Fensters (`MailLogWindow`) kam es zu einem Absturz. (5d017cc8ea)
* Im Auszahlungsvarianten-Fenster (`PaymentVariantsWindow`) war es nicht möglich die Überweisungsdaten zu exportieren, sofern mindestens eine Traubengutschrift einen negativen Betrag aufwies.
Jetzt wird der Benutzer nur gewarnt und es ist möglich alle anderen Gutschriften zu exportieren. (6d88c5645c, c7a2f2241d)
### Sonstiges {#v0.13.7-misc}
* Im Auszahlungsvarianten-Fenster (`PaymentVariantsWindow`) ist es nun möglich das Datum einer Auszahlungsvariante zu ändern. (bd4ebb8c35)
[v0.13.7]: https://git.necronda.net/winzer/elwig/releases/tag/v0.13.7
[v0.13.6][v0.13.6] (2025-01-14) {#v0.13.6} [v0.13.6][v0.13.6] (2025-01-14) {#v0.13.6}
------------------------------------------ ------------------------------------------
### Behobene Fehler {#0.13.6-bugfixes} ### Behobene Fehler {#v0.13.6-bugfixes}
* In seltenen Fällen konnten im Auszahlungsvariante-Fenster (`ChartWindow`) manche (Sorten-/Attribut-/Bewirtschaftungsart-)Zuordnungen zu Kurven nicht richtig gespeichert werden. * In seltenen Fällen konnten im Auszahlungsvariante-Fenster (`ChartWindow`) manche (Sorten-/Attribut-/Bewirtschaftungsart-)Zuordnungen zu Kurven nicht richtig gespeichert werden.
Berechnungen basierend auf diesen (evtl. falschen) Zuordnungen wurden immer richtig ausgeführt, eine nachträgliche Überprüfung ist daher möglich. (20e3e2a76b) Berechnungen basierend auf diesen (evtl. falschen) Zuordnungen wurden immer richtig ausgeführt, eine nachträgliche Überprüfung ist daher möglich. (20e3e2a76b)
### Sonstiges {#0.13.6-misc} ### Sonstiges {#v0.13.6-misc}
* Abhängigkeiten aktualisiert. (95ccb2627c, 80fec4473a) * Abhängigkeiten aktualisiert. (95ccb2627c, 80fec4473a)
@ -23,12 +58,12 @@ Changelog
[v0.13.5][v0.13.5] (2025-01-02) {#v0.13.5} [v0.13.5][v0.13.5] (2025-01-02) {#v0.13.5}
------------------------------------------ ------------------------------------------
### Neue Funktionen {#0.13.5-features} ### Neue Funktionen {#v0.13.5-features}
* Im Mitglieder-Fenster (`MemberAdminWindow`) Filter `aktiv` und `!aktiv` hinzugefügt. (5e53d864b1) * Im Mitglieder-Fenster (`MemberAdminWindow`) Filter `aktiv` und `!aktiv` hinzugefügt. (5e53d864b1)
* Im Lieferungen Fenster (`DeliveryAdminWindow`) Menüpunkt _Statistik_ mitsamt _Qualitätsstatistik_ und _Lieferstatistik pro Ort_ hinzugefügt. (c24b1ca2b9) * Im Lieferungen Fenster (`DeliveryAdminWindow`) Menüpunkt _Statistik_ mitsamt _Qualitätsstatistik_ und _Lieferstatistik pro Ort_ hinzugefügt. (c24b1ca2b9)
### Sonstiges {#0.13.5-misc} ### Sonstiges {#v0.13.5-misc}
* Abhängigkeiten aktualisiert. (c9e483ba9d, 633b560a67) * Abhängigkeiten aktualisiert. (c9e483ba9d, 633b560a67)
@ -40,12 +75,12 @@ Changelog
[v0.13.4][v0.13.4] (2024-11-25) {#v0.13.4} [v0.13.4][v0.13.4] (2024-11-25) {#v0.13.4}
------------------------------------------ ------------------------------------------
### Behobene Fehler {#0.13.4-bugfixes} ### Behobene Fehler {#v0.13.4-bugfixes}
* Bei _Unter-/Überlieferungen lt. gez. GA_ waren seit [v0.10.6](#v0.10.6) (2023-08-30) Nicht-Lieferanten nicht aufgeführt. (6ba2aa7143) * Bei _Unter-/Überlieferungen lt. gez. GA_ waren seit [v0.10.6](#v0.10.6) (2023-08-30) Nicht-Lieferanten nicht aufgeführt. (6ba2aa7143)
* Bei _Unterlieferungen laut Flächenbindungen_ wurden nur Mitglieder berücksichtigt, die zum Zeitpunkt des Exports aktiv waren. (3b97c2243a, 338f9fe092) * Bei _Unterlieferungen laut Flächenbindungen_ wurden nur Mitglieder berücksichtigt, die zum Zeitpunkt des Exports aktiv waren. (3b97c2243a, 338f9fe092)
### Sonstiges {#0.13.4-misc} ### Sonstiges {#v0.13.4-misc}
* Abhängigkeiten aktualisiert. (c3a2f983d5, 70e01849be, a99a23fd08, 4a10e94d71, 6c7f10cb26) * Abhängigkeiten aktualisiert. (c3a2f983d5, 70e01849be, a99a23fd08, 4a10e94d71, 6c7f10cb26)
@ -57,17 +92,17 @@ Changelog
[v0.13.3][v0.13.3] (2024-11-13) {#v0.13.3} [v0.13.3][v0.13.3] (2024-11-13) {#v0.13.3}
------------------------------------------ ------------------------------------------
### Neue Funktionen {#0.13.3-features} ### Neue Funktionen {#v0.13.3-features}
* Im Haupt-Fenster (`MainWindow`) unter _Leseabschluss_ eine Statistik-Tabelle (Gebunden/Ungeb., Mitglieder/Gewicht/Fläche) hinzugefügt. (54deccf021) * Im Haupt-Fenster (`MainWindow`) unter _Leseabschluss_ eine Statistik-Tabelle (Gebunden/Ungeb., Mitglieder/Gewicht/Fläche) hinzugefügt. (54deccf021)
* Im Haupt-Fenster (`MainWindow`) unter _Leseabschluss_ zwei Exportmöglichkeiten (_Flächenbindungen_, _Liefermenge/Ertrag_) hinzugefügt. (c5453c2fe6) * Im Haupt-Fenster (`MainWindow`) unter _Leseabschluss_ zwei Exportmöglichkeiten (_Flächenbindungen_, _Liefermenge/Ertrag_) hinzugefügt. (c5453c2fe6)
* Ausgangs-Protokoll-Fenster (`MailLogWindow`) zum Ansehen aller ausgehenden E-Mails oder ausgedruckten Rundschreiben hinzugefügt (_Rundschreiben_ -> _Hilfe_). (2ee0d56dcc) * Ausgangs-Protokoll-Fenster (`MailLogWindow`) zum Ansehen aller ausgehenden E-Mails oder ausgedruckten Rundschreiben hinzugefügt (_Rundschreiben_ -> _Hilfe_). (2ee0d56dcc)
### Behobene Fehler {#0.13.3-bugfixes} ### Behobene Fehler {#v0.13.3-bugfixes}
* Im Rundschreiben-Fenster (`MailWindow`) kleinere Fehler behoben und alle Einstellungen werden nun gespeichert. (0a9731af09) * Im Rundschreiben-Fenster (`MailWindow`) kleinere Fehler behoben und alle Einstellungen werden nun gespeichert. (0a9731af09)
### Sonstiges {#0.13.3-misc} ### Sonstiges {#v0.13.3-misc}
* In allen Fenstern an passenden Stellen Symbole/Icons hinzugefügt. (f4fa549130) * In allen Fenstern an passenden Stellen Symbole/Icons hinzugefügt. (f4fa549130)
* Im Mitglieder-Fenster (`MemberAdminWindow`) Filter `Flächenbindung` (Mitglieder mit irgendeiner aktiven Flächenbindung) hinzugefügt. (a1d84dd988) * Im Mitglieder-Fenster (`MemberAdminWindow`) Filter `Flächenbindung` (Mitglieder mit irgendeiner aktiven Flächenbindung) hinzugefügt. (a1d84dd988)
@ -81,17 +116,17 @@ Changelog
[v0.13.2][v0.13.2] (2024-10-13) {#v0.13.2} [v0.13.2][v0.13.2] (2024-10-13) {#v0.13.2}
------------------------------------------ ------------------------------------------
### Neue Funktionen {#0.13.2-features} ### Neue Funktionen {#v0.13.2-features}
* Im Lieferungen-Fenster den Menüpunkt _Abwertungsliste_ (`DeliveryDepreciationList`) hinzugefügt. (3cbffdbf27) * Im Lieferungen-Fenster den Menüpunkt _Abwertungsliste_ (`DeliveryDepreciationList`) hinzugefügt. (3cbffdbf27)
### Behobene Fehler {#0.13.2-bugfixes} ### Behobene Fehler {#v0.13.2-bugfixes}
* Fehler im Waagenprotokoll `Avery-Async` (L320) behoben. (8680e51052) * Fehler im Waagenprotokoll `Avery-Async` (L320) behoben. (8680e51052)
* Hausnummern in der BKI Traubentransportscheinliste werden in Excel richtig angezeigt. (86f7f693a0) * Hausnummern in der BKI Traubentransportscheinliste werden in Excel richtig angezeigt. (86f7f693a0)
* Beim Ändern der Identifikatoren von Attributen/Bewirtschaftungsarten wurden diese in Auszahlungsvarianten nicht aktualisiert. (d1f67dc57d) * Beim Ändern der Identifikatoren von Attributen/Bewirtschaftungsarten wurden diese in Auszahlungsvarianten nicht aktualisiert. (d1f67dc57d)
### Sonstiges {#0.13.2-misc} ### Sonstiges {#v0.13.2-misc}
* Weitere automatisierte Tests hinzugefügt. ([#11][i11]) * Weitere automatisierte Tests hinzugefügt. ([#11][i11])
* Namenszusätze bei Gemeinden (z.B. an, bei, im, am) genauer angegeben. (65498dd18f) * Namenszusätze bei Gemeinden (z.B. an, bei, im, am) genauer angegeben. (65498dd18f)
@ -107,15 +142,15 @@ Changelog
[v0.13.1][v0.13.1] (2024-09-29) {#v0.13.1} [v0.13.1][v0.13.1] (2024-09-29) {#v0.13.1}
------------------------------------------ ------------------------------------------
### Neue Funktionen {#0.13.1-features} ### Neue Funktionen {#v0.13.1-features}
* Das Extrahieren/Abwerten/Aufteilen von (Teil-)Lieferungen wurde grundlegend überarbeitet und funktioniert ab jetzt in einem einzigen, übersichtlicheren Dialog. (c62947dacd, c185437b9a) * Das Extrahieren/Abwerten/Aufteilen von (Teil-)Lieferungen wurde grundlegend überarbeitet und funktioniert ab jetzt in einem einzigen, übersichtlicheren Dialog. (c62947dacd, c185437b9a)
### Behobene Fehler {#0.13.1-bugfixes} ### Behobene Fehler {#v0.13.1-bugfixes}
* Im Mitglieder-Fenster (`MemberAdminWinodw`) wurden bei `Anlieferungsbestätigung -> speichern (PDF)` und `Traubengutschrift -> speichern (PDF)` E-Mails verschickt, anstatt ein PDF gespeichert. (6ba1973087, a2315e84bd) * Im Mitglieder-Fenster (`MemberAdminWinodw`) wurden bei `Anlieferungsbestätigung -> speichern (PDF)` und `Traubengutschrift -> speichern (PDF)` E-Mails verschickt, anstatt ein PDF gespeichert. (6ba1973087, a2315e84bd)
### Sonstiges {#0.13.1-misc} ### Sonstiges {#v0.13.1-misc}
* Abhängigkeiten aktualisiert. (b6ae1f5675) * Abhängigkeiten aktualisiert. (b6ae1f5675)
@ -130,7 +165,7 @@ Changelog
> [!NOTE] > [!NOTE]
> Ab dieser Version verhält sich die Berechnung der Unterlieferungen bei Flächenbindungen anders. > Ab dieser Version verhält sich die Berechnung der Unterlieferungen bei Flächenbindungen anders.
### Behobene Fehler {#0.13.0-bugfixes} ### Behobene Fehler {#v0.13.0-bugfixes}
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) war das Extrahieren in eine neue Lieferung seit ca. 6 Monaten (98688168b8) nicht mehr möglich. (8a61747538) * Im Lieferungen-Fenster (`DeliveryAdminWindow`) war das Extrahieren in eine neue Lieferung seit ca. 6 Monaten (98688168b8) nicht mehr möglich. (8a61747538)

View File

@ -197,10 +197,12 @@ namespace Elwig {
var ch = CurrentLastWrite; var ch = CurrentLastWrite;
if (ch > CurrentApp.LastChanged) if (ch > CurrentApp.LastChanged)
CurrentApp.LastChanged = ch; CurrentApp.LastChanged = ch;
foreach (Window w in CurrentApp.Windows) { MainDispatcher.Invoke(() => {
if (w is not ContextWindow c) continue; foreach (Window w in CurrentApp.Windows) {
MainDispatcher.BeginInvoke(c.HintContextChange); if (w is not ContextWindow c) continue;
} MainDispatcher.BeginInvoke(c.HintContextChange);
}
});
} }
private void OnAutoUpdateTimer(object? sender, EventArgs? evt) { private void OnAutoUpdateTimer(object? sender, EventArgs? evt) {

View File

@ -7,7 +7,7 @@
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<PreserveCompilationContext>true</PreserveCompilationContext> <PreserveCompilationContext>true</PreserveCompilationContext>
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon> <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
<Version>0.13.6</Version> <Version>0.13.8</Version>
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
@ -26,20 +26,20 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="LinqKit" Version="1.3.7" /> <PackageReference Include="LinqKit" Version="1.3.8" />
<PackageReference Include="MailKit" Version="4.9.0" /> <PackageReference Include="MailKit" Version="4.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" /> <PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.4" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2903.40" /> <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3179.45" />
<PackageReference Include="NJsonSchema" Version="11.1.0" /> <PackageReference Include="NJsonSchema" Version="11.3.2" />
<PackageReference Include="PdfiumViewer" Version="2.13.0" /> <PackageReference Include="PdfiumViewer" Version="2.13.0" />
<PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" /> <PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" />
<PackageReference Include="RazorLight" Version="2.3.1" /> <PackageReference Include="RazorLight" Version="2.3.1" />
<PackageReference Include="ScottPlot.WPF" Version="5.0.53" /> <PackageReference Include="ScottPlot.WPF" Version="5.0.55" />
<PackageReference Include="System.IO.Ports" Version="9.0.1" /> <PackageReference Include="System.IO.Ports" Version="9.0.4" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.1" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -306,7 +306,8 @@ namespace Elwig.Helpers.Billing {
if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) { if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) {
foreach (var k in ks) { foreach (var k in ks) {
if (!(originalData[$"{k[..2]}/"]?.AsValue().TryGetValue<string>(out var o) ?? false) || o == v) if (!(originalData[$"{k[..2]}/"]?.AsValue().TryGetValue<string>(out var o) ?? false) || o == v)
data.Remove(k); if (!(originalData[k.Split('-')[0]]?.AsValue().TryGetValue<string>(out var o2) ?? false) || o2 == v)
data.Remove(k);
} }
data["default"] = v; data["default"] = v;
CollapsePaymentData(data, originalData, vaributes, useDefault); CollapsePaymentData(data, originalData, vaributes, useDefault);
@ -317,7 +318,8 @@ namespace Elwig.Helpers.Billing {
if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) { if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) {
foreach (var k in ks) { foreach (var k in ks) {
if (!(originalData[$"{k[..2]}/"]?.AsValue().TryGetValue<decimal>(out var o) ?? false) || o == v) if (!(originalData[$"{k[..2]}/"]?.AsValue().TryGetValue<decimal>(out var o) ?? false) || o == v)
data.Remove(k); if (!(originalData[k.Split('-')[0]]?.AsValue().TryGetValue<decimal>(out var o2) ?? false) || o2 == v)
data.Remove(k);
} }
data["default"] = v; data["default"] = v;
CollapsePaymentData(data, originalData, vaributes, useDefault); CollapsePaymentData(data, originalData, vaributes, useDefault);
@ -371,6 +373,15 @@ namespace Elwig.Helpers.Billing {
} else if (k.Contains("/-")) { } else if (k.Contains("/-")) {
data.Remove(k, out var val); data.Remove(k, out var val);
data.Add(k.Replace("/-", "-"), val); data.Add(k.Replace("/-", "-"), val);
if (k[0] == '/' || k.Contains('-')) {
foreach (var (k2, o) in originalData) {
if (!data.ContainsKey(k2) && k2.Contains('-') && k2.Contains("-" + k.Split('-')[1]) && !k2.Contains("/-")
&& (!k2.Contains('/') || k2.Length <= 4 || !data.ContainsKey(k2[2..])))
{
data[k2] = o?.DeepClone();
}
}
}
} }
} }

View File

@ -46,14 +46,14 @@ namespace Elwig.Helpers.Billing {
m.mgnr, m.mgnr,
v.avnr, v.avnr,
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount, ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
ROUND(lp.amount / POW(10, s.precision - 2)) AS prev_amount, IIF(lc.amount >= 0, ROUND(lp.amount / POW(10, s.precision - 2)), 0) AS prev_net_amount,
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat, IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) + ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) +
ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) + ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) +
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) + ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) +
IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0) IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0)
AS modifiers, AS modifiers,
lc.modifiers AS prev_modifiers IIF(lc.amount >= 0, lc.modifiers, 0) AS prev_modifiers
FROM season s FROM season s
JOIN payment_variant v ON v.year = s.year JOIN payment_variant v ON v.year = s.year
LEFT JOIN payment_variant l ON l.year = s.year LEFT JOIN payment_variant l ON l.year = s.year

View File

@ -23,6 +23,10 @@ namespace Elwig.Helpers {
public bool HasNetWeighing(Branch? b) => HasNetWeighing(b?.ZwstId); public bool HasNetWeighing(Branch? b) => HasNetWeighing(b?.ZwstId);
public bool HasNetWeighing() => HasNetWeighing(App.ZwstId); public bool HasNetWeighing() => HasNetWeighing(App.ZwstId);
public bool HasBoxWeighing(string? zwstId) => IsWinzerkeller && (zwstId != "W");
public bool HasBoxWeighing(Branch? b) => HasBoxWeighing(b?.ZwstId);
public bool HasBoxWeighing() => HasBoxWeighing(App.ZwstId);
public string NameToken; public string NameToken;
public string NameShort; public string NameShort;
public string Name; public string Name;

View File

@ -434,8 +434,7 @@ namespace Elwig.Helpers {
if (accept != null) if (accept != null)
client.DefaultRequestHeaders.Accept.Add(new(accept)); client.DefaultRequestHeaders.Accept.Add(new(accept));
if (username != null || password != null) if (username != null || password != null)
client.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String( client.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String(Utils.UTF8.GetBytes($"{username}:{password}")));
Utils.UTF8.GetBytes($"{username}:{password}")));
return client; return client;
} }
@ -454,6 +453,8 @@ namespace Elwig.Helpers {
} }
public static async Task UploadExportData(string zip, string url, string username, string password) { public static async Task UploadExportData(string zip, string url, string username, string password) {
if (url.StartsWith("https://elwig.at/clients/"))
url = "https://sync.elwig.at/" + url[25..];
if (!url.EndsWith('/')) url += "/"; if (!url.EndsWith('/')) url += "/";
using var client = GetHttpClient(username, password, accept: "application/json"); using var client = GetHttpClient(username, password, accept: "application/json");
var content = new StreamContent(new FileStream(zip, FileMode.Open, FileAccess.Read)); var content = new StreamContent(new FileStream(zip, FileMode.Open, FileAccess.Read));
@ -463,6 +464,8 @@ namespace Elwig.Helpers {
} }
public static async Task<JsonArray> GetExportMetaData(string url, string username, string password) { public static async Task<JsonArray> GetExportMetaData(string url, string username, string password) {
if (url.StartsWith("https://elwig.at/clients/"))
url = "https://sync.elwig.at/" + url[25..];
using var client = GetHttpClient(username, password, accept: "application/json"); using var client = GetHttpClient(username, password, accept: "application/json");
using var res = await client.GetAsync(url); using var res = await client.GetAsync(url);
res.EnsureSuccessStatusCode(); res.EnsureSuccessStatusCode();
@ -496,34 +499,39 @@ namespace Elwig.Helpers {
if (App.Config.Smtp == null) if (App.Config.Smtp == null)
return false; return false;
SmtpClient? client = null; Mouse.OverrideCursor = Cursors.Wait;
try {
Mouse.OverrideCursor = Cursors.AppStarting;
client = await GetSmtpClient();
using var msg = new MimeMessage(); var success = await Task.Run(async () => {
msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From)); SmtpClient? client = null;
msg.To.AddRange(member.EmailAddresses.OrderBy(a => a.Nr).Select(a => new MailboxAddress(member.AdministrativeName, a.Address))); try {
msg.Subject = subject; client = await GetSmtpClient();
var body = new Multipart("mixed") {
new TextPart("plain") { Text = text } using var msg = new MimeMessage();
}; msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From));
foreach (var doc in docs) { msg.To.AddRange(member.EmailAddresses.OrderBy(a => a.Nr).Select(a => new MailboxAddress(member.AdministrativeName, a.Address)));
var name = NormalizeFileName(doc.Title); msg.Subject = subject;
body.Add(doc.AsEmailAttachment($"{name}.pdf")); var body = new Multipart("mixed") {
new TextPart("plain") { Text = text }
};
foreach (var doc in docs) {
var name = NormalizeFileName(doc.Title);
body.Add(doc.AsEmailAttachment($"{name}.pdf"));
}
msg.Body = body;
await client!.SendAsync(msg);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
} finally {
if (client != null)
await client.DisconnectAsync(true);
client?.Dispose();
} }
msg.Body = body; return true;
await client!.SendAsync(msg); });
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); Mouse.OverrideCursor = null;
return false; return success;
} finally {
if (client != null)
await client.DisconnectAsync(true);
client?.Dispose();
Mouse.OverrideCursor = null;
}
return true;
} }
public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member, string, string)? emailData = null) { public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member, string, string)? emailData = null) {

View File

@ -15,7 +15,7 @@ namespace Elwig.Models.Dtos {
public static IEnumerable<Transaction> FromPaymentVariant(PaymentVar variant) { public static IEnumerable<Transaction> FromPaymentVariant(PaymentVar variant) {
return variant.Credits return variant.Credits
.Where(c => c.Member.Iban != null) .Where(c => c.Member.Iban != null && c.Amount > 0)
.OrderBy(c => c.TgNr) .OrderBy(c => c.TgNr)
.Select(c => new Transaction(c)) .Select(c => new Transaction(c))
.ToList(); .ToList();

View File

@ -108,7 +108,8 @@ namespace Elwig.Services {
public static async Task<int> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr) { public static async Task<int> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr) {
int newFbNr = (int)vm.FbNr!; int newFbNr = (int)vm.FbNr!;
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var a = new AreaCom { var a = new AreaCom {
FbNr = oldFbNr ?? newFbNr, FbNr = oldFbNr ?? newFbNr,
MgNr = (int)vm.MgNr!, MgNr = (int)vm.MgNr!,
@ -140,7 +141,7 @@ namespace Elwig.Services {
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 SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}");
} }
} });
App.HintContextChange(); App.HintContextChange();
@ -253,5 +254,16 @@ namespace Elwig.Services {
} }
return grid; return grid;
} }
public static async Task DeleteAreaCom(int fbnr) {
await Task.Run(async () => {
using var ctx = new AppDbContext();
var l = (await ctx.AreaCommitments.FindAsync(fbnr))!;
ctx.Remove(l);
await ctx.SaveChangesAsync();
});
App.HintContextChange();
}
} }
} }

View File

@ -430,9 +430,10 @@ namespace Elwig.Services {
} }
public static async Task<DeliveryPart> UpdateDeliveryPart(this DeliveryAdminViewModel vm, int? oldYear, int? oldDid, int? oldDpnr, bool dateHasChanged, bool timeHasChanged, bool timeIsDefault) { public static async Task<DeliveryPart> UpdateDeliveryPart(this DeliveryAdminViewModel vm, int? oldYear, int? oldDid, int? oldDpnr, bool dateHasChanged, bool timeHasChanged, bool timeIsDefault) {
DeliveryPart p; var p = await Task.Run(async () => {
DeliveryPart p;
using (var ctx = new AppDbContext()) { using var ctx = new AppDbContext();
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);
@ -524,7 +525,9 @@ namespace Elwig.Services {
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
}
return p;
});
App.HintContextChange(); App.HintContextChange();
@ -532,9 +535,10 @@ namespace Elwig.Services {
} }
public static async Task<Delivery> SplitDeliveryToMember(int year, int did, int[] weights, int mgnr) { public static async Task<Delivery> SplitDeliveryToMember(int year, int did, int[] weights, int mgnr) {
Delivery n; var n = await Task.Run(async () => {
Delivery n;
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.FindAsync(year, did))!;
var lnr = await ctx.NextLNr(d.Date, d.ZwstId); var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
@ -577,7 +581,9 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
if (!anyLeft) if (!anyLeft)
await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})"); await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
}
return n;
});
App.HintContextChange(); App.HintContextChange();
@ -585,9 +591,9 @@ namespace Elwig.Services {
} }
public static async Task<Delivery> SplitDeliveryToLsNr(int year, int did, int[] weights, string lsnr) { public static async Task<Delivery> SplitDeliveryToLsNr(int year, int did, int[] weights, string lsnr) {
Delivery n; var n = await Task.Run(async () => {
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.FirstAsync(d => d.LsNr == lsnr))!;
var d = (await ctx.Deliveries.FindAsync(year, did))!; var d = (await ctx.Deliveries.FindAsync(year, did))!;
@ -616,7 +622,9 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
if (!anyLeft && n.LsNr != d.LsNr) if (!anyLeft && n.LsNr != d.LsNr)
await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})"); await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
}
return n;
});
App.HintContextChange(); App.HintContextChange();
@ -624,7 +632,8 @@ 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) {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var d = (await ctx.Deliveries.FindAsync(year, did))!; var d = (await ctx.Deliveries.FindAsync(year, did))!;
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)) {
@ -648,21 +657,23 @@ namespace Elwig.Services {
} }
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange(); App.HintContextChange();
} }
public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) { public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
using var ctx = new AppDbContext(); try {
var d = (await ctx.Deliveries.FindAsync(year, did))!; using var ctx = new AppDbContext();
using var doc = new DeliveryNote(d, ctx); var d = (await ctx.Deliveries.FindAsync(year, did))!;
await Utils.ExportDocument(doc, mode, d.LsNr, (d.Member, $"{DeliveryNote.Name} Nr. {d.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {d.LsNr}")); using var doc = new DeliveryNote(d, ctx);
} catch (Exception exc) { await Utils.ExportDocument(doc, mode, d.LsNr, (d.Member, $"{DeliveryNote.Name} Nr. {d.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {d.LsNr}"));
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -707,14 +718,16 @@ namespace Elwig.Services {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig" Title = $"{DeliveryJournal.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await DeliveryJournalData.FromQuery(query, filterNames); try {
using var ods = new OdsFile(d.FileName); var data = await DeliveryJournalData.FromQuery(query, filterNames);
await ods.AddTable(data); using var ods = new OdsFile(d.FileName);
} catch (Exception exc) { await ods.AddTable(data);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
@ -725,58 +738,64 @@ namespace Elwig.Services {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig" Title = $"{DeliveryJournal.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
await ElwigData.Export(d.FileName, await query
.Select(p => p.Delivery)
.Distinct()
.Include(d => d.Parts)
.ThenInclude(p => p.PartModifiers)
.AsSplitQuery()
.ToListAsync(), filterNames);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
await ElwigData.Export(d.FileName, await query var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip";
var path = Path.Combine(App.TempPath, filename);
var list = await query
.Select(p => p.Delivery) .Select(p => p.Delivery)
.Distinct() .Distinct()
.Include(d => d.Parts) .Include(d => d.Parts)
.ThenInclude(p => p.PartModifiers) .ThenInclude(p => p.PartModifiers)
.AsSplitQuery() .AsSplitQuery()
.ToListAsync(), filterNames); .ToListAsync();
if (list.Count == 0) {
MessageBox.Show("Es wurden keine Lieferungen zum Hochladen ausgewählt!", "Lieferungen hochladen",
MessageBoxButton.OK, MessageBoxImage.Error);
} else {
await ElwigData.Export(path, list, filterNames);
await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
MessageBox.Show($"Hochladen von {list.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochgeladen",
MessageBoxButton.OK, MessageBoxImage.Information);
}
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; });
}
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip";
var path = Path.Combine(App.TempPath, filename);
var list = await query
.Select(p => p.Delivery)
.Distinct()
.Include(d => d.Parts)
.ThenInclude(p => p.PartModifiers)
.AsSplitQuery()
.ToListAsync();
if (list.Count == 0) {
MessageBox.Show("Es wurden keine Lieferungen zum Hochladen ausgewählt!", "Lieferungen hochladen",
MessageBoxButton.OK, MessageBoxImage.Error);
} else {
await ElwigData.Export(path, list, filterNames);
await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
MessageBox.Show($"Hochladen von {list.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochgeladen",
MessageBoxButton.OK, MessageBoxImage.Information);
}
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await DeliveryJournalData.FromQuery(query, filterNames); try {
using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data); var data = await DeliveryJournalData.FromQuery(query, filterNames);
await Utils.ExportDocument(doc, mode); using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data);
} catch (Exception exc) { await Utils.ExportDocument(doc, mode);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@ -798,14 +817,16 @@ namespace Elwig.Services {
throw new ArgumentException("Invalid value for ExportSubject"); throw new ArgumentException("Invalid value for ExportSubject");
} }
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList); try {
using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data); var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList);
await Utils.ExportDocument(doc, mode); using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data);
} catch (Exception exc) { await Utils.ExportDocument(doc, mode);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -829,14 +850,16 @@ namespace Elwig.Services {
Title = $"Lieferstatistik pro Ort speichern unter - Elwig" Title = $"Lieferstatistik pro Ort speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
using var ods = new OdsFile(d.FileName); try {
var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames); using var ods = new OdsFile(d.FileName);
await ods.AddTable(tbl); var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames);
} catch (Exception exc) { await ods.AddTable(tbl);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@ -875,33 +898,37 @@ namespace Elwig.Services {
Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig" Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
using var ods = new OdsFile(d.FileName); try {
var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames); using var ods = new OdsFile(d.FileName);
tblTotal.FullName = DeliveryDepreciationList.Name; var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames);
tblTotal.Name = "Gesamt"; tblTotal.FullName = DeliveryDepreciationList.Name;
await ods.AddTable(tblTotal); tblTotal.Name = "Gesamt";
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) { await ods.AddTable(tblTotal);
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames); foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
tbl.FullName = DeliveryDepreciationList.Name; var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
tbl.Name = branch.Name; tbl.FullName = DeliveryDepreciationList.Name;
await ods.AddTable(tbl); tbl.Name = branch.Name;
await ods.AddTable(tbl);
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} catch (Exception exc) { });
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await DeliveryJournalData.FromQuery(query, filterNames); try {
using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data); var data = await DeliveryJournalData.FromQuery(query, filterNames);
await Utils.ExportDocument(doc, mode); using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
} catch (Exception exc) { await Utils.ExportDocument(doc, mode);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@ -1070,10 +1097,12 @@ namespace Elwig.Services {
} }
public static async Task DeleteDelivery(string lsnr) { public static async Task DeleteDelivery(string lsnr) {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
await ctx.Deliveries.Where(d => d.LsNr == lsnr).ExecuteDeleteAsync(); await ctx.Deliveries.Where(d => d.LsNr == lsnr).ExecuteDeleteAsync();
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange(); App.HintContextChange();
} }
} }

View File

@ -367,51 +367,57 @@ namespace Elwig.Services {
} }
public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) { public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
using var ctx = new AppDbContext(); try {
using var doc = new MemberDataSheet(m, ctx); using var ctx = new AppDbContext();
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt")); using var doc = new MemberDataSheet(m, ctx);
} catch (Exception exc) { await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) { public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var b = new Billing(year); try {
await b.FinishSeason(); var b = new Billing(year);
await b.CalculateBuckets(); await b.FinishSeason();
App.HintContextChange(); await b.CalculateBuckets();
App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m); var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m);
using var doc = new DeliveryConfirmation(ctx, year, m, data); 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);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) { public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
using var ctx = new AppDbContext(); try {
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!; using var ctx = new AppDbContext();
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr); var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!; var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr);
var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data); 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], using var doc = new CreditNote(ctx, p, data[m.MgNr],
b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers, b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers,
await ctx.GetMemberUnderDelivery(year, m.MgNr)); 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}")); 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);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -464,14 +470,16 @@ namespace Elwig.Services {
Title = $"{MemberList.Name} speichern unter - Elwig" Title = $"{MemberList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); try {
using var ods = new OdsFile(d.FileName); var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
await ods.AddTable(data); using var ods = new OdsFile(d.FileName);
} catch (Exception exc) { await ods.AddTable(data);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
@ -482,8 +490,33 @@ namespace Elwig.Services {
Title = $"{MemberList.Name} speichern unter - Elwig" Title = $"{MemberList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var members = await query
.OrderBy(m => m.MgNr)
.Include(m => m.BillingAddress)
.Include(m => m.TelephoneNumbers)
.Include(m => m.EmailAddresses)
.AsSplitQuery()
.ToListAsync();
var areaComs = await query
.SelectMany(m => m.AreaCommitments)
.Include(c => c.Rd)
.ToListAsync();
await ElwigData.Export(d.FileName, members, areaComs, filterNames);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip";
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.BillingAddress)
@ -495,99 +528,80 @@ namespace Elwig.Services {
.SelectMany(m => m.AreaCommitments) .SelectMany(m => m.AreaCommitments)
.Include(c => c.Rd) .Include(c => c.Rd)
.ToListAsync(); .ToListAsync();
await ElwigData.Export(d.FileName, members, areaComs, filterNames); if (members.Count == 0) {
MessageBox.Show("Es wurden keine Mitglieder zum Hochladen ausgewählt!", "Mitglieder hochladen",
MessageBoxButton.OK, MessageBoxImage.Error);
} else {
await ElwigData.Export(path, members, areaComs, filterNames);
await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!", "Mitglieder hochgeladen",
MessageBoxButton.OK, MessageBoxImage.Information);
}
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; });
}
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip";
var path = Path.Combine(App.TempPath, filename);
var members = await query
.OrderBy(m => m.MgNr)
.Include(m => m.BillingAddress)
.Include(m => m.TelephoneNumbers)
.Include(m => m.EmailAddresses)
.AsSplitQuery()
.ToListAsync();
var areaComs = await query
.SelectMany(m => m.AreaCommitments)
.Include(c => c.Rd)
.ToListAsync();
if (members.Count == 0) {
MessageBox.Show("Es wurden keine Mitglieder zum Hochladen ausgewählt!", "Mitglieder hochladen",
MessageBoxButton.OK, MessageBoxImage.Error);
} else {
await ElwigData.Export(path, members, areaComs, filterNames);
await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!", "Mitglieder hochgeladen",
MessageBoxButton.OK, MessageBoxImage.Information);
}
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); try {
using var doc = new MemberList(string.Join(" / ", filterNames), data); var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
await Utils.ExportDocument(doc, mode); using var doc = new MemberList(string.Join(" / ", filterNames), data);
} catch (Exception exc) { await Utils.ExportDocument(doc, mode);
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception exc) {
} MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
public static async Task<int> UpdateMember(this MemberAdminViewModel vm, int? oldMgNr) { public static async Task<int> UpdateMember(this MemberAdminViewModel vm, int? oldMgNr) {
var newMgNr = (int)vm.MgNr!; var newMgNr = (int)vm.MgNr!;
var m = new Member {
MgNr = oldMgNr ?? newMgNr,
PredecessorMgNr = vm.PredecessorMgNr,
IsJuridicalPerson = vm.IsJuridicalPerson,
Prefix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Prefix) ? null : vm.Prefix,
GivenName = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.GivenName) ? null : vm.GivenName,
Name = vm.Name!,
Suffix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Suffix) ? null : vm.Suffix,
ForTheAttentionOf = !vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.ForTheAttentionOf) ? null : vm.ForTheAttentionOf,
Birthday = string.IsNullOrEmpty(vm.Birthday) ? null : string.Join("-", vm.Birthday!.Split(".").Reverse()),
IsDeceased = vm.IsDeceased,
CountryNum = 40, // Austria AT AUT
PostalDestId = vm.Ort!.Id,
Address = vm.Address!,
using (var ctx = new AppDbContext()) { Iban = string.IsNullOrEmpty(vm.Iban) ? null : vm.Iban?.Replace(" ", ""),
var m = new Member { Bic = string.IsNullOrEmpty(vm.Bic) ? null : vm.Bic,
MgNr = oldMgNr ?? newMgNr,
PredecessorMgNr = vm.PredecessorMgNr,
IsJuridicalPerson = vm.IsJuridicalPerson,
Prefix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Prefix) ? null : vm.Prefix,
GivenName = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.GivenName) ? null : vm.GivenName,
Name = vm.Name!,
Suffix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Suffix) ? null : vm.Suffix,
ForTheAttentionOf = !vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.ForTheAttentionOf) ? null : vm.ForTheAttentionOf,
Birthday = string.IsNullOrEmpty(vm.Birthday) ? null : string.Join("-", vm.Birthday!.Split(".").Reverse()),
IsDeceased = vm.IsDeceased,
CountryNum = 40, // Austria AT AUT
PostalDestId = vm.Ort!.Id,
Address = vm.Address!,
Iban = string.IsNullOrEmpty(vm.Iban) ? null : vm.Iban?.Replace(" ", ""), UstIdNr = string.IsNullOrEmpty(vm.UstIdNr) ? null : vm.UstIdNr,
Bic = string.IsNullOrEmpty(vm.Bic) ? null : vm.Bic, LfbisNr = string.IsNullOrEmpty(vm.LfbisNr) ? null : vm.LfbisNr,
IsBuchführend = vm.IsBuchführend,
IsOrganic = vm.IsOrganic,
UstIdNr = string.IsNullOrEmpty(vm.UstIdNr) ? null : vm.UstIdNr, EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()),
LfbisNr = string.IsNullOrEmpty(vm.LfbisNr) ? null : vm.LfbisNr, ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()),
IsBuchführend = vm.IsBuchführend, BusinessShares = (int)vm.BusinessShares!,
IsOrganic = vm.IsOrganic, AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr,
IsActive = vm.IsActive,
EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()), IsVollLieferant = vm.IsVollLieferant,
ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()), IsFunktionär = vm.IsFunktionär,
BusinessShares = (int)vm.BusinessShares!, ZwstId = vm.Branch?.ZwstId,
AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr, DefaultKgNr = vm.DefaultKg?.KgNr,
IsActive = vm.IsActive, Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
IsVollLieferant = vm.IsVollLieferant, ContactViaPost = vm.ContactViaPost,
IsFunktionär = vm.IsFunktionär, ContactViaEmail = vm.ContactViaEmail,
ZwstId = vm.Branch?.ZwstId, };
DefaultKgNr = vm.DefaultKg?.KgNr,
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
ContactViaPost = vm.ContactViaPost,
ContactViaEmail = vm.ContactViaEmail,
};
await Task.Run(async () => {
using var ctx = new AppDbContext();
if (oldMgNr != null) { if (oldMgNr != null) {
ctx.Update(m); ctx.Update(m);
} else { } else {
@ -670,7 +684,7 @@ namespace Elwig.Services {
if (newMgNr != m.MgNr) { if (newMgNr != m.MgNr) {
await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}"); await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}");
} }
} });
App.HintContextChange(); App.HintContextChange();
@ -678,7 +692,8 @@ 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) {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var l = (await ctx.Members.FindAsync(mgnr))!; var l = (await ctx.Members.FindAsync(mgnr))!;
if (deletePaymentData) { if (deletePaymentData) {
ctx.RemoveRange(l.Credits); ctx.RemoveRange(l.Credits);
@ -691,7 +706,8 @@ namespace Elwig.Services {
} }
ctx.Remove(l); ctx.Remove(l);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange(); App.HintContextChange();
} }
} }

View File

@ -203,13 +203,9 @@ namespace Elwig.Windows {
$"Soll die Flächenbindung {a.GstNr} ({a.Area} m²) wirklich unwiderruflich gelöscht werden?", $"Soll die Flächenbindung {a.GstNr} ({a.Area} m²) wirklich unwiderruflich gelöscht werden?",
"Flächenbindung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Flächenbindung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using (var ctx = new AppDbContext()) { await AreaComService.DeleteAreaCom(a.FbNr);
ctx.Remove(a);
await ctx.SaveChangesAsync();
}
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@ -227,7 +223,7 @@ namespace Elwig.Windows {
private async void AreaCommitmentSaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void AreaCommitmentSaveButton_Click(object? sender, RoutedEventArgs? evt) {
AreaCommitmentSaveButton.IsEnabled = false; AreaCommitmentSaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
int fbnr; int fbnr;
try { try {
@ -237,9 +233,8 @@ namespace Elwig.Windows {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
AreaCommitmentSaveButton.IsEnabled = true; AreaCommitmentSaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@ -252,6 +247,7 @@ namespace Elwig.Windows {
FinishInputFilling(); FinishInputFilling();
await RefreshList(); await RefreshList();
RefreshInputs(); RefreshInputs();
Mouse.OverrideCursor = null;
ViewModel.SearchQuery = ""; ViewModel.SearchQuery = "";
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault()); ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault());
} }

View File

@ -157,7 +157,7 @@ namespace Elwig.Windows {
} }
var d = new NewSeasonDialog(s, currencies); var d = new NewSeasonDialog(s, currencies);
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
ctx.Add(new Season { ctx.Add(new Season {
@ -209,7 +209,7 @@ namespace Elwig.Windows {
$"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?", $"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?",
"Saison löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Saison löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
ctx.Remove(s); ctx.Remove(s);

View File

@ -318,8 +318,7 @@ namespace Elwig.Windows {
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Save(); await Save();
} catch (Exception exc) { } catch (Exception exc) {
@ -327,9 +326,8 @@ namespace Elwig.Windows {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Stammdaten aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Stammdaten aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@ -349,6 +347,7 @@ namespace Elwig.Windows {
} }
App.HintContextChange(); App.HintContextChange();
Mouse.OverrideCursor = null;
} }
private void FillInputs(ClientParameters p, Season? s) { private void FillInputs(ClientParameters p, Season? s) {

View File

@ -225,30 +225,8 @@ namespace Elwig.Windows {
DataPlot.Color = ColorUngebunden; DataPlot.Color = ColorUngebunden;
DataPlot.MarkerStyle = new MarkerStyle(MarkerShape.FilledCircle, 9, ColorUngebunden); DataPlot.MarkerStyle = new MarkerStyle(MarkerShape.FilledCircle, 9, ColorUngebunden);
//OechslePricePlot.Interaction.Enable(new PlotActions() {
// ZoomIn = StandardActions.ZoomIn,
// ZoomOut = StandardActions.ZoomOut,
// PanUp = StandardActions.PanUp,
// PanDown = StandardActions.PanDown,
// PanLeft = StandardActions.PanLeft,
// PanRight = StandardActions.PanRight,
// DragPan = StandardActions.DragPan,
// DragZoom = StandardActions.DragZoom,
// DragZoomRectangle = StandardActions.DragZoomRectangle,
// ZoomRectangleClear = StandardActions.ZoomRectangleClear,
// ZoomRectangleApply = StandardActions.ZoomRectangleApply,
// AutoScale = StandardActions.AutoScale,
//});
//OechslePricePlot.Plot.XAxis.ManualTickSpacing(1);
//OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1);
OechslePricePlot.Plot.Axes.SetLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 1.5); OechslePricePlot.Plot.Axes.SetLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 1.5);
//OechslePricePlot.Plot.Layout(padding: 0);
//OechslePricePlot.Plot.XAxis2.Layout(padding: 0);
//OechslePricePlot.Plot.YAxis.Layout(padding: 0);
//OechslePricePlot.Plot.YAxis2.Layout(padding: 0);
HighlightedPointPlot = OechslePricePlot.Plot.Add.Marker(0, 0, MarkerShape.OpenCircle, 10, Colors.Red); HighlightedPointPlot = OechslePricePlot.Plot.Add.Marker(0, 0, MarkerShape.OpenCircle, 10, Colors.Red);
HighlightedPointPlot.IsVisible = false; HighlightedPointPlot.IsVisible = false;

View File

@ -310,19 +310,23 @@ namespace Elwig.Windows {
UnsetDefaultValue(GerebeltGewogenInput); UnsetDefaultValue(GerebeltGewogenInput);
} }
if (!App.Client.HasNetWeighing(ViewModel.Branch)) { if (App.Client.HasBoxWeighing(ViewModel.Branch)) {
LesewagenInput.IsEnabled = false; LesewagenInput.IsEnabled = false;
SetDefaultValue(LesewagenInput, false); SetDefaultValue(LesewagenInput, false);
HandPickedInput.IsThreeState = false;
UnsetDefaultValue(HandPickedInput);
} else { } else {
LesewagenInput.IsEnabled = true; LesewagenInput.IsEnabled = true;
UnsetDefaultValue(LesewagenInput); UnsetDefaultValue(LesewagenInput);
}
if (!App.Client.HasNetWeighing(ViewModel.Branch)) {
HandPickedInput.IsThreeState = false;
UnsetDefaultValue(HandPickedInput);
} else {
HandPickedInput.IsThreeState = true; HandPickedInput.IsThreeState = true;
SetDefaultValue(HandPickedInput, null); SetDefaultValue(HandPickedInput, null);
} }
if (App.Client.IsMatzen || App.Client.IsWinzerkeller) { if (App.Client.IsMatzen || App.Client.IsWinzerkeller || App.Client.IsBaden || App.Client.IsWeinland) {
GebundenInput.IsEnabled = false; GebundenInput.IsEnabled = false;
SetDefaultValue(GebundenInput, null); SetDefaultValue(GebundenInput, null);
} else { } else {
@ -715,7 +719,7 @@ namespace Elwig.Windows {
private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
FinishButton.IsEnabled = false; FinishButton.IsEnabled = false;
NewDeliveryPartButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
DeliveryPartList.IsEnabled = false; DeliveryPartList.IsEnabled = false;
DeliveryPart? p; DeliveryPart? p;
@ -753,7 +757,7 @@ namespace Elwig.Windows {
private async void FinishButton_Click(object sender, RoutedEventArgs evt) { private async void FinishButton_Click(object sender, RoutedEventArgs evt) {
FinishButton.IsEnabled = false; FinishButton.IsEnabled = false;
NewDeliveryPartButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
DeliveryPartList.IsEnabled = false; DeliveryPartList.IsEnabled = false;
DeliveryPart? p; DeliveryPart? p;
@ -884,7 +888,7 @@ namespace Elwig.Windows {
if (res == null) if (res == null)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
var id = res.Value.Item1; var id = res.Value.Item1;
var weights = res.Value.Item2; var weights = res.Value.Item2;
@ -955,7 +959,7 @@ namespace Elwig.Windows {
$"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?", $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?",
"Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await DeliveryService.DeleteDelivery(d.LsNr); await DeliveryService.DeleteDelivery(d.LsNr);
} catch (Exception exc) { } catch (Exception exc) {
@ -975,7 +979,7 @@ namespace Elwig.Windows {
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
DeliveryPart? p; DeliveryPart? p;
try { try {
@ -992,9 +996,8 @@ namespace Elwig.Windows {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@ -1011,6 +1014,7 @@ namespace Elwig.Windows {
await RefreshDeliveryParts(); await RefreshDeliveryParts();
RefreshInputs(); RefreshInputs();
Mouse.OverrideCursor = null;
DepreciateButton.IsEnabled = true; DepreciateButton.IsEnabled = true;
} }
@ -1380,7 +1384,7 @@ namespace Elwig.Windows {
} }
private void GerebeltGewogenInput_Changed(object sender, RoutedEventArgs evt) { private void GerebeltGewogenInput_Changed(object sender, RoutedEventArgs evt) {
if (!App.Client.HasNetWeighing(ViewModel.Branch)) { if ((IsEditing || IsCreating) && !App.Client.HasNetWeighing(ViewModel.Branch)) {
HandPickedInput.IsChecked = !GerebeltGewogenInput.IsChecked; HandPickedInput.IsChecked = !GerebeltGewogenInput.IsChecked;
} }
if (!ViewModel.IsReceipt || App.Client.HasNetWeighing(ViewModel.Branch)) { if (!ViewModel.IsReceipt || App.Client.HasNetWeighing(ViewModel.Branch)) {
@ -1390,7 +1394,7 @@ namespace Elwig.Windows {
} }
private void HandPickedInput_Changed(object sender, RoutedEventArgs evt) { private void HandPickedInput_Changed(object sender, RoutedEventArgs evt) {
if (!App.Client.HasNetWeighing(ViewModel.Branch)) { if ((IsEditing || IsCreating) && !App.Client.HasNetWeighing(ViewModel.Branch)) {
GerebeltGewogenInput.IsChecked = !HandPickedInput.IsChecked; GerebeltGewogenInput.IsChecked = !HandPickedInput.IsChecked;
} }
CheckBox_Changed(sender, evt); CheckBox_Changed(sender, evt);

View File

@ -19,6 +19,7 @@ namespace Elwig.Windows {
} }
private async void TimeSpanInput_SelectionChanged(object sender, RoutedEventArgs evt) { private async void TimeSpanInput_SelectionChanged(object sender, RoutedEventArgs evt) {
if (!IsLoaded) return;
DateTime? fromDate = DateTime.Now; DateTime? fromDate = DateTime.Now;
if (TimeSpanInput.SelectedIndex == 0) { if (TimeSpanInput.SelectedIndex == 0) {
fromDate = fromDate.Value.AddDays(-7); fromDate = fromDate.Value.AddDays(-7);
@ -50,6 +51,7 @@ namespace Elwig.Windows {
} }
private void ApplyFilters() { private void ApplyFilters() {
if (!IsLoaded) return;
var filters = FilterInput.Text.Split(' '); var filters = FilterInput.Text.Split(' ');
IEnumerable<Row> data = Data; IEnumerable<Row> data = Data;
switch (TypeInput.SelectedIndex) { switch (TypeInput.SelectedIndex) {

View File

@ -62,7 +62,7 @@ namespace Elwig.Windows {
} }
private async void Menu_Help_Smtp_Click(object sender, RoutedEventArgs evt) { private async void Menu_Help_Smtp_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var client = await Utils.GetSmtpClient(); using var client = await Utils.GetSmtpClient();
await client!.DisconnectAsync(true); await client!.DisconnectAsync(true);
@ -133,8 +133,10 @@ namespace Elwig.Windows {
Multiselect = true, Multiselect = true,
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await ElwigData.Import(d.FileNames, ElwigData.ImportMode.Interactively); await Task.Run(async () => {
await ElwigData.Import(d.FileNames, ElwigData.ImportMode.Interactively);
});
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
@ -145,77 +147,81 @@ namespace Elwig.Windows {
private async void DownloadButton_Click(object sender, RoutedEventArgs evt) { private async void DownloadButton_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) if (App.Config.SyncUrl == null)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); try {
var files = data var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
.Select(f => new { var files = data
Name = f!["name"]!.AsValue().GetValue<string>(), .Select(f => new {
Timestamp = f!["timestamp"] != null && DateTime.TryParseExact(f!["timestamp"]!.AsValue().GetValue<string>(), "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? dt : (DateTime?)null, Name = f!["name"]!.AsValue().GetValue<string>(),
ZwstId = f!["meta"]?["zwstid"]?.AsValue().GetValue<string>() ?? f!["zwstid"]?.AsValue().GetValue<string>(), Timestamp = f!["timestamp"] != null && DateTime.TryParseExact(f!["timestamp"]!.AsValue().GetValue<string>(), "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? dt : (DateTime?)null,
Device = f!["meta"]?["device"]!.AsValue().GetValue<string>(), ZwstId = f!["meta"]?["zwstid"]?.AsValue().GetValue<string>() ?? f!["zwstid"]?.AsValue().GetValue<string>(),
Url = f!["url"]!.AsValue().GetValue<string>(), Device = f!["meta"]?["device"]!.AsValue().GetValue<string>(),
Size = f!["size"]!.AsValue().GetValue<long>(), Url = f!["url"]!.AsValue().GetValue<string>(),
}) Size = f!["size"]!.AsValue().GetValue<long>(),
.Where(f => f.Timestamp >= new DateTime(Utils.CurrentLastSeason, 7, 1)) })
.ToList(); .Where(f => f.Timestamp >= new DateTime(Utils.CurrentLastSeason, 7, 1))
.ToList();
var imported = await ElwigData.GetImportedFiles(); var imported = await ElwigData.GetImportedFiles();
var import = files var import = files
.Where(f => f.Device != Environment.MachineName && !imported.Contains(f.Name)) .Where(f => f.Device != Environment.MachineName && !imported.Contains(f.Name))
.ToList(); .ToList();
var paths = new List<string>(); var paths = new List<string>();
using (var client = Utils.GetHttpClient(App.Config.SyncUsername, App.Config.SyncPassword)) { using (var client = Utils.GetHttpClient(App.Config.SyncUsername, App.Config.SyncPassword)) {
foreach (var f in import) { foreach (var f in import) {
var filename = Path.Combine(App.TempPath, f.Name); var filename = Path.Combine(App.TempPath, f.Name);
using var stream = new FileStream(filename, FileMode.Create); using var stream = new FileStream(filename, FileMode.Create);
await client.DownloadAsync(f.Url, stream); await client.DownloadAsync(f.Url, stream);
paths.Add(filename); paths.Add(filename);
}
} }
await ElwigData.Import(paths, ElwigData.ImportMode.FromBranches);
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
await ElwigData.Import(paths, ElwigData.ImportMode.FromBranches); });
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
private async void UploadButton_Click(object sender, RoutedEventArgs evt) { private async void UploadButton_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) if (App.Config.SyncUrl == null)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip"); try {
using var ctx = new AppDbContext(); var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
var deliveries = await ctx.Deliveries using var ctx = new AppDbContext();
.Where(d => d.Year == Utils.CurrentLastSeason && d.ZwstId == App.ZwstId) var deliveries = await ctx.Deliveries
.Include(d => d.Parts) .Where(d => d.Year == Utils.CurrentLastSeason && d.ZwstId == App.ZwstId)
.ThenInclude(p => p.PartModifiers) .Include(d => d.Parts)
.OrderBy(d => d.DateString) .ThenInclude(p => p.PartModifiers)
.ThenBy(d => d.TimeString) .OrderBy(d => d.DateString)
.ThenBy(d => d.LsNr) .ThenBy(d => d.TimeString)
.AsSplitQuery() .ThenBy(d => d.LsNr)
.ToListAsync(); .AsSplitQuery()
if (deliveries.Count == 0) { .ToListAsync();
MessageBox.Show("Es gibt keine Lieferungen, die hochgeladen werden können!", "Lieferungen hochladen", if (deliveries.Count == 0) {
MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("Es gibt keine Lieferungen, die hochgeladen werden können!", "Lieferungen hochladen",
} else { MessageBoxButton.OK, MessageBoxImage.Error);
await ElwigData.Export(path, deliveries, [$"{Utils.CurrentLastSeason}", $"Zweigstelle {App.BranchName}"]); } else {
await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); await ElwigData.Export(path, deliveries, [$"{Utils.CurrentLastSeason}", $"Zweigstelle {App.BranchName}"]);
MessageBox.Show($"Hochladen von {deliveries.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochladen", await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
MessageBoxButton.OK, MessageBoxImage.Information); MessageBox.Show($"Hochladen von {deliveries.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochladen",
MessageBoxButton.OK, MessageBoxImage.Information);
}
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} catch (HttpRequestException exc) { });
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -270,24 +276,31 @@ namespace Elwig.Windows {
AreaCommitmentsButton.IsEnabled = valid; AreaCommitmentsButton.IsEnabled = valid;
BreakdownMemberVarietyButton.IsEnabled = valid; BreakdownMemberVarietyButton.IsEnabled = valid;
SeasonStatMembersTotal.Text = "-";
SeasonStatMembersGeb.Text = "-";
SeasonStatWeightTotal.Text = "-";
SeasonStatWeightGeb.Text = "-";
SeasonStatWeightUngeb.Text = "-";
SeasonStatArea.Text = "-";
if (valid) { if (valid) {
var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value); await Task.Run(async () => {
var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight); var membersTotal = await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync();
var gebWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value); var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value);
SeasonStatMembersTotal.Text = $"{await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync():N0}"; var membersGeb = await areaComs.Select(c => c.Member).Distinct().CountAsync();
SeasonStatMembersGeb.Text = $"{await areaComs.Select(c => c.Member).Distinct().CountAsync():N0}"; var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight);
SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg"; var gebWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value);
SeasonStatWeightGeb.Text = $"{gebWeight:N0} kg"; var area = await areaComs.SumAsync(c => c.Area);
SeasonStatWeightUngeb.Text = $"{weightTotal - gebWeight:N0} kg"; await App.MainDispatcher.BeginInvoke(() => {
SeasonStatArea.Text = $"{await areaComs.SumAsync(c => c.Area):N0} m²"; if (year != SeasonInput.Value) return;
} else { SeasonStatMembersTotal.Text = $"{membersTotal:N0}";
SeasonStatMembersTotal.Text = "-"; SeasonStatMembersGeb.Text = $"{membersGeb:N0}";
SeasonStatMembersGeb.Text = "-"; SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg";
SeasonStatWeightTotal.Text = "-"; SeasonStatWeightGeb.Text = $"{gebWeight:N0} kg";
SeasonStatWeightGeb.Text = "-"; SeasonStatWeightUngeb.Text = $"{weightTotal - gebWeight:N0} kg";
SeasonStatWeightUngeb.Text = "-"; SeasonStatArea.Text = $"{area:N0} m²";
SeasonStatArea.Text = "-"; });
} });
};
} }
private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) { private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) {
@ -315,22 +328,24 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var b = new Billing(year); try {
await b.FinishSeason(); var b = new Billing(year);
await b.CalculateBuckets(); await b.FinishSeason();
App.HintContextChange(); await b.CalculateBuckets();
App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year); var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year);
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year); var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
await ods.AddTable(tbl1); await ods.AddTable(tbl1);
await ods.AddTable(tbl2); await ods.AddTable(tbl2);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -346,24 +361,26 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var b = new Billing(year); try {
await b.FinishSeason(); var b = new Billing(year);
await b.CalculateBuckets(); await b.FinishSeason();
App.HintContextChange(); await b.CalculateBuckets();
App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
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.Branches.OrderBy(b => b.Name).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);
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} catch (Exception exc) { });
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -379,20 +396,22 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var b = new Billing(year); try {
await b.FinishSeason(); var b = new Billing(year);
await b.CalculateBuckets(); await b.FinishSeason();
App.HintContextChange(); await b.CalculateBuckets();
App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year); var tbl = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
await ods.AddTable(tbl); await ods.AddTable(tbl);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@ -408,20 +427,22 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { await Task.Run(async () => {
var b = new Billing(year); try {
await b.FinishSeason(); var b = new Billing(year);
await b.CalculateBuckets(); await b.FinishSeason();
App.HintContextChange(); await b.CalculateBuckets();
App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl = await MemberDeliveryPerVarietyData.ForSeason(ctx.MemberDeliveryPerVariantRows, year); var tbl = await MemberDeliveryPerVarietyData.ForSeason(ctx.MemberDeliveryPerVariantRows, year);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
await ods.AddTable(tbl); await ods.AddTable(tbl);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }

View File

@ -389,7 +389,7 @@ namespace Elwig.Windows {
} }
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) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs); await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
} catch (Exception exc) { } catch (Exception exc) {
@ -408,7 +408,7 @@ namespace Elwig.Windows {
} }
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
int mgnr; int mgnr;
@ -419,9 +419,8 @@ namespace Elwig.Windows {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Mitglied aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Mitglied aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@ -436,6 +435,7 @@ namespace Elwig.Windows {
await RefreshList(); await RefreshList();
RefreshInputs(); RefreshInputs();
ViewModel.SearchQuery = ""; ViewModel.SearchQuery = "";
Mouse.OverrideCursor = null;
if (mgnr is int m) if (mgnr is int m)
FocusMember(m); FocusMember(m);
} }
@ -491,15 +491,17 @@ namespace Elwig.Windows {
private async void Menu_Contact_Letterhead_Click(object sender, RoutedEventArgs evt) { private async void Menu_Contact_Letterhead_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return; if (ViewModel.SelectedMember is not Member m) return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var doc = new Letterhead(m); await Task.Run(async () => {
await doc.Generate(); using var doc = new Letterhead(m);
if (!App.Config.Debug) { await doc.Generate();
await doc.Print(); if (!App.Config.Debug) {
} else { await doc.Print();
doc.Show(); } else {
} doc.Show();
}
});
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }

View File

@ -140,8 +140,9 @@
<TextBox x:Name="CommentInput" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,40,10,0" <TextBox x:Name="CommentInput" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,40,10,0"
TextChanged="CommentInput_TextChanged"/> TextChanged="CommentInput_TextChanged"/>
<Label Content="Erstellt am:" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="Datum:" Margin="10,70,0,0" Grid.Column="0"/>
<TextBox x:Name="DateInput" Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,70,10,0" IsReadOnly="True"/> <TextBox x:Name="DateInput" Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,70,10,0"
TextChanged="DateInput_TextChanged"/>
<Label Content="Überwiesen am:" Margin="10,100,0,0" Grid.Column="0"/> <Label Content="Überwiesen am:" Margin="10,100,0,0" Grid.Column="0"/>
<TextBox x:Name="TransferDateInput" Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,100,10,0" <TextBox x:Name="TransferDateInput" Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,100,10,0"

View File

@ -19,7 +19,7 @@ namespace Elwig.Windows {
public readonly int Year; public readonly int Year;
public readonly bool SeasonLocked; public readonly bool SeasonLocked;
private bool DataValid, DataChanged, NameChanged, CommentChanged, TransferDateValid, TransferDateChanged; private bool DataValid, DataChanged, NameChanged, CommentChanged, DateValid, DateChanged, TransferDateValid, TransferDateChanged;
private BillingData? BillingData; private BillingData? BillingData;
private bool WeightModifierChanged = false; private bool WeightModifierChanged = false;
@ -175,6 +175,7 @@ namespace Elwig.Windows {
private void UpdateSaveButton() { private void UpdateSaveButton() {
SaveButton.IsEnabled = PaymentVariantList.SelectedItem != null && SaveButton.IsEnabled = PaymentVariantList.SelectedItem != null &&
((DataChanged && DataValid) || NameChanged || CommentChanged || ((DataChanged && DataValid) || NameChanged || CommentChanged ||
(DateChanged && DateValid) ||
(TransferDateChanged && TransferDateValid) || (TransferDateChanged && TransferDateValid) ||
(ConsiderModifiersInput.IsChecked != BillingData?.ConsiderDelieryModifiers) || (ConsiderModifiersInput.IsChecked != BillingData?.ConsiderDelieryModifiers) ||
(ConsiderPenaltiesInput.IsChecked != BillingData?.ConsiderContractPenalties) || (ConsiderPenaltiesInput.IsChecked != BillingData?.ConsiderContractPenalties) ||
@ -433,10 +434,16 @@ namespace Elwig.Windows {
var withoutIban = v.Credits.Count(c => c.Member.Iban == null); var withoutIban = v.Credits.Count(c => c.Member.Iban == null);
if (withoutIban > 0) { if (withoutIban > 0) {
var r = MessageBox.Show($"Achtung: Für {withoutIban} Mitglieder ist kein IBAN hinterlegt.\nDiese werden NICHT exportiert.", var r = MessageBox.Show($"Achtung: Für {withoutIban:N0} Mitglieder ist kein IBAN hinterlegt.\n\nDiese werden NICHT exportiert.",
"Mitglieder ohne IBAN", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Mitglieder ohne IBAN", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r != MessageBoxResult.OK) return; if (r != MessageBoxResult.OK) return;
} }
var withNegAmount = v.Credits.Count(c => c.Amount <= 0);
if (withNegAmount > 0) {
var r = MessageBox.Show($"Achtung: Es gibt {withNegAmount:N0} Traubengutschriften mit negativem Betrag.\n\nDiese werden NICHT exportiert.",
"Traubengutschriften mit negativem Betrag", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.OK);
if (r != MessageBoxResult.OK) return;
}
var d = new SaveFileDialog() { var d = new SaveFileDialog() {
FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}", FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}",
@ -489,6 +496,7 @@ namespace Elwig.Windows {
try { try {
v.Name = NameInput.Text; v.Name = NameInput.Text;
v.Comment = (CommentInput.Text != "") ? CommentInput.Text : null; v.Comment = (CommentInput.Text != "") ? CommentInput.Text : null;
v.DateString = string.Join("-", DateInput.Text.Split(".").Reverse());
v.TransferDateString = (TransferDateInput.Text != "") ? string.Join("-", TransferDateInput.Text.Split(".").Reverse()) : null; v.TransferDateString = (TransferDateInput.Text != "") ? string.Join("-", TransferDateInput.Text.Split(".").Reverse()) : null;
var d = App.Config.Debug ? BillingData.FromJson(DataInput.Text) : BillingData; var d = App.Config.Debug ? BillingData.FromJson(DataInput.Text) : BillingData;
d.ConsiderDelieryModifiers = ConsiderModifiersInput.IsChecked ?? false; d.ConsiderDelieryModifiers = ConsiderModifiersInput.IsChecked ?? false;
@ -557,6 +565,27 @@ namespace Elwig.Windows {
UpdateSaveButton(); UpdateSaveButton();
} }
private void DateInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(DateInput);
return;
}
var res = Validator.CheckDate(DateInput, true);
if (!res.IsValid) {
ControlUtils.SetInputInvalid(DateInput);
DateValid = false;
} else if (DateInput.Text != $"{v.Date:dd.MM.yyyy}") {
ControlUtils.SetInputChanged(DateInput);
DateValid = true;
DateChanged = true;
} else {
ControlUtils.ClearInputState(DateInput);
DateValid = true;
DateChanged = false;
}
UpdateSaveButton();
}
private void TransferDateInput_TextChanged(object sender, TextChangedEventArgs evt) { private void TransferDateInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) { if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(TransferDateInput); ControlUtils.ClearInputState(TransferDateInput);

View File

@ -1,4 +1,4 @@
<Project Sdk="WixToolset.Sdk/5.0.0"> <Project Sdk="WixToolset.Sdk/6">
<PropertyGroup> <PropertyGroup>
<HarvestFileSuppressUniqueIds>false</HarvestFileSuppressUniqueIds> <HarvestFileSuppressUniqueIds>false</HarvestFileSuppressUniqueIds>
<HarvestFileGenerateGuidsNow>true</HarvestFileGenerateGuidsNow> <HarvestFileGenerateGuidsNow>true</HarvestFileGenerateGuidsNow>
@ -37,4 +37,4 @@
<None Include="Files\config.ini" /> <None Include="Files\config.ini" />
<None Include="Files\WinziPrint.exe" /> <None Include="Files\WinziPrint.exe" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -2,3 +2,6 @@
Elwig Elwig
===== =====
**El**ektronische **Wi**nzer**g**enossenschaftsverwaltung (Electronic Management for Vintners' Cooperatives).
Further information may be found on [the website](https://elwig.at).

View File

@ -1,4 +1,6 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
<Bundle Name="Elwig" Manufacturer="Elwig" Version="!(bind.packageVersion.ElwigMsi)" UpgradeCode="f3c8fcab-c37c-43aa-9ab8-e42f4bb518b7" <Bundle Name="Elwig" Manufacturer="Elwig" Version="!(bind.packageVersion.ElwigMsi)" UpgradeCode="f3c8fcab-c37c-43aa-9ab8-e42f4bb518b7"
IconSourceFile="$(var.ElwigProjectDir)\Resources\Images\Elwig.ico"> IconSourceFile="$(var.ElwigProjectDir)\Resources\Images\Elwig.ico">
<BootstrapperApplication> <BootstrapperApplication>

View File

@ -1,4 +1,4 @@
<Project Sdk="WixToolset.Sdk/5.0.0"> <Project Sdk="WixToolset.Sdk/6">
<PropertyGroup> <PropertyGroup>
<OutputType>Bundle</OutputType> <OutputType>Bundle</OutputType>
<OutputName>Elwig</OutputName> <OutputName>Elwig</OutputName>
@ -13,7 +13,7 @@
</Target> </Target>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Installer\Installer.wixproj" /> <ProjectReference Include="..\Installer\Installer.wixproj" />
<PackageReference Include="WixToolset.Bal.wixext" Version="5.0.2" /> <PackageReference Include="WixToolset.Bal.wixext" Version="6.0.0" />
<PackageReference Include="WixToolset.Util.wixext" Version="5.0.2" /> <PackageReference Include="WixToolset.Util.wixext" Version="6.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -972,5 +972,67 @@ namespace Tests.HelperTests {
} }
""")); """));
} }
private static IEnumerable<List<T>> GetPermutations<T>(T[] input) {
if (input.Length <= 1)
yield return [..input];
for (int i = 0; i < input.Length; i++) {
yield return [input[i]];
foreach (var p in GetPermutations(input.Where((_, j) => j != i).ToArray())) {
p.Insert(0, input[i]);
yield return p;
}
}
}
private static IEnumerable<List<HashSet<RawVaribute>>> GetCurves(RawVaribute[] vaributes, int minNumCurves = 1, int maxNumCurves = 10) {
foreach (var p in GetPermutations(vaributes)) {
for (int nCurves = minNumCurves; nCurves <= Math.Min(maxNumCurves, p.Count); nCurves++) {
yield return Enumerable.Range(0, nCurves)
.Select(n => p.Where((v, idx) => idx % nCurves == n).ToHashSet())
.ToList();
}
}
}
private readonly HashSet<string> TestedCurves = [];
private void TestCollapse(List<HashSet<RawVaribute>> curves) {
var str = string.Join("\n", curves.Select(c => string.Join(" ", c.Select(v => v.ToString().PadRight(6)).Order())).Order().Select((c, n) => $"{n + 1}: [ " + c + " ]"));
if (!TestedCurves.Add(str))
return;
var vaributes = curves.SelectMany(v => v).ToList();
List<GraphEntry> entries = curves
.Select((l, n) => new GraphEntry(n, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = n + 1,
}, null), GetSelection(l.Select(v => v.ToString()))))
.ToList();
var data = BillingData.FromGraphEntries(entries);
var test = PaymentBillingData.FromJson(data.ToJsonString(), vaributes);
for (int i = 0; i < curves.Count; i++) {
foreach (var v in curves[i]) {
var val = test.CalculatePrice(v.SortId!, v.AttrId, v.CultId, "QUW", false, 73.0, 15.0);
var actualCurve = (int)val;
Assert.That(actualCurve, Is.EqualTo(i + 1), $"Invalid: {v} (Curve {i + 1} -> {actualCurve})\n\n{str}\n\n{data.ToJsonString(JsonOpts)}\n");
}
}
}
[Test]
public void TestCollapse_01_Permutations() {
RawVaribute[][] configurations = [
[new("GV/-"), new("WR/-"), new("ZW/-"), new("GV/K-"), new("WR/K-"), new("ZW/K-")],
[new("GV/-"), new("WR/-"), new("GV/K-"), new("WR/K-"), new("GV/S-"), new("WR/S-")],
[new("GV/-"), new("WR/-"), new("ZW/-"), new("GV/-B"), new("WR/-B"), new("ZW/-B")],
[new("GV/-"), new("WR/-"), new("GV/-B"), new("WR/-B"), new("GV/-KIP"), new("WR/-KIP")],
[new("GV/-"), new("GV/K-"), new("ZW/-"), new("ZW/K-"), new("GV/-B"), new("GV/K-B"), new("ZW/-B"), new("ZW/K-B")],
];
Assert.Multiple(() => {
foreach (var config in configurations) {
foreach (var c in GetCurves(config))
TestCollapse(c);
}
});
}
} }
} }

View File

@ -19,16 +19,16 @@
</Target> </Target>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.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.3.2" /> <PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" /> <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.6.0"> <PackageReference Include="NUnit.Analyzers" Version="4.7.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="6.0.3"> <PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>