Compare commits
1 Commits
v1.0.4.1
...
700e1ec92c
| Author | SHA1 | Date | |
|---|---|---|---|
| 700e1ec92c |
46
CHANGELOG.md
46
CHANGELOG.md
@@ -2,52 +2,6 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
[v1.0.4.1][v1.0.4.1] (2026-03-27) {#v1.0.4.1}
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
### Behobene Fehler {#v1.0.4.1-bugfixes}
|
|
||||||
|
|
||||||
* In der Anlieferungsbestätigung (`DeliveryConfirmation`) war in einer Spalte der Text nicht rechtsbündig. (0aefab5d63)
|
|
||||||
* Die zweite Zeile des Absenders wurde nicht mehr abgedruckt und der Briefkopf (`Letterhead`) beinhaltete zu viele Informationen. (3c52156b7e)
|
|
||||||
|
|
||||||
### Sonstiges {#v1.0.4.1-misc}
|
|
||||||
|
|
||||||
* Evtl. wurden bei Änderungen in der Datenbank unnötigerweise einige Daten in Elwig doppelt angefordert. (cc018ded10)
|
|
||||||
* Massenaktionen im Lieferungen-Fenster (`DeliveryAdminWindow`) sind nun nicht mehr während dem Bearbeiten oder Erstellen möglich. (b1075d1e69)
|
|
||||||
* Das Datum auf Lieferscheinen (`DeliveryNote`) ist nun statt des heutigen, das Datum der letzten Änderung der Lieferung. (982a6616e1)
|
|
||||||
* Sollte es im Rundschreiben-Fenster (`MailWindow`) zu einem Fehler während dem Bereinigen der Dokumenten kommen wird dieser ignoriert. (ae0a082421)
|
|
||||||
* Abhängigkeiten aktualisiert. (ddfc86197d, cdb4b0a2bd)
|
|
||||||
|
|
||||||
[v1.0.4.1]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.4.1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[v1.0.4.0][v1.0.4.0] (2026-03-16) {#v1.0.4.0}
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
### Neue Funktionen {#v1.0.4.0-features}
|
|
||||||
|
|
||||||
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) gibt es nun über die Menü-Leiste die Möglichkeit _Massenaktionen_ für mehrere Lieferungen durchzuführen (z.B. Attribut oder Zu-/Abschlag setzen). ([#78][i78])
|
|
||||||
|
|
||||||
### Behobene Fehler {#v1.0.4.0-bugfixes}
|
|
||||||
|
|
||||||
* Waagen mit Netzwerkschnittstelle versuchen die Verbindung nun wieder neu aufzubauen, sollte diese unterbrochen werden. ([#74][i74])
|
|
||||||
|
|
||||||
### Sonstiges {#v1.0.4.0-misc}
|
|
||||||
|
|
||||||
* Die bisher verwendeten Programm-Bibliotheken zum Erstellen von PDF-Dokumente wurden vollständig durch [iText](https://itextpdf.com/) ersetzt.
|
|
||||||
Das ermöglicht ein schnelleres, effizienteres, und stabileres Erstellen der PDF-Dokumente.
|
|
||||||
Außerdem konnte so die Größe der Installations-Datei von ~138 MB auf ~98 MB um ca. 30 % reduziert werden. (d8c967b2f2, 8054a024f4)
|
|
||||||
* Abhängigkeiten aktualisiert. (af73226c90, f4fddd111f)
|
|
||||||
|
|
||||||
[v1.0.4.0]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.4.0
|
|
||||||
[i74]: https://git.necronda.net/winzer/elwig/issues/74
|
|
||||||
[i78]: https://git.necronda.net/winzer/elwig/issues/78
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[v1.0.3.4][v1.0.3.4] (2026-02-19) {#v1.0.3.4}
|
[v1.0.3.4][v1.0.3.4] (2026-02-19) {#v1.0.3.4}
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Elwig.Helpers;
|
|||||||
using Elwig.Models;
|
using Elwig.Models;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using iText.Kernel.Colors;
|
using iText.Kernel.Colors;
|
||||||
using iText.Kernel.Geom;
|
|
||||||
using iText.Kernel.Pdf;
|
using iText.Kernel.Pdf;
|
||||||
using iText.Kernel.Pdf.Action;
|
using iText.Kernel.Pdf.Action;
|
||||||
using iText.Kernel.Pdf.Canvas;
|
using iText.Kernel.Pdf.Canvas;
|
||||||
@@ -54,8 +53,9 @@ namespace Elwig.Documents {
|
|||||||
IncludeSender = includeSender;
|
IncludeSender = includeSender;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.RenderHeader(doc, pdf);
|
||||||
|
|
||||||
var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10);
|
var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10);
|
||||||
if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)"));
|
if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)"));
|
||||||
Aside = new Table(ColsMM(22.5, 42.5))
|
Aside = new Table(ColsMM(22.5, 42.5))
|
||||||
@@ -68,20 +68,6 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RenderAddress(Canvas canvas, Rectangle pageSize) {
|
|
||||||
canvas.Add(new Div()
|
|
||||||
.SetFixedPositionMM(25, 50, 80, 45, pageSize)
|
|
||||||
.SetFont(NF)
|
|
||||||
.Add(new KernedParagraph(IncludeSender ? $"{App.Client.Sender1}\n{App.Client.Sender2}" : "", 8).SetMargins(8, 0, 8, 0).SetHeight(16.0625f))
|
|
||||||
.Add(new KernedParagraph(Address, 12).SetMargin(0).SetHeight(12 * 5)));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void RenderAside(Table aside, Canvas canvas, Rectangle pageSize) {
|
|
||||||
canvas.Add(new Div()
|
|
||||||
.SetFixedPositionMM(125, 50, 65, 50, pageSize)
|
|
||||||
.Add(aside));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.RenderBody(doc, pdf);
|
base.RenderBody(doc, pdf);
|
||||||
|
|
||||||
@@ -98,10 +84,16 @@ namespace Elwig.Documents {
|
|||||||
header.Add(new KernedParagraph(App.Client.NameTypeFull, 12).SetFont(NF).SetMargin(0));
|
header.Add(new KernedParagraph(App.Client.NameTypeFull, 12).SetFont(NF).SetMargin(0));
|
||||||
canvas.Add(header);
|
canvas.Add(header);
|
||||||
// address
|
// address
|
||||||
RenderAddress(canvas, pageSize);
|
canvas.Add(new Div()
|
||||||
|
.SetFixedPositionMM(25, 50, 80, 45, pageSize)
|
||||||
|
.SetFont(NF)
|
||||||
|
.Add(new KernedParagraph(IncludeSender ? $"{App.Client.Sender1}\n{App.Client.Sender2}" : "", 8).SetMargin(0).SetHeight(16).SetPaddings(8, 0, 8, 0))
|
||||||
|
.Add(new KernedParagraph(Address, 12).SetMargin(0).SetHeight(12 * 5)));
|
||||||
// aside
|
// aside
|
||||||
if (Aside != null) {
|
if (Aside != null) {
|
||||||
RenderAside(Aside, canvas, pageSize);
|
canvas.Add(new Div()
|
||||||
|
.SetFixedPositionMM(125, 50, 65, 50, pageSize)
|
||||||
|
.Add(Aside));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.RenderHeader(doc, pdf);
|
||||||
Aside?.AddCell(NewAsideCell("Gutschrift", 2))
|
Aside?.AddCell(NewAsideCell("Gutschrift", 2))
|
||||||
.AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-"))
|
.AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-"))
|
||||||
.AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}"))
|
.AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}"))
|
||||||
@@ -109,14 +109,14 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
var div = new Table(ColsMM(60, 105))
|
var div = new Table(ColsMM(60, 105))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
|
.SetBorderTop(new SolidBorder(BorderThickness));
|
||||||
var hint = new KernedParagraph(8)
|
var hint = new KernedParagraph(8)
|
||||||
.Add(Italic("Hinweis:\n" +
|
.Add(Italic("Hinweis:\n" +
|
||||||
$"Die Summe der Lieferungen und die Summe der anfal\u00adlenden Pönalen werden mit " +
|
$"Die Summe der Lieferungen und die Summe der anfal\u00adlenden Pönalen werden mit " +
|
||||||
$"{Payment?.Variant.Season.Precision} Nach\u00adkomma-stellen berechnent, " +
|
$"{Payment?.Variant.Season.Precision} Nach\u00adkomma-stellen berechnent, " +
|
||||||
$"erst das Ergebnis wird kauf-männisch auf 2 Nach\u00adkomma\u00adstellen gerundet."))
|
$"erst das Ergebnis wird kauf-männisch auf 2 Nach\u00adkomma\u00adstellen gerundet."))
|
||||||
.SetWidth(56 * PtInMM).SetMarginsMM(4, 2, 4, 2);
|
.SetWidth(56 * PtInMM).SetMarginsMM(4, 2, 4, 2);
|
||||||
div.AddCell(new Cell(1, 2).SetPadding(0).SetBorder(Border.NO_BORDER).SetBorderTop(new SolidBorder(BorderThickness)));
|
|
||||||
div.AddCell(new Cell(3, 1).SetPadding(0).SetBorder(Border.NO_BORDER).Add(hint).SetKeepTogether(true));
|
div.AddCell(new Cell(3, 1).SetPadding(0).SetBorder(Border.NO_BORDER).Add(hint).SetKeepTogether(true));
|
||||||
var tbl1 = new Table(ColsMM(70, 5, 5, 25))
|
var tbl1 = new Table(ColsMM(70, 5, 5, 25))
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
@@ -203,12 +203,12 @@ namespace Elwig.Documents {
|
|||||||
div.AddCell(new Cell().SetPadding(0).SetBorder(Border.NO_BORDER).Add(tbl1));
|
div.AddCell(new Cell().SetPadding(0).SetBorder(Border.NO_BORDER).Add(tbl1));
|
||||||
div.AddCell(new Cell().SetPadding(0).SetBorder(Border.NO_BORDER).Add(tbl2));
|
div.AddCell(new Cell().SetPadding(0).SetBorder(Border.NO_BORDER).Add(tbl2));
|
||||||
div.AddCell(new Cell().SetPadding(0).SetBorder(Border.NO_BORDER).Add(tbl3));
|
div.AddCell(new Cell().SetPadding(0).SetBorder(Border.NO_BORDER).Add(tbl3));
|
||||||
doc.Add(div);
|
doc.Add(div.SetMarginBottomMM(10));
|
||||||
|
|
||||||
if (comment != null) {
|
if (comment != null) {
|
||||||
doc.Add(new KernedParagraph($"*{comment}", 12).SetMarginTopMM(10));
|
doc.Add(new KernedParagraph($"*{comment}", 12));
|
||||||
}
|
}
|
||||||
doc.Add(new KernedParagraph($"Überweisung erfolgt auf Konto {Utils.FormatIban(Member.Iban ?? "-")}.", 12).SetPaddingTopMM(10));
|
doc.Add(new KernedParagraph($"Überweisung erfolgt auf Konto {Utils.FormatIban(Member.Iban ?? "-")}.", 12));
|
||||||
if (Text != null) {
|
if (Text != null) {
|
||||||
doc.Add(new KernedParagraph(Text, 12).SetMarginTop(12).SetKeepTogether(true));
|
doc.Add(new KernedParagraph(Text, 12).SetMarginTop(12).SetKeepTogether(true));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ namespace Elwig.Documents {
|
|||||||
MemberStats = AppDbContext.GetMemberStats(Season.Year, m.MgNr).GetAwaiter().GetResult();
|
MemberStats = AppDbContext.GetMemberStats(Season.Year, m.MgNr).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.RenderHeader(doc, pdf);
|
||||||
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
||||||
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
||||||
Aside?.AddCell(NewAsideCell("Saison", 2))
|
Aside?.AddCell(NewAsideCell("Saison", 2))
|
||||||
@@ -120,8 +120,8 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i == p.Buckets.Length - 1) {
|
if (i == p.Buckets.Length - 1) {
|
||||||
sub.AddCell(NewTd($"{p.Weight:N0}", right: true));
|
sub.AddCell(NewTd($"{p.Weight:N0}"));
|
||||||
sub.AddCell(NewTd(p.IsNetWeight ? "\u2611" : "\u2610", 7, right: true).SetFont(SF).SetPadding(0));
|
sub.AddCell(NewTd(p.IsNetWeight ? "\u2611" : "\u2610", 7, center: true).SetFont(SF).SetPadding(0));
|
||||||
} else {
|
} else {
|
||||||
sub.AddCell(NewCell(colspan: 2));
|
sub.AddCell(NewCell(colspan: 2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,12 @@ namespace Elwig.Documents {
|
|||||||
Delivery = d;
|
Delivery = d;
|
||||||
Text = App.Client.TextDeliveryNote;
|
Text = App.Client.TextDeliveryNote;
|
||||||
DocumentId = d.LsNr;
|
DocumentId = d.LsNr;
|
||||||
Date = DateOnly.FromDateTime(d.ModifiedAt);
|
|
||||||
IsDoublePaged = true;
|
IsDoublePaged = true;
|
||||||
MemberBuckets = ctx?.GetMemberBuckets(d.Year, d.Member.MgNr).GetAwaiter().GetResult() ?? [];
|
MemberBuckets = ctx?.GetMemberBuckets(d.Year, d.Member.MgNr).GetAwaiter().GetResult() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.RenderHeader(doc, pdf);
|
||||||
Aside?.AddCell(NewAsideCell("Lieferung", 2))
|
Aside?.AddCell(NewAsideCell("Lieferung", 2))
|
||||||
.AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr))
|
.AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr))
|
||||||
.AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}"))
|
.AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}"))
|
||||||
|
|||||||
@@ -88,15 +88,11 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int Render(string path) {
|
public int Render(string path) {
|
||||||
using (var writer = new PdfWriter(path)) {
|
using var writer = new PdfWriter(path);
|
||||||
Render(writer);
|
return Render(writer);
|
||||||
}
|
|
||||||
using var reader = new PdfReader(path);
|
|
||||||
using var pdf = new PdfDocument(reader);
|
|
||||||
return pdf.GetNumberOfPages();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Render(PdfWriter writer) {
|
private int Render(PdfWriter writer) {
|
||||||
NF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\times.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
NF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\times.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
||||||
BF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesbd.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
BF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesbd.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
||||||
IF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesi.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
IF = PdfFontFactory.CreateFont(@"C:\Windows\Fonts\timesi.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);
|
||||||
@@ -121,14 +117,16 @@ namespace Elwig.Documents {
|
|||||||
_doc = new iText.Layout.Document(pdf, iText.Kernel.Geom.PageSize.A4);
|
_doc = new iText.Layout.Document(pdf, iText.Kernel.Geom.PageSize.A4);
|
||||||
try {
|
try {
|
||||||
_doc.SetFont(NF).SetFontSize(12);
|
_doc.SetFont(NF).SetFontSize(12);
|
||||||
BeforeRenderBody(_doc, pdf);
|
RenderHeader(_doc, pdf);
|
||||||
RenderBody(_doc, pdf);
|
RenderBody(_doc, pdf);
|
||||||
|
var pageNum = pdf.GetNumberOfPages();
|
||||||
|
return pageNum;
|
||||||
} finally {
|
} finally {
|
||||||
_doc.Close();
|
_doc.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
protected virtual void RenderHeader(iText.Layout.Document doc, PdfDocument pdf) { }
|
||||||
|
|
||||||
protected virtual void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
protected virtual void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
||||||
|
|
||||||
@@ -152,77 +150,84 @@ namespace Elwig.Documents {
|
|||||||
using var mergedPdf = new PdfDocument(writer);
|
using var mergedPdf = new PdfDocument(writer);
|
||||||
var merger = new PdfMerger(mergedPdf);
|
var merger = new PdfMerger(mergedPdf);
|
||||||
|
|
||||||
(PdfPage Page, int InsertIndex, int DocIndex)? letterhead = null;
|
PdfPage? letterheadPage = null;
|
||||||
|
int letterheadInsertIndex = 0;
|
||||||
|
int letterheadDocIndex = 0;
|
||||||
|
|
||||||
int p = mergedPdf.GetNumberOfPages();
|
|
||||||
for (int i = 0; i < m.Documents.Count; i++) {
|
for (int i = 0; i < m.Documents.Count; i++) {
|
||||||
if (cancelToken?.IsCancellationRequested ?? false)
|
if (cancelToken?.IsCancellationRequested ?? false)
|
||||||
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||||
var doc = m.Documents[i];
|
var doc = m.Documents[i];
|
||||||
int p0 = p;
|
int p0 = mergedPdf.GetNumberOfPages();
|
||||||
|
|
||||||
if (letterhead != null && doc is Letterhead) {
|
if (letterheadPage != null && doc is Letterhead) {
|
||||||
if (p0 <= letterhead.Value.InsertIndex) {
|
if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) {
|
||||||
mergedPdf.AddPage(letterhead.Value.Page);
|
mergedPdf.AddPage(letterheadPage);
|
||||||
mergedPdf.AddNewPage();
|
mergedPdf.AddNewPage();
|
||||||
} else {
|
} else {
|
||||||
mergedPdf.AddPage(letterhead.Value.InsertIndex + 1, letterhead.Value.Page);
|
mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage);
|
||||||
mergedPdf.AddNewPage(letterhead.Value.InsertIndex + 2);
|
mergedPdf.AddNewPage(letterheadInsertIndex + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pageNums[letterhead.Value.DocIndex] = 1;
|
pageNums[letterheadDocIndex] = 1;
|
||||||
letterhead = null;
|
letterheadPage = null;
|
||||||
p += 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc is RawPdfDocument) {
|
if (doc is RawPdfDocument) {
|
||||||
using var reader = new PdfReader(doc.PdfPath);
|
if (IsDoublePaged && doc is Letterhead) {
|
||||||
using var src = new PdfDocument(reader);
|
using var reader = new PdfReader(doc.PdfPath);
|
||||||
merger.Merge(src, 1, src.GetNumberOfPages());
|
using var src = new PdfDocument(reader);
|
||||||
p += src.GetNumberOfPages();
|
letterheadPage = src.GetPage(1).CopyTo(mergedPdf);
|
||||||
|
letterheadInsertIndex = p0;
|
||||||
|
letterheadDocIndex = i;
|
||||||
|
} else {
|
||||||
|
using var reader = new PdfReader(doc.PdfPath);
|
||||||
|
using var src = new PdfDocument(reader);
|
||||||
|
merger.Merge(src, 1, src.GetNumberOfPages());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int pageNum = doc.Render(tmpPdf.FilePath);
|
int pageNum = doc.Render(tmpPdf.FilePath);
|
||||||
if (IsDoublePaged && doc is Letterhead) {
|
if (IsDoublePaged && doc is Letterhead) {
|
||||||
using var reader = new PdfReader(tmpPdf.FilePath);
|
using var reader = new PdfReader(tmpPdf.FilePath);
|
||||||
using var src = new PdfDocument(reader);
|
using var src = new PdfDocument(reader);
|
||||||
letterhead = (src.GetPage(1).CopyTo(mergedPdf), p0, i);
|
letterheadPage = src.GetPage(1).CopyTo(mergedPdf);
|
||||||
|
letterheadInsertIndex = p0;
|
||||||
|
letterheadDocIndex = i;
|
||||||
} else {
|
} else {
|
||||||
using var reader = new PdfReader(tmpPdf.FilePath);
|
using var reader = new PdfReader(tmpPdf.FilePath);
|
||||||
using var src = new PdfDocument(reader);
|
using var src = new PdfDocument(reader);
|
||||||
merger.Merge(src, 1, pageNum);
|
merger.Merge(src, 1, pageNum);
|
||||||
p += pageNum;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int p1 = p;
|
int p1 = mergedPdf.GetNumberOfPages();
|
||||||
pageNums.Add(p1 - p0);
|
pageNums.Add(p1 - p0);
|
||||||
|
|
||||||
if (IsDoublePaged && doc is not Letterhead && p % 2 != 0) {
|
if (IsDoublePaged && doc is not Letterhead && mergedPdf.GetNumberOfPages() % 2 != 0) {
|
||||||
if (letterhead != null) {
|
if (letterheadPage != null) {
|
||||||
mergedPdf.AddPage(letterhead.Value.Page);
|
mergedPdf.AddPage(letterheadPage);
|
||||||
letterhead = null;
|
letterheadPage = null;
|
||||||
} else {
|
} else {
|
||||||
mergedPdf.AddNewPage();
|
mergedPdf.AddNewPage();
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progress?.Report(100.0 * (i + 1) / (m.Documents.Count + 1));
|
progress?.Report(100.0 * (i + 1) / (m.Documents.Count + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (letterhead != null) {
|
if (letterheadPage != null) {
|
||||||
if (p <= letterhead.Value.InsertIndex) {
|
if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) {
|
||||||
mergedPdf.AddPage(letterhead.Value.Page);
|
mergedPdf.AddPage(letterheadPage.CopyTo(mergedPdf));
|
||||||
mergedPdf.AddNewPage();
|
mergedPdf.AddNewPage();
|
||||||
} else {
|
} else {
|
||||||
mergedPdf.AddPage(letterhead.Value.InsertIndex + 1, letterhead.Value.Page);
|
mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage.CopyTo(mergedPdf));
|
||||||
mergedPdf.AddNewPage(letterhead.Value.InsertIndex + 2);
|
mergedPdf.AddNewPage(letterheadInsertIndex + 2);
|
||||||
}
|
}
|
||||||
pageNums[letterhead.Value.DocIndex] = 1;
|
|
||||||
p += 2;
|
pageNums[letterheadDocIndex] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TotalPages = p;
|
TotalPages = pageNums.Sum();
|
||||||
} catch {
|
} catch {
|
||||||
pdf.Dispose();
|
pdf.Dispose();
|
||||||
throw;
|
throw;
|
||||||
@@ -292,7 +297,7 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
protected Cell NewTh(string? text, float fontSize = 8, int rowspan = 1, int colspan = 1, bool left = false, bool rotated = false) {
|
protected Cell NewTh(string? text, float fontSize = 8, int rowspan = 1, int colspan = 1, bool left = false, bool rotated = false) {
|
||||||
var p = new KernedParagraph(text ?? "", fontSize);
|
var p = new KernedParagraph(text ?? "", fontSize);
|
||||||
if (rotated) p.SetRotationAngle(0.5 * Math.PI);
|
if (rotated) p.SetRotationAngle(rotated ? 0.5 * Math.PI : 0);
|
||||||
var cell = NewCell(p, rowspan: rowspan, colspan: colspan)
|
var cell = NewCell(p, rowspan: rowspan, colspan: colspan)
|
||||||
.SetTextAlignment(left ? TextAlignment.LEFT : TextAlignment.CENTER)
|
.SetTextAlignment(left ? TextAlignment.LEFT : TextAlignment.CENTER)
|
||||||
.SetVerticalAlignment(VerticalAlignment.MIDDLE)
|
.SetVerticalAlignment(VerticalAlignment.MIDDLE)
|
||||||
@@ -389,8 +394,6 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageEnd(PdfDocumentEvent evt) {
|
private void OnPageEnd(PdfDocumentEvent evt) {
|
||||||
if (_doc is Letterhead) return;
|
|
||||||
|
|
||||||
var pdf = evt.GetDocument();
|
var pdf = evt.GetDocument();
|
||||||
var page = evt.GetPage();
|
var page = evt.GetPage();
|
||||||
var pageNum = pdf.GetPageNumber(page);
|
var pageNum = pdf.GetPageNumber(page);
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using iText.Kernel.Pdf;
|
|
||||||
using iText.Kernel.Pdf.Canvas;
|
|
||||||
using iText.Layout;
|
|
||||||
|
|
||||||
namespace Elwig.Documents {
|
namespace Elwig.Documents {
|
||||||
public class Letterhead : BusinessDocument {
|
public class Letterhead : BusinessDocument {
|
||||||
public Letterhead(Member m) :
|
public Letterhead(Member m) :
|
||||||
base($"Briefkopf {m.FullName}", m, true) {
|
base($"Briefkopf {m.FullName}", m, true) {
|
||||||
}
|
Aside = null;
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
|
||||||
// do not render anything except this
|
|
||||||
var page = pdf.AddNewPage();
|
|
||||||
var pageSize = page.GetPageSize();
|
|
||||||
var pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdf);
|
|
||||||
using var canvas = new Canvas(pdfCanvas, pageSize);
|
|
||||||
RenderAddress(canvas, pageSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>1.0.4.1</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>
|
||||||
@@ -23,22 +23,22 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="148.0.7749" />
|
<PackageReference Include="bblanchon.PDFium.Win32" Version="147.0.7690" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
<PackageReference Include="itext" Version="9.5.0" />
|
<PackageReference Include="itext" Version="9.5.0" />
|
||||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.5.0" />
|
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.5.0" />
|
||||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||||
<PackageReference Include="MailKit" Version="4.15.1" />
|
<PackageReference Include="MailKit" Version="4.15.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.5" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.5" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.5" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.3" />
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3856.49" />
|
<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="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.5" />
|
<PackageReference Include="System.IO.Hashing" Version="10.0.3" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="10.0.5" />
|
<PackageReference Include="System.IO.Ports" Version="10.0.3" />
|
||||||
<PackageReference Include="System.Management" Version="10.0.5" />
|
<PackageReference Include="System.Management" Version="10.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1180,104 +1180,5 @@ namespace Elwig.Services {
|
|||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(int Year, int DId, int DPNr)[]> GetDidsFromFilters(this DeliveryAdminViewModel vm) {
|
|
||||||
using var ctx = new AppDbContext();
|
|
||||||
var (_, _, parts, _, _) = await vm.GetFilters(ctx);
|
|
||||||
return [.. (await parts.Select(p => new { p.Year, p.DId, p.DPNr }).ToListAsync()).Select(p => (p.Year, p.DId, p.DPNr))];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task BulkSetAttribute(this DeliveryAdminViewModel vm, string? attributeName) {
|
|
||||||
try {
|
|
||||||
string attrid;
|
|
||||||
if (attributeName == null) {
|
|
||||||
attrid = "NULL";
|
|
||||||
} else {
|
|
||||||
using var ctx = new AppDbContext();
|
|
||||||
var attr = await ctx.WineAttributes.Where(a => a.Name == attributeName).SingleAsync();
|
|
||||||
attrid = $"'{attr.AttrId}'";
|
|
||||||
}
|
|
||||||
var dids = await vm.GetDidsFromFilters();
|
|
||||||
var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) das Attribut\n'{attributeName}' gesetz werden?",
|
|
||||||
"Massenaktion: Attribut setzen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
|
||||||
if (res != MessageBoxResult.OK) return;
|
|
||||||
|
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
|
||||||
await Task.Run(async () => {
|
|
||||||
using (var cnx = await AppDbContext.ConnectAsync()) {
|
|
||||||
await cnx.ExecuteBatch($"""
|
|
||||||
UPDATE delivery_part SET attrid = {attrid}
|
|
||||||
WHERE (year, did, dpnr) IN ({string.Join(", ", dids.Select(d => $"({d.Year},{d.DId},{d.DPNr})"))})
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
App.HintContextChange();
|
|
||||||
});
|
|
||||||
} catch (Exception exc) {
|
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
} finally {
|
|
||||||
Mouse.OverrideCursor = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task BulkAddModifier(this DeliveryAdminViewModel vm, string modifierName) {
|
|
||||||
try {
|
|
||||||
string modid;
|
|
||||||
using (var ctx = new AppDbContext()) {
|
|
||||||
var attr = await ctx.Modifiers.Where(a => a.Name == modifierName).FirstAsync();
|
|
||||||
modid = $"'{attr.ModId}'";
|
|
||||||
}
|
|
||||||
|
|
||||||
var dids = await vm.GetDidsFromFilters();
|
|
||||||
var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' hinzugefügt werden?",
|
|
||||||
"Massenaktion: Zu-/Abschlag hinzufügen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
|
||||||
if (res != MessageBoxResult.OK) return;
|
|
||||||
|
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
|
||||||
await Task.Run(async () => {
|
|
||||||
using (var cnx = await AppDbContext.ConnectAsync()) {
|
|
||||||
await cnx.ExecuteBatch($"""
|
|
||||||
INSERT INTO delivery_part_modifier (year, did, dpnr, modid)
|
|
||||||
VALUES {string.Join(", ", dids.Select(d => $"({d.Year},{d.DId},{d.DPNr},{modid})"))}
|
|
||||||
ON CONFLICT DO NOTHING
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
App.HintContextChange();
|
|
||||||
});
|
|
||||||
} catch (Exception exc) {
|
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
} finally {
|
|
||||||
Mouse.OverrideCursor = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task BulkRemoveModifier(this DeliveryAdminViewModel vm, string modifierName) {
|
|
||||||
try {
|
|
||||||
string modid;
|
|
||||||
using (var ctx = new AppDbContext()) {
|
|
||||||
var attr = await ctx.Modifiers.Where(a => a.Name == modifierName).FirstAsync();
|
|
||||||
modid = $"'{attr.ModId}'";
|
|
||||||
}
|
|
||||||
|
|
||||||
var dids = await vm.GetDidsFromFilters();
|
|
||||||
var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' entfernt werden?",
|
|
||||||
"Massenaktion: Zu-/Abschlag entfernen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
|
||||||
if (res != MessageBoxResult.OK) return;
|
|
||||||
|
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
|
||||||
await Task.Run(async () => {
|
|
||||||
using (var cnx = await AppDbContext.ConnectAsync()) {
|
|
||||||
await cnx.ExecuteBatch($"""
|
|
||||||
DELETE FROM delivery_part_modifier
|
|
||||||
WHERE (year, did, dpnr, modid) IN ({string.Join(", ", dids.Select(d => $"({d.Year},{d.DId},{d.DPNr},{modid})"))})
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
App.HintContextChange();
|
|
||||||
});
|
|
||||||
} catch (Exception exc) {
|
|
||||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
} finally {
|
|
||||||
Mouse.OverrideCursor = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
<Bold>Entwickler:</Bold> Lorenz Stechauner, Thomas Hilscher<LineBreak/>
|
<Bold>Entwickler:</Bold> Lorenz Stechauner, Thomas Hilscher<LineBreak/>
|
||||||
<Bold>Kontakt:</Bold> <Hyperlink NavigateUri="mailto:lorenz.stechauner@necronda.net" RequestNavigate="Hyperlink_RequestNavigate">lorenz.stechauner@necronda.net</Hyperlink>, <Hyperlink NavigateUri="mailto:thomas.hilscher@gmail.com" RequestNavigate="Hyperlink_RequestNavigate">thomas.hilscher@gmail.com</Hyperlink><LineBreak/>
|
<Bold>Kontakt:</Bold> <Hyperlink NavigateUri="mailto:lorenz.stechauner@necronda.net" RequestNavigate="Hyperlink_RequestNavigate">lorenz.stechauner@necronda.net</Hyperlink>, <Hyperlink NavigateUri="mailto:thomas.hilscher@gmail.com" RequestNavigate="Hyperlink_RequestNavigate">thomas.hilscher@gmail.com</Hyperlink><LineBreak/>
|
||||||
<Bold>Quellcode:</Bold> <Hyperlink NavigateUri="https://git.necronda.net/winzer/elwig" RequestNavigate="Hyperlink_RequestNavigate">https://git.necronda.net/winzer/elwig</Hyperlink><LineBreak/>
|
<Bold>Quellcode:</Bold> <Hyperlink NavigateUri="https://git.necronda.net/winzer/elwig" RequestNavigate="Hyperlink_RequestNavigate">https://git.necronda.net/winzer/elwig</Hyperlink><LineBreak/>
|
||||||
<Bold>Entwicklungszeitraum:</Bold> 2022–2026<LineBreak/>
|
<Bold>Entwicklungszeitraum:</Bold> 2022–2025<LineBreak/>
|
||||||
<LineBreak/>
|
<LineBreak/>
|
||||||
<Bold>Verwendete Technologien:</Bold><LineBreak/>
|
<Bold>Verwendete Technologien:</Bold><LineBreak/>
|
||||||
Programmiersprache: C#<LineBreak/>
|
Programmiersprache: C#<LineBreak/>
|
||||||
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
Framework: Windows Presentation Framework (WPF)<LineBreak/>
|
||||||
Datenbank: <Hyperlink NavigateUri="https://sqlite.org/" RequestNavigate="Hyperlink_RequestNavigate">SQLite</Hyperlink><LineBreak/>
|
Datenbank: <Hyperlink NavigateUri="https://sqlite.org/" RequestNavigate="Hyperlink_RequestNavigate">SQLite</Hyperlink><LineBreak/>
|
||||||
PDF-Erstellung: <Hyperlink NavigateUri="https://itextpdf.com/" RequestNavigate="Hyperlink_RequestNavigate">iText</Hyperlink>, <Hyperlink NavigateUri="https://github.com/bblanchon/pdfium-binaries" RequestNavigate="Hyperlink_RequestNavigate">Pdfium</Hyperlink><LineBreak/>
|
PDF-Erstellung: <Hyperlink NavigateUri="https://itextpdf.com/" RequestNavigate="Hyperlink_RequestNavigate">iText</Hyperlink>, <Hyperlink NavigateUri="https://github.com/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>
|
||||||
|
|
||||||
|
|||||||
@@ -287,7 +287,8 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
UnlockSearchInputs();
|
UnlockSearchInputs();
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
RefreshInputs();
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault());
|
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault());
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Elwig.Windows {
|
|||||||
set {
|
set {
|
||||||
_lockContext = value;
|
_lockContext = value;
|
||||||
if (!_lockContext && _renewPending) {
|
if (!_lockContext && _renewPending) {
|
||||||
Dispatcher.BeginInvoke(async () => await EnsureContextRenewed());
|
Dispatcher.BeginInvoke(async () => await RenewContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ namespace Elwig.Windows {
|
|||||||
public async Task HintContextChange() {
|
public async Task HintContextChange() {
|
||||||
_renewPending = true;
|
_renewPending = true;
|
||||||
if (LockContext) return;
|
if (LockContext) return;
|
||||||
await EnsureContextRenewed();
|
await RenewContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
|
protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
|
||||||
@@ -44,7 +44,7 @@ namespace Elwig.Windows {
|
|||||||
await OnRenewContext(ctx);
|
await OnRenewContext(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task EnsureContextRenewed() {
|
protected async Task RenewContext() {
|
||||||
if (!_renewPending) return;
|
if (!_renewPending) return;
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
await OnRenewContext(ctx);
|
await OnRenewContext(ctx);
|
||||||
|
|||||||
@@ -131,11 +131,7 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Liefermengen" x:Name="Menu_DeliveryDataList">
|
<MenuItem Header="Liefermengen" x:Name="Menu_DeliveryDataList">
|
||||||
<MenuItem x:Name="Menu_DeliveryDataList_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
<MenuItem x:Name="Menu_DeliveryDataList_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
||||||
Click="Menu_DeliveryDataList_SaveFilters_Click">
|
Click="Menu_DeliveryDataList_SaveFilters_Click"/>
|
||||||
<MenuItem.Icon>
|
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Statistik" x:Name="Menu_Statistics">
|
<MenuItem Header="Statistik" x:Name="Menu_Statistics">
|
||||||
<MenuItem Header="Qualitätsstatistik..." x:Name="Menu_Statistics_WineQuality">
|
<MenuItem Header="Qualitätsstatistik..." x:Name="Menu_Statistics_WineQuality">
|
||||||
@@ -166,11 +162,7 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="Menu_Statistics_Locality" Header="Lieferstatistik pro Ort...">
|
<MenuItem x:Name="Menu_Statistics_Locality" Header="Lieferstatistik pro Ort...">
|
||||||
<MenuItem x:Name="Menu_Statistic_Locality_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
<MenuItem x:Name="Menu_Statistic_Locality_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
||||||
Click="Menu_Statistic_Locality_SaveFilters_Click">
|
Click="Menu_Statistic_Locality_SaveFilters_Click"/>
|
||||||
<MenuItem.Icon>
|
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="BKI">
|
<MenuItem Header="BKI">
|
||||||
@@ -192,23 +184,6 @@
|
|||||||
<MenuItem x:Name="Menu_Export_UploadSeason" Header="...von Saison/Zweigstelle hochladen"
|
<MenuItem x:Name="Menu_Export_UploadSeason" Header="...von Saison/Zweigstelle hochladen"
|
||||||
Click="Menu_Export_UploadSeason_Click"/>
|
Click="Menu_Export_UploadSeason_Click"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Massenaktion">
|
|
||||||
<MenuItem x:Name="Menu_BulkAction_SetAttribute" Header="Attribut auf Lieferungen aus Filtern setzen...">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem x:Name="Menu_BulkAction_AddModifier" Header="Zu-/Abschlag auf Lieferungen aus Filtern hinzufügen...">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem x:Name="Menu_BulkAction_RemoveModifier" Header="Zu-/Abschlag auf Lieferungen aus Filtern entfernen...">
|
|
||||||
<MenuItem.Icon>
|
|
||||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
|
||||||
</MenuItem.Icon>
|
|
||||||
</MenuItem>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="Einstellungen">
|
<MenuItem Header="Einstellungen">
|
||||||
<MenuItem x:Name="Menu_Settings_EnableFreeEditing" Header="Freie Bearbeitung aktivieren"
|
<MenuItem x:Name="Menu_Settings_EnableFreeEditing" Header="Freie Bearbeitung aktivieren"
|
||||||
IsCheckable="True" Checked="Menu_Settings_EnableFreeEditing_Checked" Unchecked="Menu_Settings_EnableFreeEditing_Unchecked"/>
|
IsCheckable="True" Checked="Menu_Settings_EnableFreeEditing_Checked" Unchecked="Menu_Settings_EnableFreeEditing_Unchecked"/>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Elwig.Windows {
|
namespace Elwig.Windows {
|
||||||
@@ -284,21 +283,6 @@ namespace Elwig.Windows {
|
|||||||
private async void Menu_DeliveryDataList_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
|
private async void Menu_DeliveryDataList_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
|
||||||
await ViewModel.GenerateDeliveryDataList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
|
await ViewModel.GenerateDeliveryDataList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
|
||||||
|
|
||||||
private async void Menu_BulkAction_SetAttribute_Click(object sender, RoutedEventArgs evt) {
|
|
||||||
if (IsEditing || IsCreating || sender is not MenuItem item) return;
|
|
||||||
await ViewModel.BulkSetAttribute(item.Header as string);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void Menu_BulkAction_AddModifier_Click(object sender, RoutedEventArgs evt) {
|
|
||||||
if (IsEditing || IsCreating || sender is not MenuItem item || item.Header is not string name) return;
|
|
||||||
await ViewModel.BulkAddModifier(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void Menu_BulkAction_RemoveModifier_Click(object sender, RoutedEventArgs evt) {
|
|
||||||
if (IsEditing || IsCreating || sender is not MenuItem item || item.Header is not string name) return;
|
|
||||||
await ViewModel.BulkRemoveModifier(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) {
|
private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) {
|
||||||
if (IsEditing || IsCreating) {
|
if (IsEditing || IsCreating) {
|
||||||
DateInput.IsReadOnly = false;
|
DateInput.IsReadOnly = false;
|
||||||
@@ -484,10 +468,8 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||||
}
|
}
|
||||||
|
|
||||||
int year = 0;
|
|
||||||
Menu_Bki_SaveList.Items.Clear();
|
Menu_Bki_SaveList.Items.Clear();
|
||||||
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
|
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
|
||||||
if (s.Year > year) year = s.Year;
|
|
||||||
var i = new MenuItem {
|
var i = new MenuItem {
|
||||||
Header = $"Saison {s.Year}",
|
Header = $"Saison {s.Year}",
|
||||||
};
|
};
|
||||||
@@ -495,37 +477,6 @@ namespace Elwig.Windows {
|
|||||||
Menu_Bki_SaveList.Items.Add(i);
|
Menu_Bki_SaveList.Items.Add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
var font = new FontFamily("Segoe MDL2 Assets");
|
|
||||||
Menu_BulkAction_SetAttribute.Items.Clear();
|
|
||||||
var noAttr = new MenuItem {
|
|
||||||
Header = new TextBlock() { Text = "Kein Attribut", FontStyle = FontStyles.Italic },
|
|
||||||
Icon = new TextBlock() { Text = "\ue75c", FontFamily = font, FontSize = 16 },
|
|
||||||
};
|
|
||||||
noAttr.Click += Menu_BulkAction_SetAttribute_Click;
|
|
||||||
Menu_BulkAction_SetAttribute.Items.Add(noAttr);
|
|
||||||
foreach (var attr in await ctx.WineAttributes.OrderBy(a => a.AttrId).ToListAsync()) {
|
|
||||||
var i = new MenuItem {
|
|
||||||
Header = attr.Name,
|
|
||||||
};
|
|
||||||
i.Click += Menu_BulkAction_SetAttribute_Click;
|
|
||||||
Menu_BulkAction_SetAttribute.Items.Add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu_BulkAction_AddModifier.Items.Clear();
|
|
||||||
Menu_BulkAction_RemoveModifier.Items.Clear();
|
|
||||||
foreach (var mod in await ctx.Modifiers.Where(m => m.Year == year).OrderBy(m => m.ModId).ToListAsync()) {
|
|
||||||
var i1 = new MenuItem {
|
|
||||||
Header = mod.Name,
|
|
||||||
};
|
|
||||||
i1.Click += Menu_BulkAction_AddModifier_Click;
|
|
||||||
Menu_BulkAction_AddModifier.Items.Add(i1);
|
|
||||||
var i2 = new MenuItem {
|
|
||||||
Header = mod.Name,
|
|
||||||
};
|
|
||||||
i2.Click += Menu_BulkAction_RemoveModifier_Click;
|
|
||||||
Menu_BulkAction_RemoveModifier.Items.Add(i2);
|
|
||||||
}
|
|
||||||
|
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
var d = DeliveryList.SelectedItem as Delivery;
|
var d = DeliveryList.SelectedItem as Delivery;
|
||||||
var y = d?.Year ?? ViewModel.FilterSeason;
|
var y = d?.Year ?? ViewModel.FilterSeason;
|
||||||
@@ -812,11 +763,13 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmptyScale();
|
EmptyScale();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
await RefreshDeliveryParts();
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
ControlUtils.SelectItem(DeliveryList, p?.Delivery);
|
ControlUtils.SelectItem(DeliveryList, p?.Delivery);
|
||||||
DeliveryPartList.SelectedItem = null;
|
DeliveryPartList.SelectedItem = null;
|
||||||
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().Last());
|
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().Last());
|
||||||
|
RefreshInputs();
|
||||||
InitialInputs();
|
InitialInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,7 +802,8 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmptyScale();
|
EmptyScale();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
await RefreshDeliveryParts();
|
||||||
if (p?.Delivery != null) {
|
if (p?.Delivery != null) {
|
||||||
try {
|
try {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
@@ -867,7 +821,8 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
DeliveryList.SelectedItem = null;
|
DeliveryList.SelectedItem = null;
|
||||||
await EnsureContextRenewed();
|
await RenewContext();
|
||||||
|
RefreshInputs();
|
||||||
InitInputs();
|
InitInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,7 +853,7 @@ namespace Elwig.Windows {
|
|||||||
DisableWeighingButtons();
|
DisableWeighingButtons();
|
||||||
HideFinishNewPartDeliveryCancelButtons();
|
HideFinishNewPartDeliveryCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
await EnsureContextRenewed();
|
await RenewContext();
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
@@ -1078,7 +1033,9 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
UnlockSearchInputs();
|
UnlockSearchInputs();
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
await RefreshDeliveryParts();
|
||||||
|
RefreshInputs();
|
||||||
|
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
DepreciateButton.IsEnabled = true;
|
DepreciateButton.IsEnabled = true;
|
||||||
@@ -1178,9 +1135,6 @@ namespace Elwig.Windows {
|
|||||||
SeasonInput.IsEnabled = false;
|
SeasonInput.IsEnabled = false;
|
||||||
TodayOnlyInput.IsEnabled = false;
|
TodayOnlyInput.IsEnabled = false;
|
||||||
AllSeasonsInput.IsEnabled = false;
|
AllSeasonsInput.IsEnabled = false;
|
||||||
Menu_BulkAction_SetAttribute.IsEnabled = false;
|
|
||||||
Menu_BulkAction_AddModifier.IsEnabled = false;
|
|
||||||
Menu_BulkAction_RemoveModifier.IsEnabled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnlockSearchInputs() {
|
private void UnlockSearchInputs() {
|
||||||
@@ -1188,9 +1142,6 @@ namespace Elwig.Windows {
|
|||||||
SeasonInput.IsEnabled = true;
|
SeasonInput.IsEnabled = true;
|
||||||
TodayOnlyInput.IsEnabled = true;
|
TodayOnlyInput.IsEnabled = true;
|
||||||
AllSeasonsInput.IsEnabled = (ViewModel.FilterMember != null);
|
AllSeasonsInput.IsEnabled = (ViewModel.FilterMember != null);
|
||||||
Menu_BulkAction_SetAttribute.IsEnabled = true;
|
|
||||||
Menu_BulkAction_AddModifier.IsEnabled = true;
|
|
||||||
Menu_BulkAction_RemoveModifier.IsEnabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new protected void UnlockInputs() {
|
new protected void UnlockInputs() {
|
||||||
|
|||||||
@@ -374,7 +374,8 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
ViewModel.EnableSearchInputs = true;
|
ViewModel.EnableSearchInputs = true;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
RefreshInputs();
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
ControlUtils.SelectItemWithPk(DeliveryScheduleList, year, dsnr);
|
ControlUtils.SelectItemWithPk(DeliveryScheduleList, year, dsnr);
|
||||||
if (sortid != null)
|
if (sortid != null)
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
ViewModel.EnableSearchInputs = true;
|
ViewModel.EnableSearchInputs = true;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
RefreshInputs();
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -615,16 +615,12 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeDocs() {
|
private void DisposeDocs() {
|
||||||
try {
|
PrintDocument?.Dispose();
|
||||||
PrintDocument?.Dispose();
|
PrintDocument = null;
|
||||||
PrintDocument = null;
|
|
||||||
} catch { }
|
|
||||||
if (EmailDocuments != null) {
|
if (EmailDocuments != null) {
|
||||||
foreach (var (m, docs) in EmailDocuments) {
|
foreach (var (m, docs) in EmailDocuments) {
|
||||||
foreach (var d in docs) {
|
foreach (var d in docs) {
|
||||||
try {
|
d.Dispose();
|
||||||
d.Dispose();
|
|
||||||
} catch { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EmailDocuments = null;
|
EmailDocuments = null;
|
||||||
|
|||||||
@@ -436,7 +436,8 @@ namespace Elwig.Windows {
|
|||||||
UpdateContactInfoVisibility();
|
UpdateContactInfoVisibility();
|
||||||
ViewModel.EnableSearchInputs = true;
|
ViewModel.EnableSearchInputs = true;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await EnsureContextRenewed();
|
await RefreshList();
|
||||||
|
RefreshInputs();
|
||||||
ViewModel.SearchQuery = "";
|
ViewModel.SearchQuery = "";
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
if (mgnr is int m)
|
if (mgnr is int m)
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -13,17 +13,17 @@ About
|
|||||||
**Product:** Elwig
|
**Product:** Elwig
|
||||||
**Description:** Electronic Management for Vintners' Cooperatives
|
**Description:** Electronic Management for Vintners' Cooperatives
|
||||||
**Type:** ERP system
|
**Type:** ERP system
|
||||||
**Version:** 1.0.4.1 ([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
|
||||||
**Developement period:** 2022–2026
|
**Developement period:** 2022–2025
|
||||||
|
|
||||||
**Technology Stack:**
|
**Technology Stack:**
|
||||||
Language: C#
|
Language: C#
|
||||||
Framework: Windows Presentation Framework (WPF)
|
Framework: Windows Presentation Framework (WPF)
|
||||||
Database: [SQLite](https://sqlite.org/)
|
Database: [SQLite](https://sqlite.org/)
|
||||||
PDF creation: [iText](https://itextpdf.com/), [Pdfium](https://github.com/bblanchon/pdfium-binaries)
|
PDF creation: [WeasyPrint](https://weasyprint.org/), [RazorLight](https://github.com/toddams/RazorLight), [PdfiumViewer](https://github.com/pvginkel/PdfiumViewer)
|
||||||
Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||||
|
|
||||||
|
|
||||||
@@ -33,15 +33,15 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
|||||||
**Produkt:** Elwig
|
**Produkt:** Elwig
|
||||||
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
||||||
**Typ:** Warenwirtschaftssystem (ERP-System)
|
**Typ:** Warenwirtschaftssystem (ERP-System)
|
||||||
**Version:** 1.0.4.1 ([Ä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
|
||||||
**Entwicklungszeitraum:** 2022–2026
|
**Entwicklungszeitraum:** 2022–2025
|
||||||
|
|
||||||
**Verwendete Technologien:**
|
**Verwendete Technologien:**
|
||||||
Programmiersprache: C#
|
Programmiersprache: C#
|
||||||
Framework: Windows Presentation Framework (WPF)
|
Framework: Windows Presentation Framework (WPF)
|
||||||
Datenbank: [SQLite](https://sqlite.org/)
|
Datenbank: [SQLite](https://sqlite.org/)
|
||||||
PDF-Erstellung: [iText](https://itextpdf.com/), [Pdfium](https://github.com/bblanchon/pdfium-binaries)
|
PDF-Erstellung: [iText](https://itextpdf.com/), [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/)
|
||||||
|
|||||||
@@ -19,16 +19,16 @@
|
|||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.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.5.1" />
|
<PackageReference Include="NUnit" Version="4.5.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="6.1.0" />
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.12.0">
|
<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="8.0.1">
|
<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