Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abf06c558f | ||
|
|
6436762e8d |
No files matched your search
@@ -2,6 +2,30 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
[v1.1.2.2][v1.1.2.2] (2026-09-14) {#v1.1.2.2}
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
### Neue Funktionen {#v1.1.2.2-features}
|
||||||
|
|
||||||
|
* Bei einigen Fenstern werden in den Titeln nun die aktiven Filter der Suche angezeigt. (fea779bd95)
|
||||||
|
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) ist es nun möglich die Tara nachträglich zu korrigieren. (8ba051198f, 6436762e8d)
|
||||||
|
|
||||||
|
### Behobene Fehler {#v1.1.2.2-bugfixes}
|
||||||
|
|
||||||
|
* Bei Lieferscheinen (`DeliveryNote`) hat bei Anmerkungen zu Teil-Lfrg. ein `:` gefehlt.
|
||||||
|
Außerdem wurden Seitenumbrüche so platziert, dass sie nicht mehr innerhalb einer Teil-Lfrg. liegen. (e66780ccd0, f4cc443521)
|
||||||
|
|
||||||
|
### Sonstiges {#v1.1.2.2-misc}
|
||||||
|
|
||||||
|
* Bei Datenbank-Fehler sind die Fehlermeldungen nun genauer bzw. auf deutsch übersetzt. (cc01f92005)
|
||||||
|
* Im Mitglieder-Fenster (`MemberAdminWindow`) wurden Überschriften und Tooltips leicht angepasst. (6441fa4f50)
|
||||||
|
* Abhängigkeiten aktualisiert. (4cc33b56c8, 6bed370eba)
|
||||||
|
|
||||||
|
[v1.1.2.2]: https://git.necronda.net/winzer/elwig/releases/tag/v1.1.2.2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[v1.1.2.1][v1.1.2.1] (2026-08-27) {#v1.1.2.1}
|
[v1.1.2.1][v1.1.2.1] (2026-08-27) {#v1.1.2.1}
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace Elwig.Documents {
|
|||||||
.SetBorder(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
.SetBorder(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
||||||
.AddCell(NewAsideCell("Mitglied", 2))
|
.AddCell(NewAsideCell("Mitglied", 2))
|
||||||
.AddCell(NewAsideCell("Mitglieds-Nr.:", isName: true)).AddCell(NewAsideCell($"{Member.MgNr}"))
|
.AddCell(NewAsideCell("Mitglieds-Nr.:", isName: true)).AddCell(NewAsideCell($"{Member.MgNr}"))
|
||||||
.AddCell(NewAsideCell("Betriebs-Nr.:", isName: true)).AddCell(NewAsideCell((Member.LfbisNr ?? "-") + (Member.OrganicAuthorityCode != null ? $" ({Member.OrganicAuthorityCode})" : "")))
|
.AddCell(NewAsideCell("Betriebs-Nr.:", isName: true)).AddCell(NewAsideCell(Member.LfbisNr ?? ""))
|
||||||
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
||||||
.Add(Normal($"({(Member.IsBuchführend ? season.VatNormal : season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
.Add(Normal($"({(Member.IsBuchführend ? season.VatNormal : season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
||||||
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
||||||
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd((Member.IsOrganic ? "Ja" : "Nein") + (Member.OrganicAuthorityCode != null ? $" ({Member.OrganicAuthorityCode})" : ""), colspan: 2))
|
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(Member.IsOrganic ? "Ja" : "Nein", colspan: 2))
|
||||||
.AddCell(NewDataHdr("Genossenschaft", colspan: 6))
|
.AddCell(NewDataHdr("Genossenschaft", colspan: 6))
|
||||||
.AddCell(NewDataTh("Status:")).AddCell(NewTd(new KernedParagraph(Member.IsActive ? "Aktiv " : "Nicht aktiv ", 10)
|
.AddCell(NewDataTh("Status:")).AddCell(NewTd(new KernedParagraph(Member.IsActive ? "Aktiv " : "Nicht aktiv ", 10)
|
||||||
.Add(Normal("(" + (Member.ExitDate != null ? $"{Member.EntryDate:dd.MM.yyyy}\u2013{Member.ExitDate:dd.MM.yyyy}" : $"seit {Member.EntryDate:dd.MM.yyyy}") + ")", 8))))
|
.Add(Normal("(" + (Member.ExitDate != null ? $"{Member.EntryDate:dd.MM.yyyy}\u2013{Member.ExitDate:dd.MM.yyyy}" : $"seit {Member.EntryDate:dd.MM.yyyy}") + ")", 8))))
|
||||||
|
|||||||
+1
-1
@@ -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.1.2.1</Version>
|
<Version>1.1.2.2</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<ApplicationManifest>App.manifest</ApplicationManifest>
|
<ApplicationManifest>App.manifest</ApplicationManifest>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -10,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 = 42;
|
public static readonly int RequiredSchemaVersion = 41;
|
||||||
|
|
||||||
private static int VersionOffset = 0;
|
private static int VersionOffset = 0;
|
||||||
|
|
||||||
@@ -69,11 +68,11 @@ namespace Elwig.Helpers {
|
|||||||
})
|
})
|
||||||
.OrderBy(s => s.Item1).ThenBy(s => s.Item2)];
|
.OrderBy(s => s.Item1).ThenBy(s => s.Item2)];
|
||||||
|
|
||||||
List<(int ToVersion, string File)> toExecute = [];
|
List<string> toExecute = [];
|
||||||
var vers = fromVersion;
|
var vers = fromVersion;
|
||||||
while (vers < toVersion) {
|
while (vers < toVersion) {
|
||||||
var (_, to, name) = scripts.Last(s => s.From == vers);
|
var (_, to, name) = scripts.Last(s => s.From == vers);
|
||||||
toExecute.Add((to, name));
|
toExecute.Add(name);
|
||||||
vers = to;
|
vers = to;
|
||||||
}
|
}
|
||||||
if (toExecute.Count == 0)
|
if (toExecute.Count == 0)
|
||||||
@@ -88,11 +87,8 @@ namespace Elwig.Helpers {
|
|||||||
await cnx.IntegrityCheck();
|
await cnx.IntegrityCheck();
|
||||||
await cnx.ForeignKeyCheck();
|
await cnx.ForeignKeyCheck();
|
||||||
|
|
||||||
foreach (var (to, script) in toExecute) {
|
foreach (var script in toExecute) {
|
||||||
await cnx.ExecuteEmbeddedScript(asm, script);
|
await cnx.ExecuteEmbeddedScript(asm, script);
|
||||||
if (to == 42) {
|
|
||||||
await UpdateDbSchema_41_To_42(cnx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await cnx.IntegrityCheck();
|
await cnx.IntegrityCheck();
|
||||||
@@ -107,36 +103,5 @@ namespace Elwig.Helpers {
|
|||||||
File.Delete(backup);
|
File.Delete(backup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task UpdateDbSchema_41_To_42(SqliteConnection cnx) {
|
|
||||||
List<(int MgNr, int LfbisNr, string Name, string Address, int Plz, string Locality)> members = [];
|
|
||||||
using (var cmd = cnx.CreateCommand()) {
|
|
||||||
// TODO
|
|
||||||
cmd.CommandText = """
|
|
||||||
SELECT m.mgnr, m.lfbis_nr, '', 0, ''
|
|
||||||
FROM member m
|
|
||||||
LEFT JOIN member_billing_address a ON a.mgnr = m.mgnr
|
|
||||||
WHERE organic
|
|
||||||
""";
|
|
||||||
using var reader = await cmd.ExecuteReaderAsync();
|
|
||||||
var header = await reader.GetColumnSchemaAsync();
|
|
||||||
while (await reader.ReadAsync()) {
|
|
||||||
members.Add((reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2), reader.GetString(3), reader.GetInt32(4), reader.GetString(5));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var m in members) {
|
|
||||||
string? oocId = null;
|
|
||||||
string? authCode = null;
|
|
||||||
|
|
||||||
// TODO fetch traces certs
|
|
||||||
|
|
||||||
if (oocId != null || authCode != null) {
|
|
||||||
oocId = oocId == null ? "NULL" : $"'{oocId}'";
|
|
||||||
authCode = authCode == null ? "NULL" : $"'{authCode}'";
|
|
||||||
await cnx.ExecuteBatch($"UPDATE member SET ooc_id = {oocId}, org_auth_code = {authCode} WHERE mgnr = {m.MgNr}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -638,8 +638,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
["zwstid"] = m.ZwstId,
|
["zwstid"] = m.ZwstId,
|
||||||
["lfbis_nr"] = m.LfbisNr,
|
["lfbis_nr"] = m.LfbisNr,
|
||||||
["ustid_nr"] = m.UstIdNr,
|
["ustid_nr"] = m.UstIdNr,
|
||||||
["ooc_id"] = m.OrganicOperatorId,
|
|
||||||
["org_auth_code"] = m.OrganicAuthorityCode,
|
|
||||||
["juridical_pers"] = m.IsJuridicalPerson,
|
["juridical_pers"] = m.IsJuridicalPerson,
|
||||||
["volllieferant"] = m.IsVollLieferant,
|
["volllieferant"] = m.IsVollLieferant,
|
||||||
["buchführend"] = m.IsBuchführend,
|
["buchführend"] = m.IsBuchführend,
|
||||||
@@ -712,8 +710,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
ZwstId = json["zwstid"]?.AsValue().GetValue<string>(),
|
ZwstId = json["zwstid"]?.AsValue().GetValue<string>(),
|
||||||
LfbisNr = json["lfbis_nr"]?.AsValue().GetValue<string>(),
|
LfbisNr = json["lfbis_nr"]?.AsValue().GetValue<string>(),
|
||||||
UstIdNr = json["ustid_nr"]?.AsValue().GetValue<string>(),
|
UstIdNr = json["ustid_nr"]?.AsValue().GetValue<string>(),
|
||||||
OrganicOperatorId = json["ooc_id"]?.AsValue().GetValue<string>(),
|
|
||||||
OrganicAuthorityCode = json["org_auth_code"]?.AsValue().GetValue<string>(),
|
|
||||||
IsJuridicalPerson = json["juridical_pers"]?.AsValue().GetValue<bool>() ?? false,
|
IsJuridicalPerson = json["juridical_pers"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsVollLieferant = json["volllieferant"]?.AsValue().GetValue<bool>() ?? false,
|
IsVollLieferant = json["volllieferant"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsBuchführend = json["buchführend"]?.AsValue().GetValue<bool>() ?? false,
|
IsBuchführend = json["buchführend"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
|
|||||||
@@ -631,18 +631,15 @@ namespace Elwig.Helpers {
|
|||||||
if (v < 2 && char.IsAsciiLetter(ch)) {
|
if (v < 2 && char.IsAsciiLetter(ch)) {
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
} else if ((v == 2 || v == 5) && ch == '-' && text[^1] != '-') {
|
} else if ((v == 2 || v == 6) && ch == '-') {
|
||||||
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
} else if (v >= 2 && v <= 4 && char.IsLetter(ch)) {
|
} else if (v >= 2 && char.IsLetterOrDigit(ch)) {
|
||||||
if (v == 2 && text[^1] != '-')
|
|
||||||
text += "-";
|
|
||||||
if (text.StartsWith("AT")) {
|
if (text.StartsWith("AT")) {
|
||||||
if (v == 2 && ch == 'B' || v == 3 && ch == 'I' || v == 4 && ch == 'O') {
|
if (v == 3 && ch == 'B' || v == 4 && ch == 'I' || v == 5 && ch == 'O') {
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
}
|
} else if (v > 6 && char.IsAsciiDigit(ch)) {
|
||||||
} else if (text.StartsWith("DE")) {
|
|
||||||
if (v == 2 && ch == 'Ö' || v == 3 && ch == 'K' || v == 4 && ch == 'O') {
|
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
}
|
}
|
||||||
@@ -650,16 +647,11 @@ namespace Elwig.Helpers {
|
|||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
}
|
}
|
||||||
} else if (v >= 5 && v <= 7 && char.IsAsciiDigit(ch)) {
|
|
||||||
if (v == 5 && text[^1] != '-')
|
|
||||||
text += "-";
|
|
||||||
v++;
|
|
||||||
text += ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == input.CaretIndex - 1) {
|
if (i == input.CaretIndex - 1) {
|
||||||
pos = text.Length;
|
pos = text.Length;
|
||||||
} else if ((text.StartsWith("AT") || text.StartsWith("DE")) && v >= 10) {
|
} else if (text.StartsWith("AT") && v >= 10) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -670,7 +662,7 @@ namespace Elwig.Helpers {
|
|||||||
if (text.Length == 0)
|
if (text.Length == 0)
|
||||||
return required ? new(false, "Bio-Kontrollstellen-Code ist nicht optional") : new(true, null);
|
return required ? new(false, "Bio-Kontrollstellen-Code ist nicht optional") : new(true, null);
|
||||||
|
|
||||||
if (text.StartsWith("AT") || text.StartsWith("DE")) {
|
if (text.StartsWith("AT")) {
|
||||||
if (text.Length != 10) {
|
if (text.Length != 10) {
|
||||||
return new(false, "Bio-Kontrollstellen-Code ist ungültig");
|
return new(false, "Bio-Kontrollstellen-Code ist ungültig");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,12 +96,6 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("ustid_nr")]
|
[Column("ustid_nr")]
|
||||||
public string? UstIdNr { get; set; }
|
public string? UstIdNr { get; set; }
|
||||||
|
|
||||||
[Column("ooc_id")]
|
|
||||||
public string? OrganicOperatorId { get; set; }
|
|
||||||
|
|
||||||
[Column("org_auth_code")]
|
|
||||||
public string? OrganicAuthorityCode { get; set; }
|
|
||||||
|
|
||||||
[Column("juridical_pers")]
|
[Column("juridical_pers")]
|
||||||
public bool IsJuridicalPerson { get; set; }
|
public bool IsJuridicalPerson { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
-- schema version 41 to 42
|
|
||||||
|
|
||||||
ALTER TABLE member ADD COLUMN ooc_id TEXT CHECK (ooc_id REGEXP '^[0-9]{3}-[0-9]{7}$') DEFAULT NULL;
|
|
||||||
ALTER TABLE member ADD COLUMN org_auth_code TEXT CHECK (org_auth_code REGEXP '^[A-Z]{2}-[A-ZÖØ]{3}-[0-9]{2,3}(-[A-Z]{2})?$') DEFAULT NULL;
|
|
||||||
@@ -60,7 +60,7 @@ namespace Elwig.Services {
|
|||||||
vm.Weight = p.Weight;
|
vm.Weight = p.Weight;
|
||||||
vm.ActualTare = p.WeighingInfo.Tare ?? 0;
|
vm.ActualTare = p.WeighingInfo.Tare ?? 0;
|
||||||
vm.TargetTare = vm.ActualTare + p.WeighingInfo.TareCorrection;
|
vm.TargetTare = vm.ActualTare + p.WeighingInfo.TareCorrection;
|
||||||
vm.Tare = vm.ActualTare != 0 ? vm.TargetTare ?? vm.ActualTare : null;
|
vm.Tare = vm.TargetTare ?? (vm.ActualTare != 0 ? vm.ActualTare : null);
|
||||||
vm.IsManualWeighing = p.IsManualWeighing;
|
vm.IsManualWeighing = p.IsManualWeighing;
|
||||||
vm.IsNetWeight = p.IsNetWeight;
|
vm.IsNetWeight = p.IsNetWeight;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace Elwig.Services {
|
namespace Elwig.Services {
|
||||||
public static class MemberService {
|
public static class MemberService {
|
||||||
@@ -107,7 +106,6 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
vm.UstIdNr = m.UstIdNr;
|
vm.UstIdNr = m.UstIdNr;
|
||||||
vm.LfbisNr = m.LfbisNr;
|
vm.LfbisNr = m.LfbisNr;
|
||||||
vm.OrganicAuthorityCode = m.OrganicAuthorityCode;
|
|
||||||
vm.IsBuchführend = m.IsBuchführend;
|
vm.IsBuchführend = m.IsBuchführend;
|
||||||
vm.IsOrganic = m.IsOrganic;
|
vm.IsOrganic = m.IsOrganic;
|
||||||
|
|
||||||
@@ -189,9 +187,10 @@ namespace Elwig.Services {
|
|||||||
.GroupBy(d => d.Year)
|
.GroupBy(d => d.Year)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.Any());
|
.ToDictionaryAsync(g => g.Key, g => g.Any());
|
||||||
|
|
||||||
|
if (m.MgNr != vm.MgNr)
|
||||||
|
return;
|
||||||
|
|
||||||
await App.MainDispatcher.BeginInvoke(() => {
|
await App.MainDispatcher.BeginInvoke(() => {
|
||||||
if (m.MgNr != vm.MgNr)
|
|
||||||
return;
|
|
||||||
var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []);
|
var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []);
|
||||||
var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []);
|
var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []);
|
||||||
var grid = AreaComService.GenerateToolTip(gridData);
|
var grid = AreaComService.GenerateToolTip(gridData);
|
||||||
@@ -208,58 +207,6 @@ namespace Elwig.Services {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.OrganicTest1 = null;
|
|
||||||
vm.OrganicTest2 = "...";
|
|
||||||
vm.OrganicTest3 = Brushes.Black;
|
|
||||||
vm.OrganicTest4 = null;
|
|
||||||
Utils.RunBackground("Bio-Zertifikatsdaten laden", async () => {
|
|
||||||
if (App.MainDispatcher == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var certs = await OrganicService.FetchTracesCertificatesOfMember(m);
|
|
||||||
|
|
||||||
// TODO button for TRACES search url
|
|
||||||
// TODO button for authority search url
|
|
||||||
|
|
||||||
await App.MainDispatcher.BeginInvoke(() => {
|
|
||||||
if (m.MgNr != vm.MgNr)
|
|
||||||
return;
|
|
||||||
vm.OrganicTest2 = null;
|
|
||||||
if (certs.Length == 0) {
|
|
||||||
vm.OrganicTest1 = "Nicht gefunden";
|
|
||||||
vm.OrganicTest3 = Brushes.DarkRed;
|
|
||||||
} else {
|
|
||||||
var cert = certs[0];
|
|
||||||
vm.OrganicTest4 = $"Zertifikat-Nr.: {cert.Id}\nBio-KSt.: {cert.AuthorityCode}\nEU Operator-ID: {cert.OperatorId}\nOperator: {cert.OperatorName}";
|
|
||||||
if (cert.IsValidForWineProduction) {
|
|
||||||
vm.OrganicTest1 = "Gültig";
|
|
||||||
vm.OrganicTest2 = $" (bis {cert.ExpiresOn:dd.MM.yyyy})";
|
|
||||||
vm.OrganicTest3 = Brushes.DarkGreen;
|
|
||||||
} else if (cert.IsValid) {
|
|
||||||
vm.OrganicTest1 = "Teilw. gültig";
|
|
||||||
vm.OrganicTest2 = $" (bis {cert.ExpiresOn:dd.MM.yyyy})";
|
|
||||||
vm.OrganicTest3 = Brushes.OrangeRed;
|
|
||||||
} else {
|
|
||||||
vm.OrganicTest3 = Brushes.DarkRed;
|
|
||||||
switch (cert.Status) {
|
|
||||||
case OrganicService.TracesStatus.ISSUED:
|
|
||||||
vm.OrganicTest1 = "Ausgestellt";
|
|
||||||
vm.OrganicTest2 = $" (am {cert.LastStatusUpdateOn:dd.MM.yyyy})"; break;
|
|
||||||
case OrganicService.TracesStatus.SUSPENDED:
|
|
||||||
vm.OrganicTest1 = "Gesperrt";
|
|
||||||
vm.OrganicTest2 = $" (am {cert.LastStatusUpdateOn:dd.MM.yyyy})"; break;
|
|
||||||
case OrganicService.TracesStatus.EXPIRED:
|
|
||||||
vm.OrganicTest1 = "Ausgelaufen";
|
|
||||||
vm.OrganicTest2 = $" (am {cert.LastStatusUpdateOn:dd.MM.yyyy})"; break;
|
|
||||||
case OrganicService.TracesStatus.WITHDRAWN:
|
|
||||||
vm.OrganicTest1 = "Widerrufen";
|
|
||||||
vm.OrganicTest2 = $" (am {cert.LastStatusUpdateOn:dd.MM.yyyy})"; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
vm.MemberHasEmail = m.EmailAddresses.Count > 0;
|
vm.MemberHasEmail = m.EmailAddresses.Count > 0;
|
||||||
vm.MemberCanSendEmail = App.Config.Smtp != null && m.EmailAddresses.Count > 0;
|
vm.MemberCanSendEmail = App.Config.Smtp != null && m.EmailAddresses.Count > 0;
|
||||||
vm.MemberHasDeliveries = Enumerable.Range(0, 9999).Select(i => false).ToList();
|
vm.MemberHasDeliveries = Enumerable.Range(0, 9999).Select(i => false).ToList();
|
||||||
@@ -608,7 +555,6 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
UstIdNr = string.IsNullOrWhiteSpace(vm.UstIdNr) ? null : vm.UstIdNr,
|
UstIdNr = string.IsNullOrWhiteSpace(vm.UstIdNr) ? null : vm.UstIdNr,
|
||||||
LfbisNr = string.IsNullOrWhiteSpace(vm.LfbisNr) ? null : vm.LfbisNr,
|
LfbisNr = string.IsNullOrWhiteSpace(vm.LfbisNr) ? null : vm.LfbisNr,
|
||||||
OrganicAuthorityCode = string.IsNullOrWhiteSpace(vm.OrganicAuthorityCode) ? null : vm.OrganicAuthorityCode,
|
|
||||||
IsBuchführend = vm.IsBuchführend,
|
IsBuchführend = vm.IsBuchführend,
|
||||||
IsOrganic = vm.IsOrganic,
|
IsOrganic = vm.IsOrganic,
|
||||||
|
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
using Elwig.Helpers;
|
|
||||||
using Elwig.Models.Entities;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Web;
|
|
||||||
|
|
||||||
namespace Elwig.Services {
|
|
||||||
public static class OrganicService {
|
|
||||||
|
|
||||||
public const string TRACES_API_URL = "https://webgate.ec.europa.eu/tracesnt/directory/publication/organic-operator/for/query";
|
|
||||||
public const string TRACES_PDF_URL_PREFIX = "https://webgate.ec.europa.eu/tracesnt/directory/publication/organic-operator/digitally-signed/";
|
|
||||||
|
|
||||||
public enum TracesStatus {
|
|
||||||
ISSUED, SUSPENDED, WITHDRAWN, EXPIRED
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TracesActivity {
|
|
||||||
PREPARATION, EXPORT, IMPORT, STORING, PRODUCTION, DISTRIBUTION, DISTRIBUTION_PLACING_ON_THE_MARKET
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TracesCategoryOfProduct {
|
|
||||||
UNPROCESSED_PLANT_PRODUCTS_INCLUDING_SEEDS, LIVESTOCK_AND_UNPROCESSED_LIVESTOCK_PRODUCTS, ALGAE_AND_UNPROCESSED_AQUACULTURE_PRODUCTS,
|
|
||||||
PROCESSED_AGRICULTURAL_PRODUCTS_INCLUDING_AQUACULTURE_FOR_USE_AS_FOOD, FEED, WINE, OTHER_PRODUCTS_NOT_COVERED_BY_PREVIOUS_CATEGORIES
|
|
||||||
}
|
|
||||||
|
|
||||||
public record TracesCertificate {
|
|
||||||
public required string Id { get; init; }
|
|
||||||
public required string AuthorityCode { get; init; }
|
|
||||||
public required string OperatorId { get; init; }
|
|
||||||
public required string OperatorName { get; init; }
|
|
||||||
public required TracesActivity[] Activities { get; init; }
|
|
||||||
public required TracesCategoryOfProduct[] CategoriesOfProduct { get; init; }
|
|
||||||
public required DateOnly IssuedOn { get; init; }
|
|
||||||
public required DateOnly ExpiresOn { get; init; }
|
|
||||||
public required DateOnly LastStatusUpdateOn { get; init; }
|
|
||||||
public required TracesStatus Status { get; init; }
|
|
||||||
|
|
||||||
public string PdfUrl => TRACES_PDF_URL_PREFIX + Id + ".pdf";
|
|
||||||
public bool IsValid => Status == TracesStatus.ISSUED && IssuedOn.ToDateTime(new()) <= DateTime.Today && ExpiresOn.ToDateTime(new()) >= DateTime.Today;
|
|
||||||
public bool IsValidForWineProduction => IsValid && Activities.Contains(TracesActivity.PRODUCTION) &&
|
|
||||||
(CategoriesOfProduct.Contains(TracesCategoryOfProduct.UNPROCESSED_PLANT_PRODUCTS_INCLUDING_SEEDS) || CategoriesOfProduct.Contains(TracesCategoryOfProduct.WINE));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async static Task<JsonArray> TryFetchTracesCertificates(Dictionary<string, string> query) {
|
|
||||||
var q = HttpUtility.ParseQueryString("");
|
|
||||||
q.Add("sort", "-issuedOn");
|
|
||||||
q.Add("countryCode", "AT");
|
|
||||||
foreach (var (k, v) in query) {
|
|
||||||
q.Add(k, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
using var client = Utils.GetHttpClient();
|
|
||||||
using var res = await client.GetAsync($"{TRACES_API_URL}?{q}");
|
|
||||||
res.EnsureSuccessStatusCode();
|
|
||||||
var resJson = JsonNode.Parse(await res.Content.ReadAsStringAsync());
|
|
||||||
var certs = resJson?.AsArray() ?? throw new Exception();
|
|
||||||
if (certs.Count == 0)
|
|
||||||
throw new Exception();
|
|
||||||
return certs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async static Task<TracesCertificate[]> FetchTracesCertificatesOfMember(Member m, bool? tryNameAndAddress = null) {
|
|
||||||
bool searchedByName = false;
|
|
||||||
|
|
||||||
JsonArray? jsonCerts = null;
|
|
||||||
if (m.OrganicOperatorId != null) {
|
|
||||||
try {
|
|
||||||
jsonCerts = await TryFetchTracesCertificates(new Dictionary<string, string> {
|
|
||||||
{ "operatorIdentifierType", "ooc_identifier" },
|
|
||||||
{ "operatorIdentifierSearchOperator", "STRICT" },
|
|
||||||
{ "operatorIdentifier", m.OrganicOperatorId },
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
jsonCerts = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsonCerts == null && m.LfbisNr != null) {
|
|
||||||
try {
|
|
||||||
jsonCerts = await TryFetchTracesCertificates(new Dictionary<string, string> {
|
|
||||||
{ "operatorIdentifierType", "comp_reg" },
|
|
||||||
{ "operatorIdentifierSearchOperator", "STRICT" },
|
|
||||||
{ "operatorIdentifier", m.LfbisNr.TrimStart('0') },
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
jsonCerts = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsonCerts == null && (tryNameAndAddress ?? m.IsOrganic)) {
|
|
||||||
try {
|
|
||||||
jsonCerts = await TryFetchTracesCertificates(new Dictionary<string, string> {
|
|
||||||
{ "operatorPostalCode", $"{(m.BillingAddress?.PostalDest ?? m.PostalDest).AtPlz?.Plz}" },
|
|
||||||
{ "query", m.BillingAddress is BillingAddr a ? $"{a.FullName} {a.Address}" : $"{m.FullName} {m.Address}" },
|
|
||||||
});
|
|
||||||
searchedByName = true;
|
|
||||||
} catch {
|
|
||||||
jsonCerts = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsonCerts == null)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
TracesCertificate[] certs = [];
|
|
||||||
try {
|
|
||||||
certs = [.. jsonCerts.Select(j => new TracesCertificate {
|
|
||||||
Id = j!["reference"]?.GetValue<string>() ?? throw new Exception(),
|
|
||||||
AuthorityCode = j["issuingBody"]?["code"]?.GetValue<string>() ?? throw new Exception(),
|
|
||||||
OperatorId = j["operatorIdentifier"]?.GetValue<string>() ?? throw new Exception(),
|
|
||||||
OperatorName = j["operator"]?["name"]?.GetValue<string>() ?? throw new Exception(),
|
|
||||||
Activities = [.. j["activities"]?.AsArray().Select(a => Enum.Parse<TracesActivity>(a?["id"]?.GetValue<string>().ToUpper().Replace("_IMPORT", "IMPORT") ?? throw new Exception())) ?? []],
|
|
||||||
CategoriesOfProduct = [.. j["categoriesOfProduct"]?.AsArray().Select(c => Enum.Parse<TracesCategoryOfProduct>(c?["id"]?.GetValue<string>() ?? throw new Exception())) ?? []],
|
|
||||||
IssuedOn = DateOnly.FromDateTime(DateTime.ParseExact(j["issuedOn"]?.GetValue<string>() ?? throw new Exception(), "yyyy-MM-ddTHH:mm:ss.fffK", CultureInfo.InvariantCulture, DateTimeStyles.None)),
|
|
||||||
ExpiresOn = DateOnly.ParseExact(j["expiresOn"]?.GetValue<string>() ?? throw new Exception(), "yyyy-MM-dd"),
|
|
||||||
LastStatusUpdateOn = DateOnly.FromDateTime(DateTime.ParseExact(j["lastStatusUpdateDateTime"]?.GetValue<string>() ?? throw new Exception(), "yyyy-MM-ddTHH:mm:ss.fffK", CultureInfo.InvariantCulture, DateTimeStyles.None)),
|
|
||||||
Status = Enum.Parse<TracesStatus>(j["status"]?["id"]?.GetValue<string>() ?? throw new Exception()),
|
|
||||||
})];
|
|
||||||
} catch {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return (!searchedByName || certs.Where(c => c.Status == TracesStatus.ISSUED).Select(c => c.OperatorId).ToHashSet().Count == 1) ? certs : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace Elwig.ViewModels {
|
namespace Elwig.ViewModels {
|
||||||
public partial class MemberAdminViewModel : ObservableObject {
|
public partial class MemberAdminViewModel : ObservableObject {
|
||||||
@@ -119,21 +118,10 @@ namespace Elwig.ViewModels {
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _lfbisNr;
|
private string? _lfbisNr;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _organicAuthorityCode;
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isBuchführend;
|
private bool _isBuchführend;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isOrganic;
|
private bool _isOrganic;
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _organicTest1;
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _organicTest2;
|
|
||||||
[ObservableProperty]
|
|
||||||
private Brush? _organicTest3;
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _organicTest4;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _entryDate;
|
private string? _entryDate;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
|||||||
@@ -614,7 +614,7 @@ namespace Elwig.Windows {
|
|||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
ViewModel.FillInputs(p);
|
ViewModel.FillInputs(p);
|
||||||
CorrectTareButton.Visibility = !ViewModel.IsReceipt && p.WeighingInfo.Tare != null && p.WeighingInfo.Tare != 0 ? Visibility.Visible : Visibility.Hidden;
|
CorrectTareButton.Visibility = !ViewModel.IsReceipt && (ViewModel.ActualTare != 0 || ViewModel.IsUnloadingBox) ? Visibility.Visible : Visibility.Hidden;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1409,6 +1409,8 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private void UnloadingInput_Checked(object sender, RoutedEventArgs evt) {
|
private void UnloadingInput_Checked(object sender, RoutedEventArgs evt) {
|
||||||
if (!IsEditing && !IsCreating) return;
|
if (!IsEditing && !IsCreating) return;
|
||||||
|
if (!ViewModel.IsReceipt)
|
||||||
|
CorrectTareButton.Visibility = ViewModel.ActualTare != 0 || ViewModel.IsUnloadingBox ? Visibility.Visible : Visibility.Hidden;
|
||||||
var mod = ViewModel.Modifiers.ToList();
|
var mod = ViewModel.Modifiers.ToList();
|
||||||
var source = ViewModel.ModifiersSource.ToList();
|
var source = ViewModel.ModifiersSource.ToList();
|
||||||
if (App.Client.IsMatzen) {
|
if (App.Client.IsMatzen) {
|
||||||
|
|||||||
@@ -548,41 +548,36 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="90"/>
|
<ColumnDefinition Width="90"/>
|
||||||
<ColumnDefinition Width="110"/>
|
<ColumnDefinition Width="150"/>
|
||||||
<ColumnDefinition/>
|
<ColumnDefinition/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Label Content="UID:" Margin="10,10,0,0" Grid.Column="0" ToolTip="USt-IdNr. / Umsatzsteuer-Identifikationsnummer"/>
|
<Label Content="UID:" Margin="10,10,0,0" Grid.Column="0" ToolTip="USt-IdNr. / Umsatzsteuer-Identifikationsnummer"/>
|
||||||
<TextBox x:Name="UstIdNrInput" Text="{Binding UstIdNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<TextBox x:Name="UstIdNrInput" Text="{Binding UstIdNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Margin="0,10,10,0" Grid.Column="1" Width="96" HorizontalAlignment="Left"
|
Margin="0,10,10,0" Grid.Column="1" Width="96" HorizontalAlignment="Left"
|
||||||
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
|
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
|
||||||
<CheckBox x:Name="BuchführendInput" Content="Buchführend" IsChecked="{Binding IsBuchführend, Mode=TwoWay}" IsEnabled="False"
|
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
|
||||||
Grid.Column="2" HorizontalAlignment="Left" Margin="10,15,0,0" VerticalAlignment="Top"/>
|
|
||||||
|
|
||||||
<Label Content="Betriebs-Nr.:" Margin="10,40,0,0" Grid.Column="0"/>
|
<Label Content="Betriebs-Nr.:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||||
<TextBox x:Name="LfbisNrInput" Text="{Binding LfbisNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
<TextBox x:Name="LfbisNrInput" Text="{Binding LfbisNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
Margin="0,40,10,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right"
|
Margin="0,40,10,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right"
|
||||||
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
|
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
|
||||||
|
|
||||||
|
<CheckBox x:Name="BuchführendInput" Content="Buchführend" IsChecked="{Binding IsBuchführend, Mode=TwoWay}" IsEnabled="False"
|
||||||
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||||
|
Grid.Column="2" HorizontalAlignment="Left" Margin="10,15,0,0" VerticalAlignment="Top"/>
|
||||||
|
|
||||||
<CheckBox x:Name="OrganicInput" Content="Bio" IsChecked="{Binding IsOrganic, Mode=TwoWay}" IsEnabled="False"
|
<CheckBox x:Name="OrganicInput" Content="Bio" IsChecked="{Binding IsOrganic, Mode=TwoWay}" IsEnabled="False"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||||
Grid.Column="2" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top"/>
|
Grid.Column="2" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top"/>
|
||||||
<Label Content="Bio-Zert.:" Margin="10,10,150,0" Grid.Column="2" HorizontalAlignment="Right"/>
|
<Button x:Name="OrganicButton" Content="easy-cert.com" IsEnabled="{Binding IsMemberSelected}"
|
||||||
<TextBlock FontSize="14" Margin="10,12,10,0" Grid.Column="2" HorizontalAlignment="Right" ToolTip="{Binding OrganicTest4}">
|
Height="25" FontSize="12"
|
||||||
<Run Text="{Binding OrganicTest1}" FontWeight="Bold" Foreground="{Binding OrganicTest3}"/><Run FontSize="12" Text="{Binding OrganicTest2}"/>
|
Click="OrganicButton_Click"
|
||||||
</TextBlock>
|
Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="60,40,0,0"/>
|
||||||
<Label Content="Bio-KSt.:" Margin="10,40,95,0" Grid.Column="2" HorizontalAlignment="Right" ToolTip="Bio-Kontrollstelle"/>
|
|
||||||
<TextBox x:Name="OrganicAuthorityCodeInput" Text="{Binding OrganicAuthorityCode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
|
||||||
Margin="0,40,10,0" Grid.Column="2" Width="82" HorizontalAlignment="Right"
|
|
||||||
TextChanged="OrganicAuthorityCodeInput_TextChanged" LostFocus="OrganicAuthorityCodeInput_LostFocus"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
<GroupBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Margin="5,5,5,5">
|
<GroupBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Margin="5,5,5,5">
|
||||||
<GroupBox.Header>
|
<GroupBox.Header>
|
||||||
<TextBlock>Rechnungsadresse (optional)
|
<TextBlock>Rechnungsadresse (optional) <Run FontSize="10">für Lieferschein, Anlfrg.-Bstng., Tr.-Gutschr.</Run></TextBlock>
|
||||||
<Run FontSize="10">für Lieferschein, Anlfrg.-Bstng., Tr.-Gutschr.</Run>
|
|
||||||
</TextBlock>
|
|
||||||
</GroupBox.Header>
|
</GroupBox.Header>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Elwig.ViewModels;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@@ -965,6 +966,17 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OrganicButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
if (ViewModel.SelectedMember is not Member m) return;
|
||||||
|
var url = "https://www.easy-cert.com/htm/suchergebnis.htm?" +
|
||||||
|
//$"CustomerNumber={m.LfbisNr}&" +
|
||||||
|
$"Name={(m.BillingAddress?.FullName ?? m.FullName).Replace(' ', '+')}&" +
|
||||||
|
$"PostalCode={(m.BillingAddress?.PostalDest ?? m.PostalDest).AtPlz?.Plz}";
|
||||||
|
Process.Start(new ProcessStartInfo(url) {
|
||||||
|
UseShellExecute = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
|
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (ViewModel.SelectedMember is not Member m || m.PredecessorMgNr == null) return;
|
if (ViewModel.SelectedMember is not Member m || m.PredecessorMgNr == null) return;
|
||||||
FocusMember((int)m.PredecessorMgNr);
|
FocusMember((int)m.PredecessorMgNr);
|
||||||
|
|||||||
@@ -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.1.2.1 ([Changelog](./CHANGELOG.md))
|
**Version:** 1.1.2.2 ([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.1.2.1 ([Änderungsprotokoll](./CHANGELOG.md))
|
**Version:** 1.1.2.2 ([Ä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
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
curl --fail -s -L "https://elwig.at/files/create.sql?v=42" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"
|
curl --fail -s -L "https://elwig.at/files/create.sql?v=41" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"
|
||||||
Reference in new issue
Block a user