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}
------------------------------------------
### 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.
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)
@ -23,12 +58,12 @@ Changelog
[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 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)
@ -40,12 +75,12 @@ Changelog
[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 _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)
@ -57,17 +92,17 @@ Changelog
[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_ 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)
### 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)
### Sonstiges {#0.13.3-misc}
### Sonstiges {#v0.13.3-misc}
* 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)
@ -81,17 +116,17 @@ Changelog
[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)
### Behobene Fehler {#0.13.2-bugfixes}
### Behobene Fehler {#v0.13.2-bugfixes}
* Fehler im Waagenprotokoll `Avery-Async` (L320) behoben. (8680e51052)
* Hausnummern in der BKI Traubentransportscheinliste werden in Excel richtig angezeigt. (86f7f693a0)
* Beim Ändern der Identifikatoren von Attributen/Bewirtschaftungsarten wurden diese in Auszahlungsvarianten nicht aktualisiert. (d1f67dc57d)
### Sonstiges {#0.13.2-misc}
### Sonstiges {#v0.13.2-misc}
* Weitere automatisierte Tests hinzugefügt. ([#11][i11])
* 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}
------------------------------------------
### 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)
### 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)
### Sonstiges {#0.13.1-misc}
### Sonstiges {#v0.13.1-misc}
* Abhängigkeiten aktualisiert. (b6ae1f5675)
@ -130,7 +165,7 @@ Changelog
> [!NOTE]
> 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)

View File

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

View File

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

View File

