Compare commits
28 Commits
b31603554a
...
v1.0.3.4
| Author | SHA1 | Date | |
|---|---|---|---|
| b58dee6d3f | |||
| 0e2b004b0d | |||
| 19c3322ef2 | |||
| 6f081811c4 | |||
| 432c511b85 | |||
| 7e22759c33 | |||
| a47904cf0b | |||
| 6818491ae3 | |||
| 23db4de1ee | |||
| 9e5f709d42 | |||
| 4cd7ef85a1 | |||
| 2c0b000073 | |||
| f1737af2a2 | |||
| 8f423e3e92 | |||
| c8911c0acb | |||
| baf598b76c | |||
| 7adc9f89e4 | |||
| dde808df6a | |||
| e63de0d867 | |||
| e9e90b1e98 | |||
| 640dbf705e | |||
| 42121fe7da | |||
| d45c3f867f | |||
| a90be2644d | |||
| 01739ba42e | |||
| 7bea4d9ee0 | |||
| b6497fd422 | |||
| f141485537 |
106
CHANGELOG.md
106
CHANGELOG.md
@@ -2,6 +2,110 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
[v1.0.3.4][v1.0.3.4] (2026-02-19) {#v1.0.3.4}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Neue Funktionen {#v1.0.3.4-features}
|
||||||
|
|
||||||
|
* Bei Anlieferungsbestätigungen (`DeliveryConfirmation`) wird nun auch die Summe aller abgewerteten Lieferungen angeführt. (9e5f709d42)
|
||||||
|
* Bei der Auszahlung werden Traubengutschriften (`CreditNote`) nur noch für Mitglieder erstellt, die einen positiven Betrag ausgezahlt bekommen. (432c511b85)
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.3.4-bugfixes}
|
||||||
|
|
||||||
|
* Im Haupt-Fenster (`MainWindow`) wurde der Tooltip für den Knopf _Sorten-/Qual.aufschlüssel_ korrigiert. (2c0b000073)
|
||||||
|
* Falsch gesetzte `xtime` und `mtime` bei Lieferungen korrigiert. (23db4de1ee)
|
||||||
|
* Beim Import von Lieferungen ohne `kgnr` tritt nun kein Fehler auf. (6818491ae3)
|
||||||
|
* Beim Abfragen von neuen Daten zum Synchronisieren werden alle Fehler abgefangen. (a47904cf0b)
|
||||||
|
|
||||||
|
### Sonstiges {#v1.0.3.4-misc}
|
||||||
|
|
||||||
|
* Pdfium wird nun direkt importiert (anstatt über PdfiumViewer). (4cd7ef85a1)
|
||||||
|
* Auszahlungsvarianten von vergangenen Saisons sind nun nicht mehr für eine Bearbeitung gesperrt. (7e22759c33)
|
||||||
|
* Im Rundschreiben-Fenster (`MailWindow`) ist es nun möglich Dokumente durch Doppelklick an-/abzuwählen. (6f081811c4)
|
||||||
|
* Abhängigkeiten aktualisiert. (19c3322ef2, 0e2b004b0d)
|
||||||
|
|
||||||
|
[v1.0.3.4]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.3.4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[v1.0.3.3][v1.0.3.3] (2026-02-05) {#v1.0.3.3}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.3.3-bugfixes}
|
||||||
|
|
||||||
|
* Hotfix: Probleme beim Drucken seit der Installation von [v1.0.3.0](#v1.0.3.0). (c8911c0acb, 8f423e3e92)
|
||||||
|
|
||||||
|
[v1.0.3.3]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.3.3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[v1.0.3.2][v1.0.3.2] (2026-02-04) {#v1.0.3.2}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.3.2-bugfixes}
|
||||||
|
|
||||||
|
* Hotfix: Probleme bei der Installation von [v1.0.3.0](#v1.0.3.0). (7adc9f89e4)
|
||||||
|
|
||||||
|
[v1.0.3.2]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.3.2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[v1.0.3.1][v1.0.3.1] (2026-01-19) {#v1.0.3.1}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.3.1-bugfixes}
|
||||||
|
|
||||||
|
* Hotfix: Probleme bei der Installation von [v1.0.3.0](#v1.0.3.0). (e63de0d867)
|
||||||
|
|
||||||
|
[v1.0.3.1]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.3.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[v1.0.3.0][v1.0.3.0] (2026-01-16) {#v1.0.3.0}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Neue Funktionen {#v1.0.3.0-features}
|
||||||
|
|
||||||
|
* Bei Zu-/Abschlägen ist es nun möglich den konkreten Wert dieser auf Lieferscheinen nicht anzuzeigen (Stammdaten -> Saisons). (495aa8a691)
|
||||||
|
* Bei Teillieferungen kann nun die Art der Anlieferung angegeben werden: Planenwagen/Kipper, Lesewagen, Kiste(n). (bf6297f63b, 3419113dec, 6d6776f0f9)
|
||||||
|
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) können nun die Gesamtmengen der gefilterten Lieferungen nach Mitglied und Sorte als Excel-Liste exportiert werden ("Liefermengen"). ([#73][i73], e97c29db43)
|
||||||
|
* Im Datenbankabfragen-Fenster (`QueryWindow`) gibt es die Möglichkeit die Ergebnisse als CSV-Datei zu exportieren. (9af498287d, 5cec5b3556)
|
||||||
|
* PDF-Dokumente wurden überarbeitet:
|
||||||
|
* Traubengutschriften können nur noch ausgedruckt bzw. verschickt werden, wenn die zugehörige Auszahlungsvariante festgesetzt ist. (b31603554a)
|
||||||
|
* Auf Dokumenten für interne Verwendung (alle außer an Mitglieder adressierte) wurden Kopf- und Fußzeile auf ein Minimum beschränkt. (f141485537)
|
||||||
|
* Das Synchronisieren zwischen Zweigstellen ist für den Benutzer nun wesentlich vereinfacht. Geänderte Daten von Mitgliedern, Flächenbindungen oder Lieferungen werden beim Synchronisieren automatsich hochgeladen bzw. heruntergeladen. ([#66][i66], 3b335a568e)
|
||||||
|
* Im Rundschreiben-Fenster (`MailWindow`) wurde ein Knopf zum Abbrechen des Generierens hinzugefügt. ([#50][i50])
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.0.3.0-bugfixes}
|
||||||
|
|
||||||
|
* Einzelne (nicht über das Rundschreiben-Fenster) verschickte E-Mails werde korrekt im Ausgangsprotokoll angeführt. (ac6d559e5d)
|
||||||
|
* Bei automatischen Datenbank-Updates sind auftretende Fehler ignoriert worden. (f228ba3019)
|
||||||
|
* Beim Aufteilen von Lieferungen sind Zu-/Abschläge nicht auf neu erstellen Teillieferungen übernommen worden. (da05a49e10)
|
||||||
|
* Das Verbinden und Trennen von Waagen mittels Serial-/COM-Port ist nun bei laufendem Programm möglich. ([#71][i71])
|
||||||
|
* In den Auszahlungsvarianten-Daten (`PaymentVariantSummary`) ist die statistische Summe der gebundenen und ungebundenen Menge ohne die Spalte _attributlos gebunden_ berechnet worden. (90def81cc5)
|
||||||
|
* Seit [v0.13.7](#v0.13.7) (2025-01-21) wurde auch bei der ersten Auszahlung der Saison ein "Bisher berücksichtigt: € 0,00" auf den Traubengutschriften angeführt. (7bea4d9ee0)
|
||||||
|
* Das Speichern der Parameter `MAIL_SEND_POSTAL` und `MAIL_SEND_EMAIL` war fehlerhaft. (01739ba42e)
|
||||||
|
* Bessere Isolation der automatisierten Dokumenten-Tests. (640dbf705e)
|
||||||
|
|
||||||
|
### Sonstiges {#v1.0.3.0-misc}
|
||||||
|
|
||||||
|
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) wird bei Zu-/Abschlägen nur "Alle" angezeigt, wenn mehr als 1 ausgewählt sind. (811916a8b9)
|
||||||
|
* Im Auszahlungsvarianten-Fenster (`PaymentVariantsWindow`) wird die letzte Variante standardmäßig ausgewählt und beim Löschen wird um Bestätigung gebeten. (b6497fd422)
|
||||||
|
* Abhängigkeiten aktualisiert. (889a17b21c, 9b37330362, 3b6333a6a2, d45c3f867f, 42121fe7da)
|
||||||
|
|
||||||
|
[v1.0.3.0]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.3.0
|
||||||
|
[i50]: https://git.necronda.net/winzer/elwig/issues/50
|
||||||
|
[i66]: https://git.necronda.net/winzer/elwig/issues/60
|
||||||
|
[i71]: https://git.necronda.net/winzer/elwig/issues/71
|
||||||
|
[i73]: https://git.necronda.net/winzer/elwig/issues/73
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[v1.0.2.0][v1.0.2.0] (2025-11-10) {#v1.0.2.0}
|
[v1.0.2.0][v1.0.2.0] (2025-11-10) {#v1.0.2.0}
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
@@ -226,7 +330,7 @@ Changelog
|
|||||||
* Bei Traubengutschriften (`CreditNote`) wurde der Rebelzuschlag immer angeführt, auch wenn dieser in der zugrundeliegenden Berechnung nicht berücksichtigt wurde. (336aef5c70)
|
* Bei Traubengutschriften (`CreditNote`) wurde der Rebelzuschlag immer angeführt, auch wenn dieser in der zugrundeliegenden Berechnung nicht berücksichtigt wurde. (336aef5c70)
|
||||||
* In den Variantendaten einer Auszahlungsvariante (`PaymentVariantSummary`) wurde neben den Spalten _gebunden_ und _ungebunden_ noch _attributlos gebunden_ hinzugefügt. Ohne diese neue Spalte wären die Werte der anderen beiden falsch. ([#58][i58])
|
* In den Variantendaten einer Auszahlungsvariante (`PaymentVariantSummary`) wurde neben den Spalten _gebunden_ und _ungebunden_ noch _attributlos gebunden_ hinzugefügt. Ohne diese neue Spalte wären die Werte der anderen beiden falsch. ([#58][i58])
|
||||||
* Das erste Laden des Ausgangs-Protokoll-Fensters (`MailLogWindow`) hat nicht funktioniert. ([#65][i65])
|
* Das erste Laden des Ausgangs-Protokoll-Fensters (`MailLogWindow`) hat nicht funktioniert. ([#65][i65])
|
||||||
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) und im Mitglieder-Fenster (`MemberAdminWindow`) wird der Tool-Tip für Gewicht/Gradation mit korrektem Layout angezeigt. (e9f389b885)
|
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) und im Mitglieder-Fenster (`MemberAdminWindow`) wird der Tooltip für Gewicht/Gradation mit korrektem Layout angezeigt. (e9f389b885)
|
||||||
* Bei Traubengutschriften (`CreditNote`) werden längere Freitexte vollständig angezeigt statt abgeschnitten. ([#62][i62])
|
* Bei Traubengutschriften (`CreditNote`) werden längere Freitexte vollständig angezeigt statt abgeschnitten. ([#62][i62])
|
||||||
|
|
||||||
### Sonstiges {#v1.0.0.0-misc}
|
### Sonstiges {#v1.0.0.0-misc}
|
||||||
|
|||||||
@@ -19,6 +19,16 @@ namespace Elwig.Documents {
|
|||||||
Member = m;
|
Member = m;
|
||||||
Location = App.BranchLocation;
|
Location = App.BranchLocation;
|
||||||
IncludeSender = includeSender;
|
IncludeSender = includeSender;
|
||||||
|
var c = App.Client;
|
||||||
|
Header = $"<div class='name'>{c.Name}</div><div class='suffix'>{c.NameSuffix}</div><div class='type'>{c.NameTypeFull}</div>";
|
||||||
|
Footer = Utils.GenerateFooter("<br/>", " \u00b7 ")
|
||||||
|
.Item(c.NameFull).NextLine()
|
||||||
|
.Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextLine()
|
||||||
|
.Item(c.EmailAddress != null ? $"<a href=\"mailto:{c.Name} {c.NameSuffix} <{c.EmailAddress}>\">{c.EmailAddress}</a>" : null)
|
||||||
|
.Item(c.Website != null ? $"<a href=\"http://{c.Website}/\">{c.Website}</a>" : null)
|
||||||
|
.Item("Betriebs-Nr.", c.LfbisNr).Item("Bio-KSt.", c.OrganicAuthority).NextLine()
|
||||||
|
.Item("UID", c.UstIdNr).Item("BIC", c.Bic).Item("IBAN", c.Iban)
|
||||||
|
.ToString();
|
||||||
var uid = (m.UstIdNr ?? "-") + (m.IsBuchführend ? "" : " <i>(pauschaliert)</i>");
|
var uid = (m.UstIdNr ?? "-") + (m.IsBuchführend ? "" : " <i>(pauschaliert)</i>");
|
||||||
Aside = $"<table><colgroup><col span='1' style='width: 22.5mm;'/><col span='1' style='width: 42.5mm;'/></colgroup>" +
|
Aside = $"<table><colgroup><col span='1' style='width: 22.5mm;'/><col span='1' style='width: 42.5mm;'/></colgroup>" +
|
||||||
$"<thead><tr><th colspan='2'>Mitglied</th></tr></thead><tbody>" +
|
$"<thead><tr><th colspan='2'>Mitglied</th></tr></thead><tbody>" +
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin-top: 10mm;
|
margin-top: 0;
|
||||||
margin-bottom: 2mm;
|
margin-bottom: 2mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,12 @@
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="8">Davon abgewertet:</td>
|
||||||
|
<td colspan="2" class="number">@($"{Model.Data.Rows.Where(p => p.IsDepreciated).Sum(p => p.Weight):N0}")</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@Raw(BusinessDocument.PrintSortenaufteilung(Model.MemberStats))
|
@Raw(BusinessDocument.PrintSortenaufteilung(Model.MemberStats))
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin-top: 10mm;
|
margin-top: 0;
|
||||||
margin-bottom: 2mm;
|
margin-bottom: 2mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin-top: 10mm;
|
margin-top: 0;
|
||||||
margin-bottom: 2mm;
|
margin-bottom: 2mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Elwig.Helpers.Printing;
|
using Elwig.Helpers.Printing;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public abstract partial class Document : IDisposable {
|
public abstract partial class Document : IDisposable {
|
||||||
@@ -39,15 +40,8 @@ namespace Elwig.Documents {
|
|||||||
CurrentNextSeason = Utils.CurrentNextSeason;
|
CurrentNextSeason = Utils.CurrentNextSeason;
|
||||||
Title = title;
|
Title = title;
|
||||||
Author = c.NameFull;
|
Author = c.NameFull;
|
||||||
Header = $"<div class='name'>{c.Name}</div><div class='suffix'>{c.NameSuffix}</div><div class='type'>{c.NameTypeFull}</div>";
|
Header = "";
|
||||||
Footer = Utils.GenerateFooter("<br/>", " \u00b7 ")
|
Footer = Utils.GenerateFooter("<br/>", " \u00b7 ").Item(c.NameFull).ToString();
|
||||||
.Item(c.NameFull).NextLine()
|
|
||||||
.Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextLine()
|
|
||||||
.Item(c.EmailAddress != null ? $"<a href=\"mailto:{c.Name} {c.NameSuffix} <{c.EmailAddress}>\">{c.EmailAddress}</a>" : null)
|
|
||||||
.Item(c.Website != null ? $"<a href=\"http://{c.Website}/\">{c.Website}</a>" : null)
|
|
||||||
.Item("Betriebs-Nr.", c.LfbisNr).Item("Bio-KSt.", c.OrganicAuthority).NextLine()
|
|
||||||
.Item("UID", c.UstIdNr).Item("BIC", c.Bic).Item("IBAN", c.Iban)
|
|
||||||
.ToString();
|
|
||||||
Date = DateOnly.FromDateTime(Utils.Today);
|
Date = DateOnly.FromDateTime(Utils.Today);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +99,7 @@ namespace Elwig.Documents {
|
|||||||
return await Html.CompileRenderAsync(name, this); ;
|
return await Html.CompileRenderAsync(name, this); ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Generate(IProgress<double>? progress = null) {
|
public async Task Generate(CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
||||||
if (_pdfFile != null)
|
if (_pdfFile != null)
|
||||||
return;
|
return;
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
@@ -115,36 +109,50 @@ namespace Elwig.Documents {
|
|||||||
var pdf = new TempFile("pdf");
|
var pdf = new TempFile("pdf");
|
||||||
var tmpHtmls = new List<TempFile>();
|
var tmpHtmls = new List<TempFile>();
|
||||||
var tmpFiles = new List<string>();
|
var tmpFiles = new List<string>();
|
||||||
var n = m.Documents.Count();
|
try {
|
||||||
int i = 0;
|
var n = m.Documents.Count();
|
||||||
foreach (var doc in m.Documents) {
|
int i = 0;
|
||||||
if (doc is PdfDocument) {
|
foreach (var doc in m.Documents) {
|
||||||
tmpFiles.Add(doc.PdfPath!);
|
if (doc is PdfDocument) {
|
||||||
continue;
|
tmpFiles.Add(doc.PdfPath!);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cancelToken?.IsCancellationRequested ?? false)
|
||||||
|
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||||
|
var tmpHtml = new TempFile("html");
|
||||||
|
await File.WriteAllTextAsync(tmpHtml.FilePath, await doc.Render(), Utils.UTF8);
|
||||||
|
tmpHtmls.Add(tmpHtml);
|
||||||
|
tmpFiles.Add((doc is Letterhead ? "#" : "") + tmpHtml.FileName);
|
||||||
|
i++;
|
||||||
|
progress?.Report(GenerationProportion * 100 * i / n);
|
||||||
|
}
|
||||||
|
progress?.Report(GenerationProportion * 100);
|
||||||
|
var pages = await Pdf.Convert(tmpFiles, pdf.FileName, IsDoublePaged, cancelToken, new Progress<double>(v => progress?.Report(GenerationProportion * 100 + v * (1 - GenerationProportion))));
|
||||||
|
TotalPages = pages.Pages;
|
||||||
|
_pdfFile = pdf;
|
||||||
|
} catch {
|
||||||
|
pdf.Dispose();
|
||||||
|
throw;
|
||||||
|
} finally {
|
||||||
|
foreach (var tmp in tmpHtmls) {
|
||||||
|
tmp.Dispose();
|
||||||
}
|
}
|
||||||
var tmpHtml = new TempFile("html");
|
|
||||||
await File.WriteAllTextAsync(tmpHtml.FilePath, await doc.Render(), Utils.UTF8);
|
|
||||||
tmpHtmls.Add(tmpHtml);
|
|
||||||
tmpFiles.Add((doc is Letterhead ? "#" : "") + tmpHtml.FileName);
|
|
||||||
i++;
|
|
||||||
progress?.Report(GenerationProportion * 100 * i / n);
|
|
||||||
}
|
}
|
||||||
progress?.Report(GenerationProportion * 100);
|
|
||||||
var pages = await Pdf.Convert(tmpFiles, pdf.FileName, IsDoublePaged, new Progress<double>(v => progress?.Report(GenerationProportion * 100 + v * (1 - GenerationProportion))));
|
|
||||||
TotalPages = pages.Pages;
|
|
||||||
foreach (var tmp in tmpHtmls) {
|
|
||||||
tmp.Dispose();
|
|
||||||
}
|
|
||||||
_pdfFile = pdf;
|
|
||||||
} else {
|
} else {
|
||||||
|
if (cancelToken?.IsCancellationRequested ?? false)
|
||||||
|
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||||
var pdf = new TempFile("pdf");
|
var pdf = new TempFile("pdf");
|
||||||
using (var tmpHtml = new TempFile("html")) {
|
try {
|
||||||
|
using var tmpHtml = new TempFile("html");
|
||||||
await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
|
await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
|
||||||
progress?.Report(50.0);
|
progress?.Report(50.0);
|
||||||
var pages = await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath, IsDoublePaged);
|
var pages = await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath, IsDoublePaged, cancelToken);
|
||||||
TotalPages = pages.Pages;
|
TotalPages = pages.Pages;
|
||||||
|
_pdfFile = pdf;
|
||||||
|
} catch {
|
||||||
|
pdf.Dispose();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
_pdfFile = pdf;
|
|
||||||
}
|
}
|
||||||
progress?.Report(100.0);
|
progress?.Report(100.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin-top: 10mm;
|
margin-top: 0;
|
||||||
margin-bottom: 2mm;
|
margin-bottom: 2mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin-top: 10mm;
|
margin-top: 0;
|
||||||
margin-bottom: 2mm;
|
margin-bottom: 2mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin-top: 10mm;
|
margin-top: 0;
|
||||||
margin-bottom: 2mm;
|
margin-bottom: 2mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net10.0-windows</TargetFramework>
|
<TargetFramework>net10.0-windows</TargetFramework>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>1.0.2.0</Version>
|
<Version>1.0.3.4</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
@@ -21,24 +23,22 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="bblanchon.PDFium.Win32" Version="147.0.7690" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
<PackageReference Include="LinqKit" Version="1.3.9" />
|
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||||
<PackageReference Include="MailKit" Version="4.14.1" />
|
<PackageReference Include="MailKit" Version="4.15.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="10.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3595.46" />
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3800.47" />
|
||||||
<PackageReference Include="NJsonSchema" Version="11.5.2" />
|
<PackageReference Include="NJsonSchema" Version="11.5.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="RazorLight" Version="2.3.1" />
|
||||||
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
|
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
|
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
|
||||||
<PackageReference Include="System.IO.Hashing" Version="10.0.0" />
|
<PackageReference Include="System.IO.Hashing" Version="10.0.3" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="10.0.0" />
|
<PackageReference Include="System.IO.Ports" Version="10.0.3" />
|
||||||
<PackageReference Include="System.Management" Version="10.0.0" />
|
<PackageReference Include="System.Management" Version="10.0.3" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Elwig.Helpers {
|
|||||||
public static class AppDbUpdater {
|
public static class AppDbUpdater {
|
||||||
|
|
||||||
// Don't forget to update value in Tests/fetch-resources.bat!
|
// Don't forget to update value in Tests/fetch-resources.bat!
|
||||||
public static readonly int RequiredSchemaVersion = 36;
|
public static readonly int RequiredSchemaVersion = 37;
|
||||||
|
|
||||||
private static int VersionOffset = 0;
|
private static int VersionOffset = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -54,14 +54,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,
|
||||||
IIF(lc.amount >= 0, ROUND(lp.amount / POW(10, s.precision - 2)), 0) AS prev_net_amount,
|
IIF(lc.amount < 0, 0, ROUND(lp.amount / POW(10, s.precision - 2))) 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,
|
||||||
IIF(lc.amount >= 0, lc.modifiers, 0) AS prev_modifiers
|
IIF(lc.amount < 0, 0, lc.modifiers) 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
|
||||||
@@ -80,7 +80,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
||||||
LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr)
|
LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr)
|
||||||
LEFT JOIN payment_custom x ON (x.year, x.mgnr) = (s.year, m.mgnr)
|
LEFT JOIN payment_custom x ON (x.year, x.mgnr) = (s.year, m.mgnr)
|
||||||
WHERE s.year = {Year} AND v.avnr = {AvNr};
|
WHERE s.year = {Year} AND v.avnr = {AvNr} AND p.amount > COALESCE(lp.amount, 0);
|
||||||
""");
|
""");
|
||||||
await cnx.ExecuteBatch($"""
|
await cnx.ExecuteBatch($"""
|
||||||
UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr});
|
UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr});
|
||||||
|
|||||||
@@ -206,15 +206,15 @@ namespace Elwig.Helpers {
|
|||||||
case 1: orderingMemberList = "NAME"; break;
|
case 1: orderingMemberList = "NAME"; break;
|
||||||
case 2: orderingMemberList = "KG"; break;
|
case 2: orderingMemberList = "KG"; break;
|
||||||
}
|
}
|
||||||
string mailSendPostal = "MGNR";
|
string mailSendPostal = "WISH";
|
||||||
switch (MailOrdering) {
|
switch (MailSendPostal) {
|
||||||
case 0: mailSendPostal = "NONE"; break;
|
case 0: mailSendPostal = "NONE"; break;
|
||||||
case 1: mailSendPostal = "NO_EMAIL"; break;
|
case 1: mailSendPostal = "NO_EMAIL"; break;
|
||||||
case 2: mailSendPostal = "WISH"; break;
|
case 2: mailSendPostal = "WISH"; break;
|
||||||
case 3: mailSendPostal = "ALL"; break;
|
case 3: mailSendPostal = "ALL"; break;
|
||||||
}
|
}
|
||||||
string mailSendEmail = "MGNR";
|
string mailSendEmail = "WISH";
|
||||||
switch (MailOrdering) {
|
switch (MailSendEmail) {
|
||||||
case 0: mailSendEmail = "NONE"; break;
|
case 0: mailSendEmail = "NONE"; break;
|
||||||
case 1: mailSendEmail = "WISH"; break;
|
case 1: mailSendEmail = "WISH"; break;
|
||||||
case 2: mailSendEmail = "ALL"; break;
|
case 2: mailSendEmail = "ALL"; break;
|
||||||
|
|||||||
@@ -783,15 +783,15 @@ namespace Elwig.Helpers.Export {
|
|||||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||||
ImportedAt = DateTime.Now,
|
ImportedAt = DateTime.Now,
|
||||||
}, json["parts"]!.AsArray().Select(p => p!.AsObject()).Select(p => {
|
}, json["parts"]!.AsArray().Select(p => p!.AsObject()).Select(p => {
|
||||||
var kgnr = p["kgnr"]!.AsValue().GetValue<int>();
|
var kgnr = p["kgnr"]?.AsValue().GetValue<int>();
|
||||||
var ried = p["ried"]?.AsValue().GetValue<string>();
|
var ried = p["ried"]?.AsValue().GetValue<string>();
|
||||||
WbRd? rd = null;
|
WbRd? rd = null;
|
||||||
if (ried != null) {
|
if (ried != null && kgnr != null) {
|
||||||
var rde = riede.GetValueOrDefault(kgnr, []);
|
var rde = riede.GetValueOrDefault(kgnr.Value, []);
|
||||||
rd = rde.FirstOrDefault(r => r.Name == ried);
|
rd = rde.FirstOrDefault(r => r.Name == ried);
|
||||||
if (rd == null) {
|
if (rd == null) {
|
||||||
rd = new WbRd {
|
rd = new WbRd {
|
||||||
KgNr = kgnr,
|
KgNr = kgnr.Value,
|
||||||
RdNr = (rde.Count == 0 ? 1 : rde.Max(r => r.RdNr)) + 1,
|
RdNr = (rde.Count == 0 ? 1 : rde.Max(r => r.RdNr)) + 1,
|
||||||
Name = ried,
|
Name = ried,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,14 +14,23 @@ namespace Elwig.Helpers.Printing {
|
|||||||
.UseMemoryCachingProvider()
|
.UseMemoryCachingProvider()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
await e.CompileTemplateAsync("Document");
|
await e.CompileTemplateAsync("Document");
|
||||||
await e.CompileTemplateAsync("BusinessDocument");
|
await e.CompileTemplateAsync("BusinessDocument");
|
||||||
await e.CompileTemplateAsync("BusinessLetter");
|
await e.CompileTemplateAsync("BusinessLetter");
|
||||||
await e.CompileTemplateAsync("DeliveryNote");
|
|
||||||
await e.CompileTemplateAsync("CreditNote");
|
await e.CompileTemplateAsync("CreditNote");
|
||||||
await e.CompileTemplateAsync("DeliveryJournal");
|
await e.CompileTemplateAsync("DeliveryAncmtList");
|
||||||
await e.CompileTemplateAsync("Letterhead");
|
|
||||||
await e.CompileTemplateAsync("DeliveryConfirmation");
|
await e.CompileTemplateAsync("DeliveryConfirmation");
|
||||||
|
await e.CompileTemplateAsync("DeliveryDepreciationList");
|
||||||
|
await e.CompileTemplateAsync("DeliveryJournal");
|
||||||
|
await e.CompileTemplateAsync("DeliveryNote");
|
||||||
|
await e.CompileTemplateAsync("Letterhead");
|
||||||
|
await e.CompileTemplateAsync("MemberDataSheet");
|
||||||
|
await e.CompileTemplateAsync("MemberList");
|
||||||
|
await e.CompileTemplateAsync("PaymentVariantSummary");
|
||||||
|
await e.CompileTemplateAsync("WineQualityStatistics");
|
||||||
|
|
||||||
Engine = e;
|
Engine = e;
|
||||||
evtHandler?.Invoke();
|
evtHandler?.Invoke();
|
||||||
|
|||||||
@@ -1,28 +1,32 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Elwig.Windows;
|
using Elwig.Windows;
|
||||||
using System.Diagnostics;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows;
|
using System.Diagnostics;
|
||||||
using System.Text.RegularExpressions;
|
using System.Drawing.Printing;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using PdfiumViewer;
|
using System.Reflection;
|
||||||
using System.Drawing.Printing;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Printing {
|
namespace Elwig.Helpers.Printing {
|
||||||
public static class Pdf {
|
public static class Pdf {
|
||||||
|
|
||||||
private static readonly string WinziPrint = new string[] { App.InstallPath }
|
private static readonly string WinziPrint = (Assembly.GetEntryAssembly()?.Location.Contains(@"\bin\") ?? false) ?
|
||||||
.Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? [])
|
Path.Combine(Assembly.GetEntryAssembly()!.Location.Split(@"\bin\")[0], "../Installer/Files/WinziPrint.exe") :
|
||||||
.Select(x => Path.Combine(x, "WinziPrint.exe"))
|
new string[] { App.InstallPath }
|
||||||
.Where(File.Exists)
|
.Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? [])
|
||||||
.FirstOrDefault() ?? throw new FileNotFoundException("WiniPrint executable not found");
|
.Select(x => Path.Combine(x, "WinziPrint.exe"))
|
||||||
|
.Where(File.Exists)
|
||||||
|
.FirstOrDefault() ?? throw new FileNotFoundException("WiniPrint executable not found");
|
||||||
private static Process? WinziPrintProc;
|
private static Process? WinziPrintProc;
|
||||||
public static bool IsReady => WinziPrintProc != null;
|
public static bool IsReady => WinziPrintProc != null;
|
||||||
|
|
||||||
public static async Task Init(Action? evtHandler = null) {
|
public static async Task Init(Action? evtHandler = null) {
|
||||||
|
PdfiumNative.FPDF_InitLibrary();
|
||||||
// NOTE: If the WinziPrint daemon is already running this will succeed, but the process will fail.
|
// NOTE: If the WinziPrint daemon is already running this will succeed, but the process will fail.
|
||||||
// Should be no problem, as long as the daemon is not closed
|
// Should be no problem, as long as the daemon is not closed
|
||||||
var p = new Process() { StartInfo = new() {
|
var p = new Process() { StartInfo = new() {
|
||||||
@@ -43,27 +47,49 @@ namespace Elwig.Helpers.Printing {
|
|||||||
public static Task Cleanup() {
|
public static Task Cleanup() {
|
||||||
WinziPrintProc?.Kill(true);
|
WinziPrintProc?.Kill(true);
|
||||||
WinziPrintProc?.Close();
|
WinziPrintProc?.Close();
|
||||||
|
PdfiumNative.FPDF_DestroyLibrary();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(int Pages, IEnumerable<int> PerDoc)> Convert(string htmlPath, string pdfPath, bool doublePaged = false, IProgress<double>? progress = null) {
|
public static async Task<(int Pages, IEnumerable<int> PerDoc)> Convert(string htmlPath, string pdfPath, bool doublePaged = false, CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
||||||
return await Convert([htmlPath], pdfPath, doublePaged, progress);
|
return await Convert([htmlPath], pdfPath, doublePaged, cancelToken, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(int Pages, IEnumerable<int> PerDoc)> Convert(IEnumerable<string> htmlPath, string pdfPath, bool doublePaged = false, IProgress<double>? progress = null) {
|
public static async Task<(int Pages, IEnumerable<int> PerDoc)> Convert(IEnumerable<string> htmlPath, string pdfPath, bool doublePaged = false, CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
||||||
if (WinziPrintProc == null) throw new InvalidOperationException("The WinziPrint process has not been initialized yet");
|
if (WinziPrintProc == null) throw new InvalidOperationException("The WinziPrint process has not been initialized yet");
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
using var client = new TcpClient("127.0.0.1", 30983);
|
using var client = new TcpClient("127.0.0.1", 30983);
|
||||||
using var stream = client.GetStream();
|
using var stream = client.GetStream();
|
||||||
|
string cnxId;
|
||||||
|
using var reader = new StreamReader(stream);
|
||||||
|
var first = await reader.ReadLineAsync() ?? throw new IOException("Invalid response from WinziPrint");
|
||||||
|
if (first.StartsWith("id:")) {
|
||||||
|
cnxId = first[3..].Trim();
|
||||||
|
} else {
|
||||||
|
throw new IOException("Invalid response from WinziPrint");
|
||||||
|
}
|
||||||
await stream.WriteAsync(Utils.UTF8.GetBytes(
|
await stream.WriteAsync(Utils.UTF8.GetBytes(
|
||||||
"-e utf-8;-p;" + (doublePaged ? "-2;" : "") +
|
"-e utf-8;-p;" + (doublePaged ? "-2;" : "") +
|
||||||
$"{string.Join(';', htmlPath)};{pdfPath}" +
|
$"{string.Join(';', htmlPath)};{pdfPath}" +
|
||||||
"\r\n"));
|
"\r\n"));
|
||||||
using var reader = new StreamReader(stream);
|
bool cancelled = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (!cancelled && (cancelToken?.IsCancellationRequested ?? false)) {
|
||||||
|
try {
|
||||||
|
using var cancelClient = new TcpClient("127.0.0.1", 30983);
|
||||||
|
using var cancelStream = cancelClient.GetStream();
|
||||||
|
using var cancelReader = new StreamReader(cancelStream);
|
||||||
|
await cancelReader.ReadLineAsync();
|
||||||
|
await cancelStream.WriteAsync(Utils.UTF8.GetBytes($"cancel;{cnxId}\r\n"));
|
||||||
|
} catch { }
|
||||||
|
cancelled = true;
|
||||||
|
}
|
||||||
var line = await reader.ReadLineAsync() ?? throw new IOException("Invalid response from WinziPrint");
|
var line = await reader.ReadLineAsync() ?? throw new IOException("Invalid response from WinziPrint");
|
||||||
if (line.StartsWith("error:")) {
|
if (line.StartsWith("error:")) {
|
||||||
throw new IOException($"WinziPrint: {line[6..].Trim()}");
|
var msg = line[6..].Trim();
|
||||||
|
if (msg == "aborted")
|
||||||
|
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||||
|
throw new IOException($"WinziPrint: {msg}");
|
||||||
} else if (line.StartsWith("progress:")) {
|
} else if (line.StartsWith("progress:")) {
|
||||||
var parts = line[9..].Trim().Split('/').Select(int.Parse).ToArray();
|
var parts = line[9..].Trim().Split('/').Select(int.Parse).ToArray();
|
||||||
progress?.Report(100.0 * parts[0] / parts[1]);
|
progress?.Report(100.0 * parts[0] / parts[1]);
|
||||||
@@ -98,9 +124,9 @@ namespace Elwig.Helpers.Printing {
|
|||||||
|
|
||||||
public static Task Print(string path, PrinterSettings settings) {
|
public static Task Print(string path, PrinterSettings settings) {
|
||||||
try {
|
try {
|
||||||
using var doc = PdfDocument.Load(path);
|
using var printDoc = new PdfPrintDocument(path) {
|
||||||
using var printDoc = doc.CreatePrintDocument(PdfPrintMode.CutMargin);
|
PrinterSettings = settings,
|
||||||
printDoc.PrinterSettings = settings;
|
};
|
||||||
printDoc.Print();
|
printDoc.Print();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MessageBox.Show("Beim Drucken ist ein Fehler aufgetreten:\n\n" + e.Message, "Fehler beim Drucken", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show("Beim Drucken ist ein Fehler aufgetreten:\n\n" + e.Message, "Fehler beim Drucken", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
|||||||
102
Elwig/Helpers/Printing/PdfPrintDocument.cs
Normal file
102
Elwig/Helpers/Printing/PdfPrintDocument.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Drawing.Printing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Elwig.Helpers.Printing {
|
||||||
|
public class PdfPrintDocument : PrintDocument {
|
||||||
|
|
||||||
|
private readonly IntPtr _handle;
|
||||||
|
private readonly int _pageCount;
|
||||||
|
private readonly double _dpi;
|
||||||
|
|
||||||
|
private int _currentPage;
|
||||||
|
|
||||||
|
public PdfPrintDocument(string path, string? password = null, double dpi = 300.0) :
|
||||||
|
base() {
|
||||||
|
_handle = PdfiumNative.FPDF_LoadDocument(path, password);
|
||||||
|
_pageCount = PdfiumNative.FPDF_GetPageCount(_handle);
|
||||||
|
_dpi = dpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing) {
|
||||||
|
PdfiumNative.FPDF_CloseDocument(_handle);
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnBeginPrint(PrintEventArgs evt) {
|
||||||
|
_currentPage = (PrinterSettings.FromPage != 0) ? (PrinterSettings.FromPage - 1) : 0;
|
||||||
|
base.OnBeginPrint(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPrintPage(PrintPageEventArgs evt) {
|
||||||
|
if (_currentPage < _pageCount) {
|
||||||
|
IntPtr page = PdfiumNative.FPDF_LoadPage(_handle, _currentPage);
|
||||||
|
double width = PdfiumNative.FPDF_GetPageWidth(page);
|
||||||
|
double height = PdfiumNative.FPDF_GetPageHeight(page);
|
||||||
|
int pixelWidth = (int)(width / 72.0 * _dpi);
|
||||||
|
int pixelHeight = (int)(height / 72.0 * _dpi);
|
||||||
|
|
||||||
|
IntPtr bitmap = PdfiumNative.FPDFBitmap_Create(pixelWidth, pixelHeight, 1);
|
||||||
|
PdfiumNative.FPDF_RenderPageBitmap(bitmap, page, 0, 0, pixelWidth, pixelHeight, 0, 0);
|
||||||
|
|
||||||
|
IntPtr buffer = PdfiumNative.FPDFBitmap_GetBuffer(bitmap);
|
||||||
|
int stride = PdfiumNative.FPDFBitmap_GetStride(bitmap);
|
||||||
|
using (var bmp = new Bitmap(pixelWidth, pixelHeight, stride, PixelFormat.Format32bppArgb, buffer)) {
|
||||||
|
evt.Graphics?.DrawImage(bmp, evt.PageBounds);
|
||||||
|
}
|
||||||
|
_currentPage++;
|
||||||
|
|
||||||
|
PdfiumNative.FPDFBitmap_Destroy(bitmap);
|
||||||
|
PdfiumNative.FPDF_ClosePage(page);
|
||||||
|
}
|
||||||
|
evt.HasMorePages = _currentPage < ((PrinterSettings.ToPage == 0) ? _pageCount : Math.Min(PrinterSettings.ToPage, _pageCount));
|
||||||
|
base.OnPrintPage(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal partial class PdfiumNative {
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial void FPDF_InitLibrary();
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial void FPDF_DestroyLibrary();
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll", StringMarshalling = StringMarshalling.Utf8)]
|
||||||
|
public static partial IntPtr FPDF_LoadDocument(string filePath, string? password);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial void FPDF_CloseDocument(IntPtr document);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial int FPDF_GetPageCount(IntPtr document);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial IntPtr FPDF_LoadPage(IntPtr document, int pageIndex);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial void FPDF_ClosePage(IntPtr page);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial double FPDF_GetPageWidth(IntPtr page);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial double FPDF_GetPageHeight(IntPtr page);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial IntPtr FPDFBitmap_Create(int width, int height, int alpha);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial void FPDFBitmap_Destroy(IntPtr bitmap);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial IntPtr FPDFBitmap_GetBuffer(IntPtr bitmap);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial int FPDFBitmap_GetStride(IntPtr bitmap);
|
||||||
|
|
||||||
|
[LibraryImport("pdfium.dll")]
|
||||||
|
public static partial void FPDF_RenderPageBitmap(IntPtr bitmap, IntPtr page, int start_x, int start_y, int size_x, int size_y, int rotate, int flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -75,6 +75,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
public string? Attribute;
|
public string? Attribute;
|
||||||
public string? Cultivation;
|
public string? Cultivation;
|
||||||
public string QualityLevel;
|
public string QualityLevel;
|
||||||
|
public bool IsDepreciated;
|
||||||
public (double Oe, double Kmw) Gradation;
|
public (double Oe, double Kmw) Gradation;
|
||||||
public string[] Modifiers;
|
public string[] Modifiers;
|
||||||
public int Weight;
|
public int Weight;
|
||||||
@@ -89,17 +90,15 @@ namespace Elwig.Models.Dtos {
|
|||||||
Attribute = p.Attribute?.Name;
|
Attribute = p.Attribute?.Name;
|
||||||
Cultivation = p.Cultivation?.Name;
|
Cultivation = p.Cultivation?.Name;
|
||||||
QualityLevel = p.Quality.Name;
|
QualityLevel = p.Quality.Name;
|
||||||
|
IsDepreciated = p.QualId == "WEI";
|
||||||
Gradation = (p.Oe, p.Kmw);
|
Gradation = (p.Oe, p.Kmw);
|
||||||
Modifiers = p.Modifiers
|
Modifiers = [.. p.Modifiers.Select(m => m.Name)];
|
||||||
.Select(m => m.Name)
|
|
||||||
.ToArray();
|
|
||||||
Weight = p.Weight;
|
Weight = p.Weight;
|
||||||
IsNetWeight = p.IsNetWeight;
|
IsNetWeight = p.IsNetWeight;
|
||||||
Buckets = p.Buckets
|
Buckets = [.. p.Buckets
|
||||||
.Where(b => b.Value > 0)
|
.Where(b => b.Value > 0)
|
||||||
.OrderByDescending(b => b.BktNr)
|
.OrderByDescending(b => b.BktNr)
|
||||||
.Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{b.Discr}", b.Value))
|
.Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{b.Discr}", b.Value))];
|
||||||
.ToArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
-- schema version 34 to 35
|
-- schema version 34 to 35
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
ALTER TABLE delivery_part ADD COLUMN unloading TEXT DEFAULT NULL;
|
ALTER TABLE delivery_part ADD COLUMN unloading TEXT DEFAULT NULL;
|
||||||
UPDATE delivery_part SET unloading = 'pumped' WHERE lesewagen;
|
UPDATE delivery_part SET unloading = 'pumped' WHERE lesewagen;
|
||||||
UPDATE delivery_part SET unloading = 'box' WHERE (SELECT zwstid IN ('H','S') FROM delivery d WHERE (d.year, d.did) = (delivery_part.year, delivery_part.did));
|
UPDATE delivery_part SET unloading = 'box' WHERE (SELECT zwstid IN ('H','S') FROM delivery d WHERE (d.year, d.did) = (delivery_part.year, delivery_part.did));
|
||||||
ALTER TABLE delivery_part DROP COLUMN lesewagen;
|
ALTER TABLE delivery_part DROP COLUMN lesewagen;
|
||||||
|
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
|
|||||||
12
Elwig/Resources/Sql/36-37.sql
Normal file
12
Elwig/Resources/Sql/36-37.sql
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
-- schema version 36 to 37
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
|
|
||||||
|
-- fix old deliveries
|
||||||
|
UPDATE delivery SET xtime = NULL, mtime = ctime WHERE year <= 2022 AND mtime >= 1768521600 AND mtime < 1772323200;
|
||||||
|
UPDATE delivery_part SET xtime = NULL, mtime = ctime WHERE year <= 2022 AND mtime >= 1768521600 AND mtime < 1772323200;
|
||||||
|
-- clear xtime at one laptop to force updates from this one
|
||||||
|
UPDATE delivery SET xtime = NULL WHERE year >= 2023 AND xtime >= 1771200000 AND xtime < 1771286400;
|
||||||
|
UPDATE delivery_part SET xtime = NULL WHERE year >= 2023 AND xtime >= 1771200000 AND xtime < 1771286400;
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
@@ -271,7 +271,11 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
||||||
return await ctx.Members.AnyAsync(ChangedMembers) || await ctx.Deliveries.AnyAsync(ChangedDeliveries) || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
try {
|
||||||
|
return await ctx.Members.AnyAsync(ChangedMembers) || await ctx.Deliveries.AnyAsync(ChangedDeliveries) || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Elwig.ViewModels {
|
|||||||
private IEnumerable<PaymentVar> _paymentVariants = [];
|
private IEnumerable<PaymentVar> _paymentVariants = [];
|
||||||
|
|
||||||
public BillingData? BillingData;
|
public BillingData? BillingData;
|
||||||
public bool SeasonLocked;
|
public bool SeasonLocked = false; // never locked
|
||||||
public bool WeightModifierChanged;
|
public bool WeightModifierChanged;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
Programmiersprache: C#<LineBreak/>
|
Programmiersprache: C#<LineBreak/>
|
||||||
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
||||||
Datenbank: <Hyperlink NavigateUri="https://sqlite.org/" RequestNavigate="Hyperlink_RequestNavigate">SQLite</Hyperlink><LineBreak/>
|
Datenbank: <Hyperlink NavigateUri="https://sqlite.org/" RequestNavigate="Hyperlink_RequestNavigate">SQLite</Hyperlink><LineBreak/>
|
||||||
PDF-Erstellung: <Hyperlink NavigateUri="https://weasyprint.org/" RequestNavigate="Hyperlink_RequestNavigate">WeasyPrint</Hyperlink>, <Hyperlink NavigateUri="https://github.com/toddams/RazorLight" RequestNavigate="Hyperlink_RequestNavigate">RazorLight</Hyperlink>, <Hyperlink NavigateUri="https://github.com/pvginkel/PdfiumViewer" RequestNavigate="Hyperlink_RequestNavigate">PdfiumViewer</Hyperlink><LineBreak/>
|
PDF-Erstellung: <Hyperlink NavigateUri="https://weasyprint.org/" RequestNavigate="Hyperlink_RequestNavigate">WeasyPrint</Hyperlink>, <Hyperlink NavigateUri="https://github.com/toddams/RazorLight" RequestNavigate="Hyperlink_RequestNavigate">RazorLight</Hyperlink>, <Hyperlink NavigateUri="https://github.com/bblanchon/pdfium-binaries" RequestNavigate="Hyperlink_RequestNavigate">Pdfium</Hyperlink><LineBreak/>
|
||||||
Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink>
|
Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
Grid.Column="0" Margin="10,8,10,10"/>
|
Grid.Column="0" Margin="10,8,10,10"/>
|
||||||
<ListBox x:Name="AvaiableDocumentsList"
|
<ListBox x:Name="AvaiableDocumentsList"
|
||||||
Grid.Column="0" Margin="10,30,10,10"
|
Grid.Column="0" Margin="10,30,10,10"
|
||||||
SelectionChanged="AvaiableDocumentsList_SelectionChanged"/>
|
SelectionChanged="AvaiableDocumentsList_SelectionChanged" MouseDoubleClick="AvaiableDocumentsList_MouseDoubleClick"/>
|
||||||
|
|
||||||
<Button x:Name="DocumentAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14"
|
<Button x:Name="DocumentAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14"
|
||||||
Grid.Column="1" Margin="0,0,0,30" VerticalAlignment="Center" Height="25" IsEnabled="False"
|
Grid.Column="1" Margin="0,0,0,30" VerticalAlignment="Center" Height="25" IsEnabled="False"
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
Grid.Column="2" Margin="10,8,10,10"/>
|
Grid.Column="2" Margin="10,8,10,10"/>
|
||||||
<ListBox x:Name="SelectedDocumentsList" DisplayMemberPath="Name"
|
<ListBox x:Name="SelectedDocumentsList" DisplayMemberPath="Name"
|
||||||
Grid.Column="2" Margin="10,30,10,37"
|
Grid.Column="2" Margin="10,30,10,37"
|
||||||
SelectionChanged="SelectedDocumentsList_SelectionChanged">
|
SelectionChanged="SelectedDocumentsList_SelectionChanged" MouseDoubleClick="SelectedDocumentsList_MouseDoubleClick">
|
||||||
<ListBox.InputBindings>
|
<ListBox.InputBindings>
|
||||||
<KeyBinding Key="Delete" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>
|
<KeyBinding Key="Delete" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>
|
||||||
</ListBox.InputBindings>
|
</ListBox.InputBindings>
|
||||||
@@ -138,58 +138,61 @@
|
|||||||
<RadioButton GroupName="Recipients" x:Name="RecipientsNonDeliveryMembersInput" Content="Nicht-Lieferanten der Saison"
|
<RadioButton GroupName="Recipients" x:Name="RecipientsNonDeliveryMembersInput" Content="Nicht-Lieferanten der Saison"
|
||||||
Margin="10,90,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="10,90,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
||||||
<RadioButton GroupName="Recipients" x:Name="RecipientsCustomInput" Content="Benutzerdefiniert"
|
<RadioButton GroupName="Recipients" x:Name="RecipientsCreditMembersInput" Content="Empfänger von Gutschriften"
|
||||||
Margin="10,110,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="10,110,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
||||||
|
<RadioButton GroupName="Recipients" x:Name="RecipientsCustomInput" Content="Benutzerdefiniert"
|
||||||
|
Margin="10,130,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
|
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
||||||
|
|
||||||
<Label Content="Zwst.:" x:Name="MemberBranchLabel" Margin="10,140,0,10"/>
|
<Label Content="Zwst.:" x:Name="MemberBranchLabel" Margin="10,160,0,10"/>
|
||||||
<ctrl:CheckComboBox x:Name="MemberBranchInput" AllItemsSelectedContent="Alle Stammzweigstellen" Delimiter=", " DisplayMemberPath="Name"
|
<ctrl:CheckComboBox x:Name="MemberBranchInput" AllItemsSelectedContent="Alle Stammzweigstellen" Delimiter=", " DisplayMemberPath="Name"
|
||||||
Margin="50,140,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
Margin="50,160,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
||||||
SelectionChanged="MemberInput_SelectionChanged"/>
|
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||||
|
|
||||||
<Label Content="Gem.:" x:Name="MemberKgLabel" Margin="10,170,0,10"/>
|
<Label Content="Gem.:" x:Name="MemberKgLabel" Margin="10,190,0,10"/>
|
||||||
<ctrl:CheckComboBox x:Name="MemberKgInput" AllItemsSelectedContent="Alle Stammgemeinden" Delimiter=", " DisplayMemberPath="Name"
|
<ctrl:CheckComboBox x:Name="MemberKgInput" AllItemsSelectedContent="Alle Stammgemeinden" Delimiter=", " DisplayMemberPath="Name"
|
||||||
IsSelectAllActive="True" SelectAllContent="Alle Stammgemeinden"
|
IsSelectAllActive="True" SelectAllContent="Alle Stammgemeinden"
|
||||||
Margin="50,170,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
Margin="50,190,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
||||||
SelectionChanged="MemberInput_SelectionChanged"/>
|
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||||
|
|
||||||
<Label Content="Bio-Betrieb:" x:Name="MemberOrganicLabel" Margin="10,200,0,10"/>
|
<Label Content="Bio-Betrieb:" x:Name="MemberOrganicLabel" Margin="10,220,0,10"/>
|
||||||
<RadioButton x:Name="MemberOrganicYesInput" Content="Ja" GroupName="MemberOrganic"
|
<RadioButton x:Name="MemberOrganicYesInput" Content="Ja" GroupName="MemberOrganic"
|
||||||
Margin="80,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="80,225,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="MemberInput_Checked"/>
|
Checked="MemberInput_Checked"/>
|
||||||
<RadioButton x:Name="MemberOrganicNoInput" Content="Nein" GroupName="MemberOrganic"
|
<RadioButton x:Name="MemberOrganicNoInput" Content="Nein" GroupName="MemberOrganic"
|
||||||
Margin="125,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="125,225,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="MemberInput_Checked"/>
|
Checked="MemberInput_Checked"/>
|
||||||
<RadioButton x:Name="MemberOrganicIndifferentInput" Content="Egal" GroupName="MemberOrganic"
|
<RadioButton x:Name="MemberOrganicIndifferentInput" Content="Egal" GroupName="MemberOrganic"
|
||||||
Margin="180,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="180,225,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="MemberInput_Checked"/>
|
Checked="MemberInput_Checked"/>
|
||||||
|
|
||||||
<Label Content="Funktionär:" x:Name="MemberFunktionärLabel" Margin="10,230,0,10"/>
|
<Label Content="Funktionär:" x:Name="MemberFunktionärLabel" Margin="10,250,0,10"/>
|
||||||
<RadioButton x:Name="MemberFunktionärYesInput" Content="Ja" GroupName="MemberFunktionär"
|
<RadioButton x:Name="MemberFunktionärYesInput" Content="Ja" GroupName="MemberFunktionär"
|
||||||
Margin="80,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="80,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="MemberInput_Checked"/>
|
Checked="MemberInput_Checked"/>
|
||||||
<RadioButton x:Name="MemberFunktionärNoInput" Content="Nein" GroupName="MemberFunktionär"
|
<RadioButton x:Name="MemberFunktionärNoInput" Content="Nein" GroupName="MemberFunktionär"
|
||||||
Margin="125,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="125,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="MemberInput_Checked"/>
|
Checked="MemberInput_Checked"/>
|
||||||
<RadioButton x:Name="MemberFunktionärIndifferentInput" Content="Egal" GroupName="MemberFunktionär"
|
<RadioButton x:Name="MemberFunktionärIndifferentInput" Content="Egal" GroupName="MemberFunktionär"
|
||||||
Margin="180,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
Margin="180,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="MemberInput_Checked"/>
|
Checked="MemberInput_Checked"/>
|
||||||
|
|
||||||
<Label Content="Vtrg.:" x:Name="MemberAreaComLabel" Margin="10,260,0,10"/>
|
<Label Content="Vtrg.:" x:Name="MemberAreaComLabel" Margin="10,280,0,10"/>
|
||||||
<ctrl:CheckComboBox x:Name="MemberAreaComInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId"
|
<ctrl:CheckComboBox x:Name="MemberAreaComInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId"
|
||||||
IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten"
|
IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten"
|
||||||
Margin="50,260,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
Margin="50,280,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
||||||
SelectionChanged="MemberInput_SelectionChanged"/>
|
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||||
|
|
||||||
<Label Content="Tag:" x:Name="MemberDeliveryAncmtLabel" Margin="10,260,0,10"/>
|
<Label Content="Tag:" x:Name="MemberDeliveryAncmtLabel" Margin="10,280,0,10"/>
|
||||||
<ctrl:CheckComboBox x:Name="MemberDeliveryAncmtInput" AllItemsSelectedContent="Alle Lesepläne" Delimiter=", " DisplayMemberPath="Identifier"
|
<ctrl:CheckComboBox x:Name="MemberDeliveryAncmtInput" AllItemsSelectedContent="Alle Lesepläne" Delimiter=", " DisplayMemberPath="Identifier"
|
||||||
IsSelectAllActive="True" SelectAllContent="Alle Lesepläne"
|
IsSelectAllActive="True" SelectAllContent="Alle Lesepläne"
|
||||||
Margin="50,260,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
Margin="50,280,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
||||||
SelectionChanged="MemberInput_SelectionChanged"/>
|
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||||
|
|
||||||
<ctrl:CheckComboBox x:Name="MemberCustomInput" AllItemsSelectedContent="Alle Mitglieder" Delimiter=", " DisplayMemberPath="AdministrativeName"
|
<ctrl:CheckComboBox x:Name="MemberCustomInput" AllItemsSelectedContent="Alle Mitglieder" Delimiter=", " DisplayMemberPath="AdministrativeName"
|
||||||
IsSelectAllActive="True" SelectAllContent="Alle Mitglieder"
|
IsSelectAllActive="True" SelectAllContent="Alle Mitglieder"
|
||||||
Margin="10,140,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
Margin="10,160,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
||||||
SelectionChanged="MemberInput_SelectionChanged"/>
|
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
@@ -302,6 +305,9 @@
|
|||||||
<Button x:Name="GenerateButton" Content="Generieren"
|
<Button x:Name="GenerateButton" Content="Generieren"
|
||||||
Grid.Row="0" Grid.Column="0" FontSize="14"
|
Grid.Row="0" Grid.Column="0" FontSize="14"
|
||||||
Click="GenerateButton_Click"/>
|
Click="GenerateButton_Click"/>
|
||||||
|
<Button x:Name="AbortButton" Content="Abbrechen" Visibility="Hidden" IsEnabled="False"
|
||||||
|
Grid.Row="0" Grid.Column="0" FontSize="14"
|
||||||
|
Click="AbortButton_Click"/>
|
||||||
<ProgressBar x:Name="ProgressBar"
|
<ProgressBar x:Name="ProgressBar"
|
||||||
Grid.Row="2" Grid.Column="0" SnapsToDevicePixels="True"/>
|
Grid.Row="2" Grid.Column="0" SnapsToDevicePixels="True"/>
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
@@ -61,6 +62,8 @@ namespace Elwig.Windows {
|
|||||||
protected Dictionary<Member, List<Document>>? PrintMemberDocuments;
|
protected Dictionary<Member, List<Document>>? PrintMemberDocuments;
|
||||||
protected Dictionary<Member, List<Document>>? EmailDocuments;
|
protected Dictionary<Member, List<Document>>? EmailDocuments;
|
||||||
|
|
||||||
|
private CancellationTokenSource? CancelGeneration;
|
||||||
|
|
||||||
public static readonly DependencyProperty PostalAllCountProperty = DependencyProperty.Register(nameof(PostalAllCount), typeof(int), typeof(MailWindow));
|
public static readonly DependencyProperty PostalAllCountProperty = DependencyProperty.Register(nameof(PostalAllCount), typeof(int), typeof(MailWindow));
|
||||||
public int PostalAllCount {
|
public int PostalAllCount {
|
||||||
get => (int)GetValue(PostalAllCountProperty);
|
get => (int)GetValue(PostalAllCountProperty);
|
||||||
@@ -330,7 +333,35 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void DocumentAddButton_Click(object sender, RoutedEventArgs evt) {
|
private void AvaiableDocumentsList_MouseDoubleClick(object sender, MouseEventArgs evt) {
|
||||||
|
if (evt.LeftButton != MouseButtonState.Pressed) return;
|
||||||
|
var src = evt.OriginalSource;
|
||||||
|
if (src is Border b) {
|
||||||
|
src = (b.Child as ContentPresenter)?.Content.ToString();
|
||||||
|
} else if (src is TextBlock t) {
|
||||||
|
src = t.Text;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AvaiableDocumentsList.SelectedIndex = AvaiableDocumentsList.ItemsSource.Cast<object?>().ToList().IndexOf(src);
|
||||||
|
DocumentAddButton_Click(sender, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectedDocumentsList_MouseDoubleClick(object sender, MouseEventArgs evt) {
|
||||||
|
if (evt.LeftButton != MouseButtonState.Pressed) return;
|
||||||
|
var src = evt.OriginalSource;
|
||||||
|
if (src is Border b) {
|
||||||
|
src = (b.Child as ContentPresenter)?.Content.ToString();
|
||||||
|
} else if (src is TextBlock t) {
|
||||||
|
src = t.Text;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SelectedDocumentsList.SelectedItem = SelectedDocs.FirstOrDefault(d => d.Name == (string?)src);
|
||||||
|
DocumentRemoveButton_Click(sender, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void DocumentAddButton_Click(object sender, RoutedEventArgs? evt) {
|
||||||
var idx = AvaiableDocumentsList.SelectedIndex;
|
var idx = AvaiableDocumentsList.SelectedIndex;
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
if (AvaiableDocumentsList.SelectedItem is not string s)
|
if (AvaiableDocumentsList.SelectedItem is not string s)
|
||||||
@@ -344,13 +375,13 @@ namespace Elwig.Windows {
|
|||||||
var name = s.Split(" – ")[^1];
|
var name = s.Split(" – ")[^1];
|
||||||
var pv = await ctx.PaymentVariants.SingleAsync(v => v.Year == Year && v.Name == name)!;
|
var pv = await ctx.PaymentVariants.SingleAsync(v => v.Year == Year && v.Name == name)!;
|
||||||
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
||||||
RecipientsDeliveryMembersInput.IsChecked = true;
|
RecipientsCreditMembersInput.IsChecked = true;
|
||||||
}
|
}
|
||||||
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
||||||
await UpdateRecipients(ctx);
|
await UpdateRecipients(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void DocumentRemoveButton_Click(object sender, RoutedEventArgs evt) {
|
private async void DocumentRemoveButton_Click(object sender, RoutedEventArgs? evt) {
|
||||||
DeleteCommand.Execute(null);
|
DeleteCommand.Execute(null);
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
await UpdateRecipients(ctx);
|
await UpdateRecipients(ctx);
|
||||||
@@ -451,8 +482,11 @@ namespace Elwig.Windows {
|
|||||||
query = query.Where(m => m.Deliveries.Any(d => d.Year == Year));
|
query = query.Where(m => m.Deliveries.Any(d => d.Year == Year));
|
||||||
} else if (RecipientsNonDeliveryMembersInput.IsChecked == true) {
|
} else if (RecipientsNonDeliveryMembersInput.IsChecked == true) {
|
||||||
query = query.Where(m => m.IsActive && !m.Deliveries.Any(d => d.Year == Year));
|
query = query.Where(m => m.IsActive && !m.Deliveries.Any(d => d.Year == Year));
|
||||||
} else if (RecipientsActiveMembersInput.IsChecked == true && SelectedDocs.Any(d => d.Type == DocType.DeliveryConfirmation || d.Type == DocType.CreditNote)) {
|
} else if (RecipientsActiveMembersInput.IsChecked == true && SelectedDocs.Any(d => d.Type == DocType.DeliveryConfirmation || d.Type == DocType.CreditNote)) {
|
||||||
query = query.Where(m => m.IsActive || m.Deliveries.Any(d => d.Year == Year));
|
query = query.Where(m => m.IsActive || m.Deliveries.Any(d => d.Year == Year));
|
||||||
|
} else if (RecipientsCreditMembersInput.IsChecked == true) {
|
||||||
|
var avnrs = SelectedDocs.Where(d => d.Type == DocType.CreditNote).Select(d => (((int,int)?)d.Details)?.Item2).ToList();
|
||||||
|
query = query.Where(m => m.Credits.Any(c => c.Year == Year && avnrs.Contains(c.AvNr)));
|
||||||
} else {
|
} else {
|
||||||
query = query.Where(m => m.IsActive);
|
query = query.Where(m => m.IsActive);
|
||||||
}
|
}
|
||||||
@@ -594,20 +628,32 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Closed(object sender, EventArgs evt) {
|
private void Window_Closed(object sender, EventArgs evt) {
|
||||||
|
CancelGeneration?.Dispose();
|
||||||
DisposeDocs();
|
DisposeDocs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void AbortButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
CancelGeneration?.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
private async void GenerateButton_Click(object sender, RoutedEventArgs evt) {
|
private async void GenerateButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
LockInputs();
|
LockInputs();
|
||||||
PreviewButton.IsEnabled = false;
|
PreviewButton.IsEnabled = false;
|
||||||
PrintButton.IsEnabled = false;
|
PrintButton.IsEnabled = false;
|
||||||
EmailButton.IsEnabled = false;
|
EmailButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
|
AbortButton.IsEnabled = true;
|
||||||
|
AbortButton.Visibility = Visibility.Visible;
|
||||||
GenerateButton.IsEnabled = false;
|
GenerateButton.IsEnabled = false;
|
||||||
|
GenerateButton.Visibility = Visibility.Hidden;
|
||||||
|
|
||||||
DisposeDocs();
|
DisposeDocs();
|
||||||
await UpdateClientParameters();
|
await UpdateClientParameters();
|
||||||
|
|
||||||
|
CancelGeneration?.Dispose();
|
||||||
|
CancelGeneration = new();
|
||||||
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
|
|
||||||
var doublePaged = DoublePagedInput.IsChecked == true;
|
var doublePaged = DoublePagedInput.IsChecked == true;
|
||||||
@@ -662,6 +708,9 @@ namespace Elwig.Windows {
|
|||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
|
GenerateButton.Visibility = Visibility.Visible;
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
AbortButton.Visibility = Visibility.Hidden;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -679,6 +728,9 @@ namespace Elwig.Windows {
|
|||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
|
GenerateButton.Visibility = Visibility.Visible;
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
AbortButton.Visibility = Visibility.Hidden;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -735,11 +787,14 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
var hasPreviewDocs = memberDocs.Any(m => m.Docs.Any(d => d.Doc.IsPreview));
|
var hasPreviewDocs = memberDocs.Any(m => m.Docs.Any(d => d.Doc.IsPreview));
|
||||||
if (hasPreviewDocs) {
|
if (hasPreviewDocs) {
|
||||||
var res = MessageBox.Show("Einige der ausgewählten Dokumente sind nur als vorläufig zu betrachten und können daher nicht verschickt/ausgedruckt werden!\n\nDies könnte an einer noch nicht festgesetzen Auszahlungsvariante liegen.\n\nSoll mit dem Generieren fortgefahren werden?",
|
var res = MessageBox.Show("Einige der ausgewählten Dokumente sind nur als vorläufig zu betrachten und können daher nicht verschickt/ausgedruckt werden!\n\nDies könnte an einer noch nicht festgesetzen Auszahlungsvariante liegen oder daran, dass nicht alle Adressaten/Empfänger eine Traubengutschrift erhalten\n(\"Empfänger von Gutschriften\").\n\nSoll mit dem Generieren fortgefahren werden?",
|
||||||
"Vorläufige Dokumente", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
"Vorläufige Dokumente", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
||||||
if (res != MessageBoxResult.OK) {
|
if (res != MessageBoxResult.OK) {
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
|
GenerateButton.Visibility = Visibility.Visible;
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
AbortButton.Visibility = Visibility.Hidden;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -771,7 +826,7 @@ namespace Elwig.Windows {
|
|||||||
try {
|
try {
|
||||||
foreach (var item1 in email.Select((e, i) => new { Index = i, e.Key, e.Value })) {
|
foreach (var item1 in email.Select((e, i) => new { Index = i, e.Key, e.Value })) {
|
||||||
foreach (var item2 in item1.Value.Select((d, i) => new { Index = i, Doc = d })) {
|
foreach (var item2 in item1.Value.Select((d, i) => new { Index = i, Doc = d })) {
|
||||||
await item2.Doc.Generate(new Progress<double>(v => {
|
await item2.Doc.Generate(CancelGeneration.Token, new Progress<double>(v => {
|
||||||
ProgressBar.Value = v * (item2.Index + 1) / item1.Value.Count / totalNum + 100.0 * item1.Index / totalNum;
|
ProgressBar.Value = v * (item2.Index + 1) / item1.Value.Count / totalNum + 100.0 * item1.Index / totalNum;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -780,6 +835,9 @@ namespace Elwig.Windows {
|
|||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
|
GenerateButton.Visibility = Visibility.Visible;
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
AbortButton.Visibility = Visibility.Hidden;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -814,7 +872,7 @@ namespace Elwig.Windows {
|
|||||||
try {
|
try {
|
||||||
var print = Document.Merge(printDocs);
|
var print = Document.Merge(printDocs);
|
||||||
print.IsDoublePaged = doublePaged;
|
print.IsDoublePaged = doublePaged;
|
||||||
await print.Generate(new Progress<double>(v => {
|
await print.Generate(CancelGeneration.Token, new Progress<double>(v => {
|
||||||
ProgressBar.Value = 100.0 * emailNum / totalNum + v * printNum / totalNum;
|
ProgressBar.Value = 100.0 * emailNum / totalNum + v * printNum / totalNum;
|
||||||
}));
|
}));
|
||||||
PrintDocument = print;
|
PrintDocument = print;
|
||||||
@@ -823,6 +881,9 @@ namespace Elwig.Windows {
|
|||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
|
GenerateButton.Visibility = Visibility.Visible;
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
AbortButton.Visibility = Visibility.Hidden;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -834,6 +895,9 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
GenerateButton.IsEnabled = true;
|
GenerateButton.IsEnabled = true;
|
||||||
|
GenerateButton.Visibility = Visibility.Visible;
|
||||||
|
AbortButton.IsEnabled = false;
|
||||||
|
AbortButton.Visibility = Visibility.Hidden;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
PreviewButton.IsEnabled = true;
|
PreviewButton.IsEnabled = true;
|
||||||
PrintButton.IsEnabled = PrintDocument != null && !hasPreviewDocs;
|
PrintButton.IsEnabled = PrintDocument != null && !hasPreviewDocs;
|
||||||
@@ -981,7 +1045,7 @@ namespace Elwig.Windows {
|
|||||||
var pv = ctx.PaymentVariants.Single(v => v.Year == Year && v.Name == name)!;
|
var pv = ctx.PaymentVariants.Single(v => v.Year == Year && v.Name == name)!;
|
||||||
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
||||||
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
||||||
RecipientsDeliveryMembersInput.IsChecked = true;
|
RecipientsCreditMembersInput.IsChecked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DocumentInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void DocumentInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
|||||||
@@ -248,7 +248,7 @@
|
|||||||
<Button x:Name="BreakdownButton"
|
<Button x:Name="BreakdownButton"
|
||||||
Click="BreakdownButton_Click"
|
Click="BreakdownButton_Click"
|
||||||
Margin="195,90,0,10" Width="190" Padding="3,5,5,5"
|
Margin="195,90,0,10" Width="190" Padding="3,5,5,5"
|
||||||
ToolTip="Aufschlüsselung der Menge nach Zweigstelle, Mitglied, Sorte, Attribut/Bewirt., Qualitätsstufe, gebunden/ungebunden">
|
ToolTip="Aufschlüsselung der Menge nach Zweigstelle, Sorte, Attribut/Bewirt., Qualitätsstufe, gebunden/ungebunden">
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""
|
||||||
TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,0.5,0,0"/>
|
TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,0.5,0,0"/>
|
||||||
|
|||||||
@@ -16,16 +16,14 @@ namespace Elwig.Windows {
|
|||||||
public partial class PaymentAdjustmentWindow : ContextWindow {
|
public partial class PaymentAdjustmentWindow : ContextWindow {
|
||||||
|
|
||||||
public readonly int Year;
|
public readonly int Year;
|
||||||
public readonly bool SeasonLocked;
|
public readonly bool SeasonLocked = false; // never locked
|
||||||
|
|
||||||
public Dictionary<int, PaymentCustom>? CustomPayments;
|
public Dictionary<int, PaymentCustom>? CustomPayments;
|
||||||
|
|
||||||
public PaymentAdjustmentWindow(int year) {
|
public PaymentAdjustmentWindow(int year) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Year = year;
|
Year = year;
|
||||||
using (var ctx = new AppDbContext()) {
|
// using (var ctx = new AppDbContext()) { SeasonLocked = ctx.Seasons.Find(Year + 1) != null; }
|
||||||
SeasonLocked = ctx.Seasons.Find(Year + 1) != null;
|
|
||||||
}
|
|
||||||
Title = $"Auszahlung anpassen - Lese {Year} - Elwig";
|
Title = $"Auszahlung anpassen - Lese {Year} - Elwig";
|
||||||
AutoAdjustBsButton.IsEnabled = !SeasonLocked;
|
AutoAdjustBsButton.IsEnabled = !SeasonLocked;
|
||||||
UnAdjustBsButton.IsEnabled = !SeasonLocked;
|
UnAdjustBsButton.IsEnabled = !SeasonLocked;
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using Elwig.Helpers.Billing;
|
using Elwig.Helpers.Billing;
|
||||||
using Elwig.Helpers.Export;
|
|
||||||
using Elwig.Models.Dtos;
|
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Services;
|
using Elwig.Services;
|
||||||
using Elwig.ViewModels;
|
using Elwig.ViewModels;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Win32;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -35,9 +32,7 @@ namespace Elwig.Windows {
|
|||||||
CommandBindings.Add(new CommandBinding(CtrlÜ, Menu_EbicsSave_Click));
|
CommandBindings.Add(new CommandBinding(CtrlÜ, Menu_EbicsSave_Click));
|
||||||
CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_SummaryPrint_Click));
|
CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_SummaryPrint_Click));
|
||||||
Year = year;
|
Year = year;
|
||||||
using (var ctx = new AppDbContext()) {
|
// using (var ctx = new AppDbContext()) { ViewModel.SeasonLocked = ctx.Seasons.Find(Year + 1) != null; }
|
||||||
ViewModel.SeasonLocked = ctx.Seasons.Find(Year + 1) != null;
|
|
||||||
}
|
|
||||||
Title = $"Auszahlungsvarianten - Lese {Year} - Elwig";
|
Title = $"Auszahlungsvarianten - Lese {Year} - Elwig";
|
||||||
if (!App.Config.Debug) {
|
if (!App.Config.Debug) {
|
||||||
DataInput.Visibility = Visibility.Hidden;
|
DataInput.Visibility = Visibility.Hidden;
|
||||||
@@ -55,6 +50,9 @@ namespace Elwig.Windows {
|
|||||||
.OrderBy(v => v.AvNr)
|
.OrderBy(v => v.AvNr)
|
||||||
.Include(v => v.Season.Currency)
|
.Include(v => v.Season.Currency)
|
||||||
.ToListAsync());
|
.ToListAsync());
|
||||||
|
if (PaymentVariantList.SelectedItem == null && PaymentVariantList.Items.Count > 0) {
|
||||||
|
PaymentVariantList.SelectedIndex = PaymentVariantList.Items.Count - 1;
|
||||||
|
}
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +117,11 @@ namespace Elwig.Windows {
|
|||||||
private async void DeleteButton_Click(object sender, RoutedEventArgs evt) {
|
private async void DeleteButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (PaymentVariantList.SelectedItem is not PaymentVar v || !v.TestVariant)
|
if (PaymentVariantList.SelectedItem is not PaymentVar v || !v.TestVariant)
|
||||||
return;
|
return;
|
||||||
|
var res = MessageBox.Show(
|
||||||
|
$"Soll die Auszahlungsvariante \"{v.Name}\" wirklich unwiderruflich gelöscht werden?",
|
||||||
|
"Auszahlungsvariante löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
||||||
|
if (res != MessageBoxResult.OK)
|
||||||
|
return;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
try {
|
try {
|
||||||
await PaymentVariantService.DeletePaymentVariant(v.Year, v.AvNr);
|
await PaymentVariantService.DeletePaymentVariant(v.Year, v.AvNr);
|
||||||
|
|||||||
Binary file not shown.
@@ -13,7 +13,7 @@ About
|
|||||||
**Product:** Elwig
|
**Product:** Elwig
|
||||||
**Description:** Electronic Management for Vintners' Cooperatives
|
**Description:** Electronic Management for Vintners' Cooperatives
|
||||||
**Type:** ERP system
|
**Type:** ERP system
|
||||||
**Version:** 1.0.2.0 ([Changelog](./CHANGELOG.md))
|
**Version:** 1.0.3.4 ([Changelog](./CHANGELOG.md))
|
||||||
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||||
**Website:** https://elwig.at/
|
**Website:** https://elwig.at/
|
||||||
**Source code:** https://git.necronda.net/winzer/elwig
|
**Source code:** https://git.necronda.net/winzer/elwig
|
||||||
@@ -33,7 +33,7 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
|||||||
**Produkt:** Elwig
|
**Produkt:** Elwig
|
||||||
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
||||||
**Typ:** Warenwirtschaftssystem (ERP-System)
|
**Typ:** Warenwirtschaftssystem (ERP-System)
|
||||||
**Version:** 1.0.2.0 ([Änderungsprotokoll](./CHANGELOG.md))
|
**Version:** 1.0.3.4 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||||
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||||
**Website:** https://elwig.at/
|
**Website:** https://elwig.at/
|
||||||
**Quellcode:** https://git.necronda.net/winzer/elwig
|
**Quellcode:** https://git.necronda.net/winzer/elwig
|
||||||
@@ -43,5 +43,5 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
|||||||
Programmiersprache: C#
|
Programmiersprache: C#
|
||||||
Framework: Windows Presentation Framework (WPF)
|
Framework: Windows Presentation Framework (WPF)
|
||||||
Datenbank: [SQLite](https://sqlite.org/)
|
Datenbank: [SQLite](https://sqlite.org/)
|
||||||
PDF-Erstellung: [WeasyPrint](https://weasyprint.org/), [RazorLight](https://github.com/toddams/RazorLight), [PdfiumViewer](https://github.com/pvginkel/PdfiumViewer)
|
PDF-Erstellung: [WeasyPrint](https://weasyprint.org/), [RazorLight](https://github.com/toddams/RazorLight), [Pdfium](https://github.com/bblanchon/pdfium-binaries)
|
||||||
Paketierung: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
Paketierung: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||||
|
|||||||
@@ -8,18 +8,18 @@
|
|||||||
SuppressOptionsUI="yes" ShowVersion="yes"/>
|
SuppressOptionsUI="yes" ShowVersion="yes"/>
|
||||||
</BootstrapperApplication>
|
</BootstrapperApplication>
|
||||||
|
|
||||||
<util:RegistrySearch Id="VCredistx86" Variable="VCredistx86" Result="exists"
|
<util:RegistrySearch Id="VCredistx64" Variable="VCredistx64" Result="exists"
|
||||||
Root="HKLM" Key="SOFTWARE\Classes\Installer\Dependencies\VC,redist.x86,x86,14.36,bundle"/>
|
Root="HKLM" Key="SOFTWARE\Classes\Installer\Dependencies\VC,redist.x64,amd64,14.50,bundle"/>
|
||||||
<util:RegistrySearch Id="Webview2Machine" Variable="Webview2Machine" Result="exists"
|
<util:RegistrySearch Id="Webview2Machine" Variable="Webview2Machine" Result="exists"
|
||||||
Root="HKLM" Key="SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"/>
|
Root="HKLM" Key="SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"/>
|
||||||
<util:RegistrySearch Id="Webview2User" Variable="Webview2User" Result="exists"
|
<util:RegistrySearch Id="Webview2User" Variable="Webview2User" Result="exists"
|
||||||
Root="HKCU" Key="Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"/>
|
Root="HKCU" Key="Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"/>
|
||||||
|
|
||||||
<Chain>
|
<Chain>
|
||||||
<ExePackage Id="VCredistx86Installer" DisplayName="VC Redist x86 installer" Name="VC_redist.x86.exe"
|
<ExePackage Id="VCredistx64Installer" DisplayName="VC Redist x64 installer" Name="VC_redist.x64.exe"
|
||||||
SourceFile="$(ProjectDir)\Files\VC_redist.x86.exe"
|
SourceFile="$(ProjectDir)\Files\VC_redist.x64.exe"
|
||||||
Cache="remove" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes"
|
Cache="remove" Compressed="yes" PerMachine="yes" Permanent="yes" Vital="yes"
|
||||||
InstallArguments="/install /passive /norestart" DetectCondition="VCredistx86"/>
|
InstallArguments="/install /passive /norestart" DetectCondition="VCredistx64"/>
|
||||||
<ExePackage Id="MicrosoftEdgeWebview2" DisplayName="Microsoft Edge Webview2 Runtime" Name="MicrosoftEdgeWebview2Setup.exe"
|
<ExePackage Id="MicrosoftEdgeWebview2" DisplayName="Microsoft Edge Webview2 Runtime" Name="MicrosoftEdgeWebview2Setup.exe"
|
||||||
SourceFile="$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe"
|
SourceFile="$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe"
|
||||||
Cache="remove" Compressed="yes" PerMachine="yes" Permanent ="yes" Vital="no"
|
Cache="remove" Compressed="yes" PerMachine="yes" Permanent ="yes" Vital="no"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
||||||
<Exec Command="curl --fail -s -L "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -z "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe" -o "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe"" />
|
<Exec Command="curl --fail -s -L "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -z "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe" -o "$(ProjectDir)\Files\MicrosoftEdgeWebview2Setup.exe"" />
|
||||||
<Exec Command="curl --fail -s -L "https://aka.ms/vs/17/release/vc_redist.x86.exe" -z "$(ProjectDir)\Files\VC_redist.x86.exe" -o "$(ProjectDir)\Files\VC_redist.x86.exe"" />
|
<Exec Command="curl --fail -s -L "https://aka.ms/vc14/vc_redist.x64.exe" -z "$(ProjectDir)\Files\VC_redist.x64.exe" -o "$(ProjectDir)\Files\VC_redist.x64.exe"" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<DefineConstants>ElwigProjectDir=..\Elwig</DefineConstants>
|
<DefineConstants>ElwigProjectDir=..\Elwig</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -22,13 +22,13 @@
|
|||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
|
||||||
<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.4.0" />
|
<PackageReference Include="NUnit" Version="4.5.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="5.2.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.11.2">
|
<PackageReference Include="NUnit.Analyzers" Version="4.11.2">
|
||||||
<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.4">
|
<PackageReference Include="coverlet.collector" Version="8.0.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>
|
||||||
|
|||||||
Reference in New Issue
Block a user