@ -306,7 +306,8 @@ namespace Elwig.Helpers.Billing {
if ((ks.Count > vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) {
foreach (var k in ks) {
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;
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()) {
foreach (var k in ks) {
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;
CollapsePaymentData(data, originalData, vaributes, useDefault);
@ -371,6 +373,15 @@ namespace Elwig.Helpers.Billing {
} else if (k.Contains("/-")) {
data.Remove(k, out var 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,
v.avnr,
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,
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.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) +
IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0)
AS modifiers,
lc.modifiers AS prev_modifiers
IIF(lc.amount >= 0, lc.modifiers, 0) AS prev_modifiers
FROM season s
JOIN payment_variant v ON v.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() => 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 NameShort;
public string Name;

View File

@ -434,8 +434,7 @@ namespace Elwig.Helpers {
if (accept != null)
client.DefaultRequestHeaders.Accept.Add(new(accept));
if (username != null || password != null)
client.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String(
Utils.UTF8.GetBytes($"{username}:{password}")));
client.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String(Utils.UTF8.GetBytes($"{username}:{password}")));
return client;
}
@ -454,6 +453,8 @@ namespace Elwig.Helpers {
}
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 += "/";
using var client = GetHttpClient(username, password, accept: "application/json");
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) {
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 res = await client.GetAsync(url);
res.EnsureSuccessStatusCode();
@ -496,34 +499,39 @@ namespace Elwig.Helpers {
if (App.Config.Smtp == null)
return false;
SmtpClient? client = null;
try {
Mouse.OverrideCursor = Cursors.AppStarting;
client = await GetSmtpClient();
Mouse.OverrideCursor = Cursors.Wait;
using var msg = new MimeMessage();
msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From));
msg.To.AddRange(member.EmailAddresses.OrderBy(a => a.Nr).Select(a => new MailboxAddress(member.AdministrativeName, a.Address)));
msg.Subject = subject;
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"));
var success = await Task.Run(async () => {
SmtpClient? client = null;
try {
client = await GetSmtpClient();
using var msg = new MimeMessage();
msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From));
msg.To.AddRange(member.EmailAddresses.OrderBy(a => a.Nr).Select(a => new MailboxAddress(member.AdministrativeName, a.Address)));
msg.Subject = subject;
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;
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();
Mouse.OverrideCursor = null;
}
return true;
return true;
});
Mouse.OverrideCursor = null;
return success;
}
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) {
return variant.Credits
.Where(c => c.Member.Iban != null)
.Where(c => c.Member.Iban != null && c.Amount > 0)
.OrderBy(c => c.TgNr)
.Select(c => new Transaction(c))
.ToList();

View File

@ -108,7 +108,8 @@ namespace Elwig.Services {
public static async Task<int> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr) {
int newFbNr = (int)vm.FbNr!;
using (var ctx = new AppDbContext()) {
await Task.Run(async () => {
using var ctx = new AppDbContext();
var a = new AreaCom {
FbNr = oldFbNr ?? newFbNr,
MgNr = (int)vm.MgNr!,
@ -140,7 +141,7 @@ namespace Elwig.Services {
if (newFbNr != a.FbNr) {
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}");
}
}
});
App.HintContextChange();
@ -253,5 +254,16 @@ namespace Elwig.Services {
}
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) {
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 did = oldDid ?? await ctx.NextDId(year);
int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did);
@ -524,7 +525,9 @@ namespace Elwig.Services {
}
await ctx.SaveChangesAsync();
}
return p;
});
App.HintContextChange();
@ -532,9 +535,10 @@ namespace Elwig.Services {
}
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;
var d = (await ctx.Deliveries.FindAsync(year, did))!;
var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
@ -577,7 +581,9 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync();
if (!anyLeft)
await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
}
return n;
});
App.HintContextChange();
@ -585,9 +591,9 @@ namespace Elwig.Services {
}
public static async Task<Delivery> SplitDeliveryToLsNr(int year, int did, int[] weights, string lsnr) {
Delivery n;
using (var ctx = new AppDbContext()) {
var n = await Task.Run(async () => {
Delivery n;
using var ctx = new AppDbContext();
var anyLeft = false;
n = (await ctx.Deliveries.FirstAsync(d => d.LsNr == lsnr))!;
var d = (await ctx.Deliveries.FindAsync(year, did))!;
@ -616,7 +622,9 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync();
if (!anyLeft && n.LsNr != d.LsNr)
await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
}
return n;
});
App.HintContextChange();
@ -624,7 +632,8 @@ namespace Elwig.Services {
}
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 dpnr = await ctx.NextDPNr(year, did);
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
@ -648,21 +657,23 @@ namespace Elwig.Services {
}
}
await ctx.SaveChangesAsync();
}
});
App.HintContextChange();
}
public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ctx = new AppDbContext();
var d = (await ctx.Deliveries.FindAsync(year, did))!;
using var doc = new DeliveryNote(d, ctx);
await Utils.ExportDocument(doc, mode, d.LsNr, (d.Member, $"{DeliveryNote.Name} Nr. {d.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {d.LsNr}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
var d = (await ctx.Deliveries.FindAsync(year, did))!;
using var doc = new DeliveryNote(d, ctx);
await Utils.ExportDocument(doc, mode, d.LsNr, (d.Member, $"{DeliveryNote.Name} Nr. {d.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {d.LsNr}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
@ -707,14 +718,16 @@ namespace Elwig.Services {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
} else if (mode == ExportMode.Export) {
@ -725,58 +738,64 @@ namespace Elwig.Services {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig"
};
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 {
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)
.Distinct()
.Include(d => d.Parts)
.ThenInclude(p => p.PartModifiers)
.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) {
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;
} else {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
@ -798,14 +817,16 @@ namespace Elwig.Services {
throw new ArgumentException("Invalid value for ExportSubject");
}
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList);
using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList);
using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
@ -829,14 +850,16 @@ namespace Elwig.Services {
Title = $"Lieferstatistik pro Ort speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ods = new OdsFile(d.FileName);
var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames);
await ods.AddTable(tbl);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ods = new OdsFile(d.FileName);
var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames);
await ods.AddTable(tbl);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
@ -875,33 +898,37 @@ namespace Elwig.Services {
Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ods = new OdsFile(d.FileName);
var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames);
tblTotal.FullName = DeliveryDepreciationList.Name;
tblTotal.Name = "Gesamt";
await ods.AddTable(tblTotal);
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
tbl.FullName = DeliveryDepreciationList.Name;
tbl.Name = branch.Name;
await ods.AddTable(tbl);
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ods = new OdsFile(d.FileName);
var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames);
tblTotal.FullName = DeliveryDepreciationList.Name;
tblTotal.Name = "Gesamt";
await ods.AddTable(tblTotal);
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
tbl.FullName = DeliveryDepreciationList.Name;
tbl.Name = branch.Name;
await ods.AddTable(tbl);
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
} else {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
@ -1070,10 +1097,12 @@ namespace Elwig.Services {
}
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.SaveChangesAsync();
}
});
App.HintContextChange();
}
}

View File

@ -367,51 +367,57 @@ namespace Elwig.Services {
}
public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ctx = new AppDbContext();
using var doc = new MemberDataSheet(m, ctx);
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
using var doc = new MemberDataSheet(m, ctx);
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var b = new Billing(year);
await b.FinishSeason();
await b.CalculateBuckets();
App.HintContextChange();
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var b = new Billing(year);
await b.FinishSeason();
await b.CalculateBuckets();
App.HintContextChange();
using var ctx = new AppDbContext();
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m);
using var doc = new DeliveryConfirmation(ctx, year, m, data);
await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
using var ctx = new AppDbContext();
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m);
using var doc = new DeliveryConfirmation(ctx, year, m, data);
await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr);
var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!;
var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data);
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr);
var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!;
var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data);
using var doc = new CreditNote(ctx, p, data[m.MgNr],
b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers,
await ctx.GetMemberUnderDelivery(year, m.MgNr));
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {v.Name}", $"Im Anhang finden Sie die Traubengutschrift {v.Name}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
using var doc = new CreditNote(ctx, p, data[m.MgNr],
b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers,
await ctx.GetMemberUnderDelivery(year, m.MgNr));
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {v.Name}", $"Im Anhang finden Sie die Traubengutschrift {v.Name}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
@ -464,14 +470,16 @@ namespace Elwig.Services {
Title = $"{MemberList.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
} else if (mode == ExportMode.Export) {
@ -482,8 +490,33 @@ namespace Elwig.Services {
Title = $"{MemberList.Name} speichern unter - Elwig"
};
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 {
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)
@ -495,99 +528,80 @@ namespace Elwig.Services {
.SelectMany(m => m.AreaCommitments)
.Include(c => c.Rd)
.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) {
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;
} else {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var doc = new MemberList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var doc = new MemberList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
public static async Task<int> UpdateMember(this MemberAdminViewModel vm, int? oldMgNr) {
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()) {
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!,
Iban = string.IsNullOrEmpty(vm.Iban) ? null : vm.Iban?.Replace(" ", ""),
Bic = string.IsNullOrEmpty(vm.Bic) ? null : vm.Bic,
Iban = string.IsNullOrEmpty(vm.Iban) ? null : vm.Iban?.Replace(" ", ""),
Bic = string.IsNullOrEmpty(vm.Bic) ? null : vm.Bic,
UstIdNr = string.IsNullOrEmpty(vm.UstIdNr) ? null : vm.UstIdNr,
LfbisNr = string.IsNullOrEmpty(vm.LfbisNr) ? null : vm.LfbisNr,
IsBuchführend = vm.IsBuchführend,
IsOrganic = vm.IsOrganic,
UstIdNr = string.IsNullOrEmpty(vm.UstIdNr) ? null : vm.UstIdNr,
LfbisNr = string.IsNullOrEmpty(vm.LfbisNr) ? null : vm.LfbisNr,
IsBuchführend = vm.IsBuchführend,
IsOrganic = vm.IsOrganic,
EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()),
ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()),
BusinessShares = (int)vm.BusinessShares!,
AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr,
IsActive = vm.IsActive,
IsVollLieferant = vm.IsVollLieferant,
IsFunktionär = vm.IsFunktionär,
ZwstId = vm.Branch?.ZwstId,
DefaultKgNr = vm.DefaultKg?.KgNr,
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
ContactViaPost = vm.ContactViaPost,
ContactViaEmail = vm.ContactViaEmail,
};
EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()),
ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()),
BusinessShares = (int)vm.BusinessShares!,
AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr,
IsActive = vm.IsActive,
IsVollLieferant = vm.IsVollLieferant,
IsFunktionär = vm.IsFunktionär,
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) {
ctx.Update(m);
} else {
@ -670,7 +684,7 @@ namespace Elwig.Services {
if (newMgNr != m.MgNr) {
await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}");
}
}
});
App.HintContextChange();
@ -678,7 +692,8 @@ namespace Elwig.Services {
}
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))!;
if (deletePaymentData) {
ctx.RemoveRange(l.Credits);
@ -691,7 +706,8 @@ namespace Elwig.Services {
}
ctx.Remove(l);
await ctx.SaveChangesAsync();
}
});
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?",
"Flächenbindung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting;
Mouse.OverrideCursor = Cursors.Wait;
try {
using (var ctx = new AppDbContext()) {
ctx.Remove(a);
await ctx.SaveChangesAsync();
}
App.HintContextChange();
await AreaComService.DeleteAreaCom(a.FbNr);
} catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@ -227,7 +223,7 @@ namespace Elwig.Windows {
private async void AreaCommitmentSaveButton_Click(object? sender, RoutedEventArgs? evt) {
AreaCommitmentSaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
Mouse.OverrideCursor = Cursors.Wait;
int fbnr;
try {
@ -237,9 +233,8 @@ namespace Elwig.Windows {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
AreaCommitmentSaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null;
return;
}
IsEditing = false;
@ -252,6 +247,7 @@ namespace Elwig.Windows {
FinishInputFilling();
await RefreshList();
RefreshInputs();
Mouse.OverrideCursor = null;
ViewModel.SearchQuery = "";
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);
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting;
Mouse.OverrideCursor = Cursors.Wait;
try {
using var ctx = new AppDbContext();
ctx.Add(new Season {
@ -209,7 +209,7 @@ namespace Elwig.Windows {
$"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?",
"Saison löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting;
Mouse.OverrideCursor = Cursors.Wait;
try {
using var ctx = new AppDbContext();
ctx.Remove(s);

View File

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

View File

@ -225,30 +225,8 @@ namespace Elwig.Windows {
DataPlot.Color = 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.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.IsVisible = false;

View File

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

View File

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

View File

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

View File

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

View File

@ -19,7 +19,7 @@ namespace Elwig.Windows {
public readonly int Year;
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 bool WeightModifierChanged = false;
@ -175,6 +175,7 @@ namespace Elwig.Windows {
private void UpdateSaveButton() {
SaveButton.IsEnabled = PaymentVariantList.SelectedItem != null &&
((DataChanged && DataValid) || NameChanged || CommentChanged ||
(DateChanged && DateValid) ||
(TransferDateChanged && TransferDateValid) ||
(ConsiderModifiersInput.IsChecked != BillingData?.ConsiderDelieryModifiers) ||
(ConsiderPenaltiesInput.IsChecked != BillingData?.ConsiderContractPenalties) ||
@ -433,10 +434,16 @@ namespace Elwig.Windows {
var withoutIban = v.Credits.Count(c => c.Member.Iban == null);
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);
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() {
FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}",
@ -489,6 +496,7 @@ namespace Elwig.Windows {
try {
v.Name = NameInput.Text;
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;
var d = App.Config.Debug ? BillingData.FromJson(DataInput.Text) : BillingData;
d.ConsiderDelieryModifiers = ConsiderModifiersInput.IsChecked ?? false;
@ -557,6 +565,27 @@ namespace Elwig.Windows {
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) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(TransferDateInput);

View File

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

View File

@ -2,3 +2,6 @@
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"
IconSourceFile="$(var.ElwigProjectDir)\Resources\Images\Elwig.ico">
<BootstrapperApplication>

View File

@ -1,4 +1,4 @@
<Project Sdk="WixToolset.Sdk/5.0.0">
<Project Sdk="WixToolset.Sdk/6">
<PropertyGroup>
<OutputType>Bundle</OutputType>
<OutputName>Elwig</OutputName>
@ -13,7 +13,7 @@
</Target>
<ItemGroup>
<ProjectReference Include="..\Installer\Installer.wixproj" />
<PackageReference Include="WixToolset.Bal.wixext" Version="5.0.2" />
<PackageReference Include="WixToolset.Util.wixext" Version="5.0.2" />
<PackageReference Include="WixToolset.Bal.wixext" Version="6.0.0" />
<PackageReference Include="WixToolset.Util.wixext" Version="6.0.0" />
</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>
<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="NReco.PdfRenderer" Version="1.6.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.6.0">
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.3">
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>