[#54] Member: Add IsJuridicalPerson
All checks were successful
Test / Run tests (push) Successful in 2m49s

This commit is contained in:
2024-08-12 15:18:34 +02:00
parent 025ff08d84
commit f48c6a02cb
37 changed files with 225 additions and 116 deletions

View File

@ -32,7 +32,7 @@ namespace Elwig.Documents {
get { get {
IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member; IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member;
var plz = addr.PostalDest.AtPlz; var plz = addr.PostalDest.AtPlz;
return (addr is BillingAddr ? $"{addr.Name}\n" : "") + $"{Member.AdministrativeName}\n{addr.Address}\n{plz?.Plz} {plz?.Ort.Name.Split(",")[0]}\n{addr.PostalDest.Country.Name}"; return string.Join("\n", ((string?[])[Member.BillingAddress?.FullName, Member.AdministrativeName, Member.ForTheAttentionOf, addr.Address, $"{plz?.Plz} {plz?.Ort.Name.Split(",")[0]}", addr.PostalDest.Country.Name]).Where(s => !string.IsNullOrWhiteSpace(s)));
} }
} }

View File

@ -33,7 +33,7 @@ namespace Elwig.Documents {
bool considerCustomModifiers, bool considerCustomModifiers,
Dictionary<string, UnderDelivery>? underDeliveries = null Dictionary<string, UnderDelivery>? underDeliveries = null
) : ) :
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} {p.Variant.Name}", p.Member) { base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.FullName)} {p.Variant.Name}", p.Member) {
UseBillingAddress = true; UseBillingAddress = true;
ShowDateAndLocation = true; ShowDateAndLocation = true;
Data = data; Data = data;

View File

@ -158,7 +158,7 @@ namespace Elwig.Documents {
public void Show() { public void Show() {
if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet"); if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
Pdf.Show(_pdfFile.NewReference(), Title + (this is BusinessDocument b ? $" - {b.Member.Name}" : "")); Pdf.Show(_pdfFile.NewReference(), Title + (this is BusinessDocument b ? $" - {b.Member.FullName}" : ""));
} }
public MimePart AsEmailAttachment(string filename) { public MimePart AsEmailAttachment(string filename) {

View File

@ -2,7 +2,7 @@ using Elwig.Models.Entities;
namespace Elwig.Documents { namespace Elwig.Documents {
public class Letterhead : BusinessDocument { public class Letterhead : BusinessDocument {
public Letterhead(Member m) : base($"Briefkopf {m.Name}", m, true) { public Letterhead(Member m) : base($"Briefkopf {m.FullName}", m, true) {
Aside = ""; Aside = "";
} }
} }

View File

@ -18,21 +18,31 @@
<tbody> <tbody>
<tr class="sectionheading"><th colspan="6">Persönliche Daten</th></tr> <tr class="sectionheading"><th colspan="6">Persönliche Daten</th></tr>
<tr> <tr>
@if (Model.Member.IsJuridicalPerson) {
<th colspan="3" class="small">Name</th>
<th colspan="3" class="small">Zu Handen</th>
} else {
<th class="small">Titel (vorangestellt)</th> <th class="small">Titel (vorangestellt)</th>
<th class="small">Vorname</th> <th class="small">Vorname</th>
<th colspan="3" class="small">Nachname</th> <th colspan="3" class="small">Nachname</th>
<th class="small">Titel (nachgestellt)</th> <th class="small">Titel (nachgestellt)</th>
}
</tr> </tr>
<tr> <tr>
@if (Model.Member.IsJuridicalPerson) {
<td colspan="3" class="large">@Model.Member.Name</td>
<td colspan="3" class="large">@Model.Member.ForTheAttentionOf</td>
} else {
<td class="large">@Model.Member.Prefix</td> <td class="large">@Model.Member.Prefix</td>
<td class="large">@Model.Member.GivenName @Model.Member.MiddleName</td> <td class="large">@Model.Member.GivenName @Model.Member.MiddleName</td>
<td class="large" colspan="3">@Model.Member.FamilyName</td> <td class="large" colspan="3">@Model.Member.Name</td>
<td class="large">@Model.Member.Suffix</td> <td class="large">@Model.Member.Suffix</td>
}
</tr> </tr>
<tr> <tr>
<th>Mitglieds-Nr.:</th> <th>Mitglieds-Nr.:</th>
<td>@Model.Member.MgNr</td> <td>@Model.Member.MgNr</td>
<th colspan="2">Geburtsjahr/-tag:</th> <th colspan="2">@(Model.Member.IsJuridicalPerson ? "Gründungsjahr/-tag" : "Geburtsjahr/-tag"):</th>
<td colspan="2">@(string.Join('.', Model.Member.Birthday?.Split('-')?.Reverse() ?? Array.Empty<string>()))</td> <td colspan="2">@(string.Join('.', Model.Member.Birthday?.Split('-')?.Reverse() ?? Array.Empty<string>()))</td>
</tr> </tr>
<tr> <tr>
@ -50,7 +60,7 @@
<tr class="sectionheading"><th colspan="6">Rechnungsadresse (optional)</th></tr> <tr class="sectionheading"><th colspan="6">Rechnungsadresse (optional)</th></tr>
<tr> <tr>
<th>Name:</th> <th>Name:</th>
<td colspan="5">@Model.Member.BillingAddress?.Name</td> <td colspan="5">@Model.Member.BillingAddress?.FullName</td>
</tr> </tr>
<tr> <tr>
<th>Adresse:</th> <th>Adresse:</th>

View File

@ -9,7 +9,7 @@ namespace Elwig.Helpers {
public static class AppDbUpdater { public static class AppDbUpdater {
// Don't forget to update value in Tests/fetch-resources.bat! // Don't forget to update value in Tests/fetch-resources.bat!
public static readonly int RequiredSchemaVersion = 26; public static readonly int RequiredSchemaVersion = 27;
private static int VersionOffset = 0; private static int VersionOffset = 0;

View File

@ -29,7 +29,7 @@ namespace Elwig.Helpers.Export {
using var cnx = await AppDbContext.ConnectAsync(); using var cnx = await AppDbContext.ConnectAsync();
using var cmd = cnx.CreateCommand(); using var cmd = cnx.CreateCommand();
cmd.CommandText = $""" cmd.CommandText = $"""
SELECT lfbis_nr, family_name, name, billing_name, address, plz, ort, area, SELECT lfbis_nr, name, other_names, billing_name, address, plz, ort, area,
date, weight, type, sortid, qualid, year, hkid, kmw, oe date, weight, type, sortid, qualid, year, hkid, kmw, oe
FROM v_bki_delivery FROM v_bki_delivery
WHERE year = {year} WHERE year = {year}

View File

@ -83,7 +83,7 @@ namespace Elwig.Helpers.Export {
<PmtId><EndToEndId>{id}</EndToEndId></PmtId> <PmtId><EndToEndId>{id}</EndToEndId></PmtId>
<Amt><InstdAmt Ccy="{tx.Currency}">{Transaction.FormatAmount(tx.Amount)}</InstdAmt></Amt> <Amt><InstdAmt Ccy="{tx.Currency}">{Transaction.FormatAmount(tx.Amount)}</InstdAmt></Amt>
<Cdtr> <Cdtr>
<Nm>{SecurityElement.Escape(a.Name[..Math.Min(140, a.Name.Length)])}</Nm> <Nm>{SecurityElement.Escape(a.FullName[..Math.Min(140, a.FullName.Length)])}</Nm>
"""); """);
if (ShowAddresses != AddressMode.Omit) { if (ShowAddresses != AddressMode.Omit) {
var full = ShowAddresses == AddressMode.Full; var full = ShowAddresses == AddressMode.Full;

View File

@ -401,11 +401,12 @@ namespace Elwig.Helpers.Export {
return new JsonObject { return new JsonObject {
["mgnr"] = m.MgNr, ["mgnr"] = m.MgNr,
["predecessor_mgnr"] = m.PredecessorMgNr, ["predecessor_mgnr"] = m.PredecessorMgNr,
["name"] = m.Name,
["prefix"] = m.Prefix, ["prefix"] = m.Prefix,
["given_name"] = m.GivenName, ["given_name"] = m.GivenName,
["middle_names"] = m.MiddleName, ["middle_names"] = m.MiddleName,
["family_name"] = m.FamilyName,
["suffix"] = m.Suffix, ["suffix"] = m.Suffix,
["attn"] = m.ForTheAttentionOf,
["birthday"] = m.Birthday, ["birthday"] = m.Birthday,
["entry_date"] = m.EntryDate != null ? $"{m.EntryDate:yyyy-MM-dd}" : null, ["entry_date"] = m.EntryDate != null ? $"{m.EntryDate:yyyy-MM-dd}" : null,
["exit_date"] = m.ExitDate != null ? $"{m.ExitDate:yyyy-MM-dd}" : null, ["exit_date"] = m.ExitDate != null ? $"{m.ExitDate:yyyy-MM-dd}" : null,
@ -414,6 +415,7 @@ 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,
["juridical_pers"] = m.IsJuridicalPerson,
["volllieferant"] = m.IsVollLieferant, ["volllieferant"] = m.IsVollLieferant,
["buchführend"] = m.IsBuchführend, ["buchführend"] = m.IsBuchführend,
["organic"] = m.IsOrganic, ["organic"] = m.IsOrganic,
@ -431,7 +433,7 @@ namespace Elwig.Helpers.Export {
["country"] = m.CountryNum, ["country"] = m.CountryNum,
}, },
["billing_address"] = m.BillingAddress != null ? new JsonObject { ["billing_address"] = m.BillingAddress != null ? new JsonObject {
["name"] = m.BillingAddress.Name, ["name"] = m.BillingAddress.FullName,
["address"] = m.BillingAddress.Address, ["address"] = m.BillingAddress.Address,
["postal_dest"] = m.BillingAddress.PostalDestId, ["postal_dest"] = m.BillingAddress.PostalDestId,
["country"] = m.BillingAddress.CountryNum, ["country"] = m.BillingAddress.CountryNum,
@ -460,11 +462,12 @@ namespace Elwig.Helpers.Export {
return (new Member { return (new Member {
MgNr = mgnr, MgNr = mgnr,
PredecessorMgNr = json["predecessor_mgnr"]?.AsValue().GetValue<int>(), PredecessorMgNr = json["predecessor_mgnr"]?.AsValue().GetValue<int>(),
Name = json["name"]!.AsValue().GetValue<string>(),
Prefix = json["prefix"]?.AsValue().GetValue<string>(), Prefix = json["prefix"]?.AsValue().GetValue<string>(),
GivenName = json["given_name"]!.AsValue().GetValue<string>(), GivenName = json["given_name"]?.AsValue().GetValue<string>(),
MiddleName = json["middle_names"]?.AsValue().GetValue<string>(), MiddleName = json["middle_names"]?.AsValue().GetValue<string>(),
FamilyName = json["family_name"]!.AsValue().GetValue<string>(),
Suffix = json["suffix"]?.AsValue().GetValue<string>(), Suffix = json["suffix"]?.AsValue().GetValue<string>(),
ForTheAttentionOf = json["attn"]?.AsValue().GetValue<string>(),
Birthday = json["birthday"]?.AsValue().GetValue<string>(), Birthday = json["birthday"]?.AsValue().GetValue<string>(),
EntryDateString = json["entry_date"]?.AsValue().GetValue<string>(), EntryDateString = json["entry_date"]?.AsValue().GetValue<string>(),
ExitDateString = json["exit_date"]?.AsValue().GetValue<string>(), ExitDateString = json["exit_date"]?.AsValue().GetValue<string>(),
@ -473,6 +476,7 @@ 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>(),
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,
IsOrganic = json["organic"]?.AsValue().GetValue<bool>() ?? false, IsOrganic = json["organic"]?.AsValue().GetValue<bool>() ?? false,
@ -490,7 +494,7 @@ namespace Elwig.Helpers.Export {
Comment = json["comment"]?.AsValue().GetValue<string>(), Comment = json["comment"]?.AsValue().GetValue<string>(),
}, json["billing_address"] is JsonObject a ? new BillingAddr { }, json["billing_address"] is JsonObject a ? new BillingAddr {
MgNr = mgnr, MgNr = mgnr,
Name = a["name"]!.AsValue().GetValue<string>(), FullName = a["name"]!.AsValue().GetValue<string>(),
CountryNum = a["country"]!.AsValue().GetValue<int>(), CountryNum = a["country"]!.AsValue().GetValue<int>(),
PostalDestId = a["postal_dest"]!.AsValue().GetValue<string>(), PostalDestId = a["postal_dest"]!.AsValue().GetValue<string>(),
Address = a["address"]!.AsValue().GetValue<string>(), Address = a["address"]!.AsValue().GetValue<string>(),

View File

@ -35,7 +35,7 @@ namespace Elwig.Models.Dtos {
private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) { private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
return await table.FromSqlRaw($""" return await table.FromSqlRaw($"""
SELECT m.mgnr, m.family_name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
p.plz, o.name AS ort, m.address, p.plz, o.name AS ort, m.address,

View File

@ -50,7 +50,7 @@ namespace Elwig.Models.Dtos {
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) { private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) {
return await table.FromSqlRaw($""" return await table.FromSqlRaw($"""
SELECT m.mgnr, m.family_name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision, p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision,

View File

@ -88,7 +88,7 @@ namespace Elwig.Models.Dtos {
Time = d.Time; Time = d.Time;
DeliveryBranch = d.Branch.Name; DeliveryBranch = d.Branch.Name;
MgNr = m.MgNr; MgNr = m.MgNr;
Name1 = m.FamilyName; Name1 = m.Name;
Name2 = m.AdministrativeName2; Name2 = m.AdministrativeName2;
AdministrativeName = m.AdministrativeName; AdministrativeName = m.AdministrativeName;
MemberBranch = m.Branch?.Name; MemberBranch = m.Branch?.Name;

View File

@ -37,7 +37,7 @@ namespace Elwig.Models.Dtos {
private static async Task<IEnumerable<MemberDeliveryPerVariantRowSingle>> FromDbSet(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) { private static async Task<IEnumerable<MemberDeliveryPerVariantRowSingle>> FromDbSet(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) {
return await table.FromSqlRaw($""" return await table.FromSqlRaw($"""
SELECT m.mgnr, m.family_name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
p.plz, o.name AS ort, m.address, p.plz, o.name AS ort, m.address,

View File

@ -91,7 +91,7 @@ namespace Elwig.Models.Dtos {
public MemberListRow(Member m, int? areaCom = null) { public MemberListRow(Member m, int? areaCom = null) {
MgNr = m.MgNr; MgNr = m.MgNr;
Name1 = m.FamilyName; Name1 = m.Name;
Name2 = m.AdministrativeName2; Name2 = m.AdministrativeName2;
DefaultKg = m.DefaultKg?.Name; DefaultKg = m.DefaultKg?.Name;
Branch = m.Branch?.Name; Branch = m.Branch?.Name;
@ -100,7 +100,7 @@ namespace Elwig.Models.Dtos {
Plz = m.PostalDest.AtPlz!.Plz; Plz = m.PostalDest.AtPlz!.Plz;
Locality = m.PostalDest.AtPlz!.Ort.Name; Locality = m.PostalDest.AtPlz!.Ort.Name;
if (m.BillingAddress is BillingAddr a) { if (m.BillingAddress is BillingAddr a) {
BillingName = a.Name; BillingName = a.FullName;
BillingAddress = a.Address; BillingAddress = a.Address;
BillingPlz = a.PostalDest.AtPlz!.Plz; BillingPlz = a.PostalDest.AtPlz!.Plz;
BillingLocality = a.PostalDest.AtPlz!.Ort.Name; BillingLocality = a.PostalDest.AtPlz!.Ort.Name;

View File

@ -26,7 +26,7 @@ namespace Elwig.Models.Dtos {
public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) { public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) {
var rows = await table.FromSqlRaw($""" var rows = await table.FromSqlRaw($"""
SELECT m.mgnr, m.family_name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
p.plz, o.name AS ort, m.address, m.business_shares, p.plz, o.name AS ort, m.address, m.business_shares,

View File

@ -8,7 +8,7 @@ namespace Elwig.Models.Entities {
public int MgNr { get; set; } public int MgNr { get; set; }
[Column("name")] [Column("name")]
public required string Name { get; set; } public required string FullName { get; set; }
[Column("country")] [Column("country")]
public int CountryNum { get; set; } public int CountryNum { get; set; }

View File

@ -118,7 +118,7 @@ namespace Elwig.Models.Entities {
public int SearchScore(IEnumerable<string> keywords) { public int SearchScore(IEnumerable<string> keywords) {
var list = new string?[] { var list = new string?[] {
LsNr, Time?.ToString("HH:mm"), LsNr, Time?.ToString("HH:mm"),
Member.FamilyName, Member.MiddleName, Member.GivenName, Member.BillingAddress?.Name, Member.Name, Member.MiddleName, Member.GivenName, Member.BillingAddress?.FullName,
Comment Comment
}.ToList(); }.ToList();
list.AddRange(Parts.Select(p => p.Comment).Distinct()); list.AddRange(Parts.Select(p => p.Comment).Distinct());

View File

@ -48,8 +48,8 @@ namespace Elwig.Models.Entities {
public int SearchScore(IEnumerable<string> keywords) { public int SearchScore(IEnumerable<string> keywords) {
return Utils.GetSearchScore([ return Utils.GetSearchScore([
Schedule.Description, Schedule.Description,
Member.FamilyName, Member.MiddleName, Member.GivenName, Member.Name, Member.MiddleName, Member.GivenName,
Member.BillingAddress?.Name, Member.BillingAddress?.FullName,
], keywords); ], keywords);
} }
} }

View File

@ -14,11 +14,14 @@ namespace Elwig.Models.Entities {
[Column("predecessor_mgnr")] [Column("predecessor_mgnr")]
public int? PredecessorMgNr { get; set; } public int? PredecessorMgNr { get; set; }
[Column("name")]
public required string Name { get; set; }
[Column("prefix")] [Column("prefix")]
public string? Prefix { get; set; } public string? Prefix { get; set; }
[Column("given_name")] [Column("given_name")]
public required string GivenName { get; set; } public string? GivenName { get; set; }
[Column("middle_names")] [Column("middle_names")]
public string? MiddleName { get; set; } public string? MiddleName { get; set; }
@ -28,30 +31,22 @@ namespace Elwig.Models.Entities {
set => MiddleName = (value.Length > 0) ? string.Join(" ", value) : null; set => MiddleName = (value.Length > 0) ? string.Join(" ", value) : null;
} }
[Column("family_name")]
public required string FamilyName { get; set; }
[Column("suffix")] [Column("suffix")]
public string? Suffix { get; set; } public string? Suffix { get; set; }
public string Name => [Column("attn")]
(Prefix != null ? Prefix + " " : "") + public string? ForTheAttentionOf { get; set; }
GivenName + " " +
(MiddleName != null ? MiddleName + " " : "") +
FamilyName +
(Suffix != null ? " " + Suffix : "");
public string ShortName => GivenName + " " + FamilyName; [NotMapped]
public string FullName => IsJuridicalPerson ? Name : string.Join(" ", ((string?[])[Prefix, GivenName, MiddleName, Name, Suffix]).Where(s => !string.IsNullOrWhiteSpace(s)));
public string AdministrativeName => AdministrativeName1 + " " + AdministrativeName2; [NotMapped]
public string ShortName => (!string.IsNullOrWhiteSpace(GivenName) ? $"{GivenName} " : "") + Name;
public string AdministrativeName1 => FamilyName.Replace('ß', 'ẞ').ToUpper(); [NotMapped]
public string AdministrativeName => AdministrativeName1 + (!string.IsNullOrWhiteSpace(AdministrativeName2) ? $" {AdministrativeName2}" : "");
public string AdministrativeName2 => [NotMapped]
(Prefix != null ? Prefix + " " : "") + public string AdministrativeName1 => IsJuridicalPerson ? Name : Name.Replace('ß', 'ẞ').ToUpper();
GivenName + [NotMapped]
(MiddleName != null ? " " + MiddleName : "") + public string? AdministrativeName2 => IsJuridicalPerson ? null : string.Join(" ", ((string?[])[Prefix, GivenName, MiddleName, Suffix]).Where(s => !string.IsNullOrWhiteSpace(s)));
(Suffix != null ? " " + Suffix : "");
[Column("birthday")] [Column("birthday")]
public string? Birthday { get; set; } public string? Birthday { get; set; }
@ -87,6 +82,9 @@ namespace Elwig.Models.Entities {
[Column("ustid_nr")] [Column("ustid_nr")]
public string? UstIdNr { get; set; } public string? UstIdNr { get; set; }
[Column("juridical_pers")]
public bool IsJuridicalPerson { get; set; }
[Column("volllieferant")] [Column("volllieferant")]
public bool IsVollLieferant { get; set; } public bool IsVollLieferant { get; set; }
@ -185,8 +183,8 @@ namespace Elwig.Models.Entities {
public int SearchScore(IEnumerable<string> keywords) { public int SearchScore(IEnumerable<string> keywords) {
return Utils.GetSearchScore([ return Utils.GetSearchScore([
FamilyName, MiddleName, GivenName, Name, MiddleName, GivenName,
BillingAddress?.Name, BillingAddress?.FullName,
Comment, Comment,
], keywords); ], keywords);
} }

View File

@ -2,7 +2,7 @@ using Elwig.Models.Entities;
namespace Elwig.Models { namespace Elwig.Models {
public interface IAddress { public interface IAddress {
string Name { get; } string FullName { get; }
string Address { get; } string Address { get; }
PostalDest PostalDest { get; } PostalDest PostalDest { get; }
} }

View File

@ -1,4 +1,4 @@
-- schema version 24 to 25 -- schema version 25 to 26
CREATE TABLE delivery_schedule ( CREATE TABLE delivery_schedule (
year INTEGER NOT NULL, year INTEGER NOT NULL,

View File

@ -0,0 +1,48 @@
-- schema version 26 to 27
PRAGMA writable_schema = ON;
ALTER TABLE member RENAME COLUMN family_name TO name;
ALTER TABLE member ADD COLUMN attn TEXT DEFAULT NULL;
ALTER TABLE member ADD COLUMN juridical_pers INTEGER NOT NULL CHECK (juridical_pers IN (TRUE, FALSE)) DEFAULT FALSE;
UPDATE sqlite_schema SET sql = REPLACE(sql, 'given_name TEXT NOT NULL', 'given_name TEXT DEFAULT NULL')
WHERE type = 'table' AND name = 'member';
DROP VIEW v_bki_member;
CREATE VIEW v_bki_member AS
SELECT s.year, m.mgnr, m.lfbis_nr, m.name,
(COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '')) AS other_names,
a.name AS billing_name, COALESCE(a.address, m.address) AS address,
COALESCE(a.country, m.country) AS country, COALESCE(a.postal_dest, m.postal_dest) AS postal_dest,
SUM(IIF(c.year_from <= s.year AND (c.year_to IS NULL OR c.year_to >= s.year), c.area, 0)) AS area
FROM season s, member m
LEFT JOIN member_billing_address a ON a.mgnr = m.mgnr
LEFT JOIN area_commitment c ON c.mgnr = m.mgnr
GROUP BY s.year, m.mgnr;
DROP VIEW v_bki_delivery;
CREATE VIEW v_bki_delivery AS
SELECT m.lfbis_nr, m.name, m.other_names, m.billing_name,
m.address, plz.plz, IIF(INSTR(o.name, ',') = 0, o.name, SUBSTR(o.name, 1, INSTR(o.name, ',') - 1)) AS ort,
d.date, d.weight, v.type, v.sortid, d.qualid, d.year, d.hkid, d.kmw, d.oe,
m.area
FROM v_delivery d
JOIN v_bki_member m ON (m.year, m.mgnr) = (d.year, d.mgnr)
JOIN postal_dest pd ON (pd.country, pd.id) = (m.country, m.postal_dest)
LEFT JOIN AT_plz_dest ap ON (ap.country, ap.id) = (pd.country, pd.id)
LEFT JOIN AT_plz plz ON plz.plz = ap.plz
LEFT JOIN AT_ort o ON o.okz = ap.okz
JOIN wine_variety v ON v.sortid = d.sortid
ORDER BY d.date, d.time;
PRAGMA schema_version = 2601;
PRAGMA writable_schema = OFF;
UPDATE member
SET name = a.name, juridical_pers = TRUE
FROM member_billing_address a
WHERE a.mgnr = member.mgnr AND member.name = '';
DELETE FROM member_billing_address
WHERE mgnr IN (SELECT mgnr FROM member WHERE name = member_billing_address.name)

View File

@ -145,7 +145,7 @@ namespace Elwig.Services {
.OrderBy(a => a.Schedule.DateString) .OrderBy(a => a.Schedule.DateString)
.ThenBy(a => a.Schedule.Branch.Name) .ThenBy(a => a.Schedule.Branch.Name)
.ThenBy(a => a.Schedule.Description) .ThenBy(a => a.Schedule.Description)
.ThenBy(a => a.Member.FamilyName) .ThenBy(a => a.Member.Name)
.ThenBy(a => a.Member.GivenName) .ThenBy(a => a.Member.GivenName)
.ThenBy(a => a.Member.MgNr); .ThenBy(a => a.Member.MgNr);

View File

@ -55,11 +55,13 @@ namespace Elwig.Services {
vm.IsMemberSelected = true; vm.IsMemberSelected = true;
vm.MgNrString = $"{m.MgNr}"; vm.MgNrString = $"{m.MgNr}";
vm.PredecessorMgNrString = $"{m.PredecessorMgNr}"; vm.PredecessorMgNrString = $"{m.PredecessorMgNr}";
vm.IsJuridicalPerson = m.IsJuridicalPerson;
vm.EnableMemberReferenceButton = m.PredecessorMgNr != null; vm.EnableMemberReferenceButton = m.PredecessorMgNr != null;
vm.Prefix = m.Prefix; vm.Prefix = m.Prefix;
vm.GivenName = m.GivenName; vm.GivenName = m.GivenName;
vm.FamilyName = m.FamilyName; vm.Name = m.Name;
vm.Suffix = m.Suffix; vm.Suffix = m.Suffix;
vm.ForTheAttentionOf = m.ForTheAttentionOf;
vm.Birthday = (m.Birthday != null) ? string.Join(".", m.Birthday.Split("-").Reverse()) : null; vm.Birthday = (m.Birthday != null) ? string.Join(".", m.Birthday.Split("-").Reverse()) : null;
if (m.Birthday?.Length == 10) { if (m.Birthday?.Length == 10) {
vm.Age = Utils.GetAge(DateOnly.ParseExact(m.Birthday, "yyyy-MM-dd")).ToString(); vm.Age = Utils.GetAge(DateOnly.ParseExact(m.Birthday, "yyyy-MM-dd")).ToString();
@ -109,7 +111,7 @@ namespace Elwig.Services {
var billingAddr = m.BillingAddress; var billingAddr = m.BillingAddress;
if (billingAddr != null) { if (billingAddr != null) {
vm.BillingName = billingAddr.Name; vm.BillingName = billingAddr.FullName;
vm.BillingAddress = billingAddr.Address; vm.BillingAddress = billingAddr.Address;
if (billingAddr.PostalDest.AtPlz is AT_PlzDest b) { if (billingAddr.PostalDest.AtPlz is AT_PlzDest b) {
vm.BillingPlzString = $"{b.Plz}"; vm.BillingPlzString = $"{b.Plz}";
@ -150,8 +152,12 @@ namespace Elwig.Services {
vm.StatusDeliveriesThisSeasonToolTip = d2Grid; vm.StatusDeliveriesThisSeasonToolTip = d2Grid;
var c = m.ActiveAreaCommitments(ctx, Utils.CurrentLastSeason); var c = m.ActiveAreaCommitments(ctx, Utils.CurrentLastSeason);
int maxKgPerHa = 10_000;
try {
var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year)); var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year));
var (text, grid) = await AreaComService.GenerateToolTip(c, s?.MaxKgPerHa ?? 10_000); if (s != null) maxKgPerHa = s.MaxKgPerHa;
} catch { }
var (text, grid) = await AreaComService.GenerateToolTip(c, maxKgPerHa);
vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}"; vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}";
vm.StatusAreaCommitment = text; vm.StatusAreaCommitment = text;
vm.StatusAreaCommitmentToolTip = grid; vm.StatusAreaCommitmentToolTip = grid;
@ -392,14 +398,14 @@ namespace Elwig.Services {
} else if (vm.MemberListOrderByName) { } else if (vm.MemberListOrderByName) {
query = query query = query
.OrderBy(m => m.Branch!.Name) .OrderBy(m => m.Branch!.Name)
.ThenBy(m => m.FamilyName) .ThenBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr); .ThenBy(m => m.MgNr);
} else if (vm.MemberListOrderByOrt) { } else if (vm.MemberListOrderByOrt) {
query = query query = query
.OrderBy(m => m.Branch!.Name) .OrderBy(m => m.Branch!.Name)
.ThenBy(m => m.DefaultWbKg!.AtKg.Name) .ThenBy(m => m.DefaultWbKg!.AtKg.Name)
.ThenBy(m => m.FamilyName) .ThenBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr); .ThenBy(m => m.MgNr);
} }
@ -497,10 +503,12 @@ namespace Elwig.Services {
var m = new Member { var m = new Member {
MgNr = oldMgNr ?? newMgNr, MgNr = oldMgNr ?? newMgNr,
PredecessorMgNr = vm.PredecessorMgNr, PredecessorMgNr = vm.PredecessorMgNr,
Prefix = string.IsNullOrEmpty(vm.Prefix) ? null : vm.Prefix, IsJuridicalPerson = vm.IsJuridicalPerson,
GivenName = vm.GivenName!, Prefix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Prefix) ? null : vm.Prefix,
FamilyName = vm.FamilyName!, GivenName = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.GivenName) ? null : vm.GivenName,
Suffix = string.IsNullOrEmpty(vm.Suffix) ? null : vm.Suffix, Name = vm.Name!,
Suffix = vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.Suffix) ? null : vm.Suffix,
ForTheAttentionOf = !vm.IsJuridicalPerson || string.IsNullOrWhiteSpace(vm.ForTheAttentionOf) ? null : vm.ForTheAttentionOf,
Birthday = string.IsNullOrEmpty(vm.Birthday) ? null : string.Join("-", vm.Birthday!.Split(".").Reverse()), Birthday = string.IsNullOrEmpty(vm.Birthday) ? null : string.Join("-", vm.Birthday!.Split(".").Reverse()),
IsDeceased = vm.IsDeceased, IsDeceased = vm.IsDeceased,
CountryNum = 40, // Austria AT AUT CountryNum = 40, // Austria AT AUT
@ -540,7 +548,7 @@ namespace Elwig.Services {
var p = vm.BillingOrt; var p = vm.BillingOrt;
ctx.Add(new BillingAddr { ctx.Add(new BillingAddr {
MgNr = m.MgNr, MgNr = m.MgNr,
Name = vm.BillingName, FullName = vm.BillingName,
Address = vm.BillingAddress ?? "", Address = vm.BillingAddress ?? "",
CountryNum = p.CountryNum, CountryNum = p.CountryNum,
PostalDestId = p.Id, PostalDestId = p.Id,

View File

@ -38,7 +38,7 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private bool _enableSearchInputs = true; private bool _enableSearchInputs = true;
[ObservableProperty] [ObservableProperty]
public IEnumerable<bool> _memberHasDeliveries = [ .. Enumerable.Range(0, 9999).Select(i => false) ]; private IEnumerable<bool> _memberHasDeliveries = [ .. Enumerable.Range(0, 9999).Select(i => false) ];
[ObservableProperty] [ObservableProperty]
private bool _memberListOrderByMgNr; private bool _memberListOrderByMgNr;
@ -54,14 +54,18 @@ namespace Elwig.ViewModels {
private string? _predecessorMgNrString; private string? _predecessorMgNrString;
public int? PredecessorMgNr => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null; public int? PredecessorMgNr => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null;
[ObservableProperty] [ObservableProperty]
private bool _isJuridicalPerson;
[ObservableProperty]
private string? _prefix; private string? _prefix;
[ObservableProperty] [ObservableProperty]
private string? _givenName; private string? _givenName;
[ObservableProperty] [ObservableProperty]
private string? _familyName; private string? _name;
[ObservableProperty] [ObservableProperty]
private string? _suffix; private string? _suffix;
[ObservableProperty] [ObservableProperty]
private string? _forTheAttentionOf;
[ObservableProperty]
private string? _birthday; private string? _birthday;
[ObservableProperty] [ObservableProperty]
private string? _age; private string? _age;
@ -176,5 +180,9 @@ namespace Elwig.ViewModels {
private Visibility _controlButtonsVisibility = Visibility.Visible; private Visibility _controlButtonsVisibility = Visibility.Visible;
[ObservableProperty] [ObservableProperty]
private Visibility _editingButtonsVisibility = Visibility.Hidden; private Visibility _editingButtonsVisibility = Visibility.Hidden;
[ObservableProperty]
private Visibility _personalNameVisibility = Visibility.Visible;
[ObservableProperty]
private Visibility _juridicalNameVisibility = Visibility.Hidden;
} }
} }

View File

@ -159,7 +159,10 @@ namespace Elwig.Windows {
protected void ValidateRequiredInputs() { protected void ValidateRequiredInputs() {
foreach (var input in RequiredInputs) { foreach (var input in RequiredInputs) {
if (input is TextBox tb && tb.Text.Length == 0) { if (input is Control c && c.Visibility != Visibility.Visible) {
ControlUtils.ClearInputState(input);
Valid[input] = true;
} else if (input is TextBox tb && tb.Text.Length == 0) {
ControlUtils.SetInputInvalid(input); ControlUtils.SetInputInvalid(input);
Valid[input] = false; Valid[input] = false;
} else if (input is ComboBox cb && cb.SelectedItem == null && cb.ItemsSource != null && cb.ItemsSource.Cast<object>().Any()) { } else if (input is ComboBox cb && cb.SelectedItem == null && cb.ItemsSource != null && cb.ItemsSource.Cast<object>().Any()) {

View File

@ -434,7 +434,7 @@ namespace Elwig.Windows {
.Where(m => m.IsActive || !IsCreating) .Where(m => m.IsActive || !IsCreating)
.Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ToListAsync()); .ToListAsync());
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync()); ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
@ -764,7 +764,7 @@ namespace Elwig.Windows {
.Where(m => m.IsActive || !ViewModel.IsReceipt) .Where(m => m.IsActive || !ViewModel.IsReceipt)
.Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ToListAsync()); .ToListAsync());
if (DeliveryList.SelectedItem is not Delivery d) { if (DeliveryList.SelectedItem is not Delivery d) {
@ -810,7 +810,7 @@ namespace Elwig.Windows {
.Where(m => m.IsActive || !ViewModel.IsReceipt) .Where(m => m.IsActive || !ViewModel.IsReceipt)
.Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ToListAsync()); .ToListAsync());
IsCreating = true; IsCreating = true;

View File

@ -288,7 +288,7 @@
</ComboBox.ItemTemplateSelector> </ComboBox.ItemTemplateSelector>
</ComboBox> </ComboBox>
<Label Content="Gewicht" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="Gewicht:" Margin="10,70,0,0" Grid.Column="0"/>
<ctrl:UnitTextBox x:Name="WeightInput" Unit="kg" Text="{Binding WeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <ctrl:UnitTextBox x:Name="WeightInput" Unit="kg" Text="{Binding WeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="1" Margin="0,70,10,10" Width="61" HorizontalAlignment="Left" Grid.Column="1" Margin="0,70,10,10" Width="61" HorizontalAlignment="Left"
TextChanged="WeightInput_TextChanged" KeyUp="Input_KeyUp"/> TextChanged="WeightInput_TextChanged" KeyUp="Input_KeyUp"/>

View File

@ -107,7 +107,7 @@ namespace Elwig.Windows {
var dict = deliveryAncmts.AsParallel() var dict = deliveryAncmts.AsParallel()
.ToDictionary(a => a, a => a.SearchScore(filter)) .ToDictionary(a => a, a => a.SearchScore(filter))
.OrderByDescending(a => a.Value) .OrderByDescending(a => a.Value)
.ThenBy(a => a.Key.Member.FamilyName) .ThenBy(a => a.Key.Member.Name)
.ThenBy(a => a.Key.Member.GivenName) .ThenBy(a => a.Key.Member.GivenName)
.ThenBy(a => a.Key.Member.MgNr); .ThenBy(a => a.Key.Member.MgNr);
var threshold = dict.Select(a => a.Value).Max() * 3 / 4; var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
@ -117,7 +117,7 @@ namespace Elwig.Windows {
.ToList(); .ToList();
} else { } else {
deliveryAncmts = deliveryAncmts deliveryAncmts = deliveryAncmts
.OrderBy(a => a.Member.FamilyName) .OrderBy(a => a.Member.Name)
.ThenBy(a => a.Member.GivenName) .ThenBy(a => a.Member.GivenName)
.ThenBy(a => a.Member.MgNr) .ThenBy(a => a.Member.MgNr)
.ToList(); .ToList();
@ -160,7 +160,7 @@ namespace Elwig.Windows {
.Where(m => m.IsActive || !IsCreating) .Where(m => m.IsActive || !IsCreating)
.Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToListAsync()); .ToListAsync());
@ -244,7 +244,7 @@ namespace Elwig.Windows {
.Where(m => m.IsActive || !IsCreating) .Where(m => m.IsActive || !IsCreating)
.Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToListAsync()); .ToListAsync());
@ -361,7 +361,7 @@ namespace Elwig.Windows {
.Where(m => m.IsActive || !IsCreating) .Where(m => m.IsActive || !IsCreating)
.Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.PostalDest.AtPlz!.Ort)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToListAsync()); .ToListAsync());

View File

@ -166,7 +166,7 @@ namespace Elwig.Windows {
} }
ControlUtils.RenewItemsSource(MemberCustomInput, await ctx.Members ControlUtils.RenewItemsSource(MemberCustomInput, await ctx.Members
.Where(m => m.IsActive) .Where(m => m.IsActive)
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.Include(m => m.Branch) .Include(m => m.Branch)
.Include(m => m.DefaultWbKg!.AtKg) .Include(m => m.DefaultWbKg!.AtKg)
@ -438,7 +438,7 @@ namespace Elwig.Windows {
.ToList(); .ToList();
} else if (OrderNameInput.IsChecked == true) { } else if (OrderNameInput.IsChecked == true) {
recipients = recipients recipients = recipients
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToList(); .ToList();
@ -447,7 +447,7 @@ namespace Elwig.Windows {
recipients = recipients recipients = recipients
.OrderBy(m => m.BillingAddress?.PostalDest.AtPlz?.Plz ?? m.PostalDest.AtPlz?.Plz) .OrderBy(m => m.BillingAddress?.PostalDest.AtPlz?.Plz ?? m.PostalDest.AtPlz?.Plz)
.ThenBy(m => m.BillingAddress?.PostalDest.AtPlz?.Ort.Name ?? m.PostalDest.AtPlz?.Ort.Name) .ThenBy(m => m.BillingAddress?.PostalDest.AtPlz?.Ort.Name ?? m.PostalDest.AtPlz?.Ort.Name)
.ThenBy(m => m.FamilyName) .ThenBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToList(); .ToList();
@ -455,7 +455,7 @@ namespace Elwig.Windows {
recipients = recipients recipients = recipients
.OrderBy(m => m.PostalDest.AtPlz?.Plz) .OrderBy(m => m.PostalDest.AtPlz?.Plz)
.ThenBy(m => m.PostalDest.AtPlz?.Ort.Name) .ThenBy(m => m.PostalDest.AtPlz?.Ort.Name)
.ThenBy(m => m.FamilyName) .ThenBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToList(); .ToList();

View File

@ -199,7 +199,7 @@
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Nachname" Binding="{Binding FamilyName}" Width="140"/> <DataGridTextColumn Header="Nachname" Binding="{Binding Name}" Width="140"/>
<DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="140"/> <DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="140"/>
<DataGridTextColumn Header="GA" Binding="{Binding BusinessShares, StringFormat='{}{0} '}" Width="40"> <DataGridTextColumn Header="GA" Binding="{Binding BusinessShares, StringFormat='{}{0} '}" Width="40">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
@ -208,7 +208,7 @@
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Rechnungsadresse" Binding="{Binding BillingAddress.Name}" Width="200"/> <DataGridTextColumn Header="Rechnungsadresse" Binding="{Binding BillingAddress.FullName}" Width="200"/>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
@ -285,6 +285,9 @@
<TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,10,0,0" Width="48" Grid.Column="1" TextAlignment="Right" HorizontalAlignment="Left" Margin="0,10,0,0" Width="48" Grid.Column="1" TextAlignment="Right" HorizontalAlignment="Left"
TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus"/> TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus"/>
<CheckBox x:Name="JuridicalPersonInput" Content="Juristische Person" IsChecked="{Binding IsJuridicalPerson}"
Checked="JuridicalPersonInput_Changed" Unchecked="JuridicalPersonInput_Changed"
Margin="53,15,0,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Label Content="Vorg.:" Margin="10,10,0,0" Grid.Column="2"/> <Label Content="Vorg.:" Margin="10,10,0,0" Grid.Column="2"/>
<TextBox x:Name="PredecessorMgNrInput" Text="{Binding PredecessorMgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="PredecessorMgNrInput" Text="{Binding PredecessorMgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
@ -294,27 +297,33 @@
Margin="53,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" IsEnabled="{Binding EnableMemberReferenceButton}" ToolTip="Zu Vorgänger springen" Margin="53,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" IsEnabled="{Binding EnableMemberReferenceButton}" ToolTip="Zu Vorgänger springen"
Click="MemberReferenceButton_Click"/> Click="MemberReferenceButton_Click"/>
<Label Content="Präfix:" Margin="10,40,0,0" Grid.Column="2"/> <Label Content="Präfix:" Margin="10,40,0,0" Grid.Column="2" Visibility="{Binding PersonalNameVisibility}"/>
<TextBox x:Name="PrefixInput" Text="{Binding Prefix, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="PrefixInput" Text="{Binding Prefix, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding PersonalNameVisibility}"
Margin="0,40,10,0" Grid.Column="3" Margin="0,40,10,0" Grid.Column="3"
TextChanged="TextBox_TextChanged"/> TextChanged="TextBox_TextChanged"/>
<Label Content="Vorname:" Margin="10,40,0,0" Grid.Column="0"/> <Label Content="Name:" Margin="10,40,0,0" Grid.Column="0" Visibility="{Binding JuridicalNameVisibility}"/>
<TextBox x:Name="GivenNameInput" Text="{Binding GivenName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <Label Content="Vorname:" Margin="10,40,0,0" Grid.Column="0" Visibility="{Binding PersonalNameVisibility}"/>
<TextBox x:Name="GivenNameInput" Text="{Binding GivenName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding PersonalNameVisibility}"
Margin="0,40,0,0" Grid.Column="1" Margin="0,40,0,0" Grid.Column="1"
TextChanged="TextBox_TextChanged"/> TextChanged="TextBox_TextChanged"/>
<Label Content="Nachname:" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="Nachname:" Margin="10,70,0,0" Grid.Column="0" Visibility="{Binding PersonalNameVisibility}"/>
<TextBox x:Name="FamilyNameInput" Text="{Binding FamilyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="NameInput" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,70,0,0" Grid.Column="1" Margin="0,70,0,0" Grid.Column="1"
TextChanged="TextBox_TextChanged"/> TextChanged="TextBox_TextChanged"/>
<Label Content="Suffix:" Margin="10,70,0,0" Grid.Column="2"/> <Label Content="Zu Handen:" Margin="10,70,0,0" Grid.Column="0" Visibility="{Binding JuridicalNameVisibility}"/>
<TextBox x:Name="SuffixInput" Text="{Binding Suffix, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="AttnInput" Text="{Binding ForTheAttentionOf, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding JuridicalNameVisibility}"
Margin="0,70,10,0" Grid.Column="1" Grid.ColumnSpan="3"
TextChanged="TextBox_TextChanged"/>
<Label Content="Suffix:" Margin="10,70,0,0" Grid.Column="2" Visibility="{Binding PersonalNameVisibility}"/>
<TextBox x:Name="SuffixInput" Text="{Binding Suffix, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding PersonalNameVisibility}"
Margin="0,70,10,0" Grid.Column="3" Margin="0,70,10,0" Grid.Column="3"
TextChanged="TextBox_TextChanged"/> TextChanged="TextBox_TextChanged"/>
<Label Content="Geburtstag:" Margin="10,100,0,0" Grid.Column="0"/> <Label x:Name="BirthdayLabel" Content="Geburtstag:" Margin="10,100,0,0" Grid.Column="0"/>
<TextBox x:Name="BirthdayInput" Text="{Binding Birthday, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="BirthdayInput" Text="{Binding Birthday, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,100,0,0" Grid.Column="1" Width="78" TextAlignment="Right" HorizontalAlignment="Left" Margin="0,100,0,0" Grid.Column="1" Width="78" TextAlignment="Right" HorizontalAlignment="Left"
TextChanged="PartialDateInput_TextChanged" LostFocus="PartialDateInput_LostFocus"/> TextChanged="PartialDateInput_TextChanged" LostFocus="PartialDateInput_LostFocus"/>

View File

@ -41,7 +41,7 @@ namespace Elwig.Windows {
SearchInput, ActiveMemberInput, MemberList, SearchInput, ActiveMemberInput, MemberList,
]; ];
RequiredInputs = [ RequiredInputs = [
MgNrInput, GivenNameInput, FamilyNameInput, MgNrInput, GivenNameInput, NameInput,
AddressInput, PlzInput, OrtInput, BillingOrtInput, AddressInput, PlzInput, OrtInput, BillingOrtInput,
BusinessSharesInput, BranchInput, DefaultKgInput BusinessSharesInput, BranchInput, DefaultKgInput
]; ];
@ -130,7 +130,7 @@ namespace Elwig.Windows {
var dict = members.AsParallel() var dict = members.AsParallel()
.ToDictionary(m => m, m => m.SearchScore(filter)) .ToDictionary(m => m, m => m.SearchScore(filter))
.OrderByDescending(a => a.Value) .OrderByDescending(a => a.Value)
.ThenBy(a => a.Key.FamilyName) .ThenBy(a => a.Key.Name)
.ThenBy(a => a.Key.GivenName) .ThenBy(a => a.Key.GivenName)
.ThenBy(a => a.Key.MgNr); .ThenBy(a => a.Key.MgNr);
var threshold = dict.Select(a => a.Value).Max() * 3 / 4; var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
@ -140,7 +140,7 @@ namespace Elwig.Windows {
.ToList(); .ToList();
} else { } else {
members = members members = members
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToList(); .ToList();
@ -738,7 +738,7 @@ namespace Elwig.Windows {
return; return;
var oldMember = (await ctx.Members.FindAsync(mgnr))!; var oldMember = (await ctx.Members.FindAsync(mgnr))!;
var newName = $"{ViewModel.FamilyName?.Replace('ß', 'ẞ').ToUpper()} " + var newName = $"{ViewModel.Name?.Replace('ß', 'ẞ').ToUpper()} " +
$"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" + $"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" +
$"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" + $"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" +
$"{ViewModel.Suffix}{(!string.IsNullOrEmpty(ViewModel.Suffix) ? " " : "")}"; $"{ViewModel.Suffix}{(!string.IsNullOrEmpty(ViewModel.Suffix) ? " " : "")}";
@ -782,7 +782,7 @@ namespace Elwig.Windows {
if (ViewModel.SelectedMember is not Member m) return; if (ViewModel.SelectedMember is not Member m) return;
var url = "https://www.easy-cert.com/htm/suchergebnis.htm?" + var url = "https://www.easy-cert.com/htm/suchergebnis.htm?" +
//$"CustomerNumber={m.LfbisNr}&" + //$"CustomerNumber={m.LfbisNr}&" +
$"Name={(m.BillingAddress?.Name ?? m.Name).Replace(' ', '+')}&" + $"Name={(m.BillingAddress?.FullName ?? m.FullName).Replace(' ', '+')}&" +
$"PostalCode={(m.BillingAddress?.PostalDest ?? m.PostalDest).AtPlz?.Plz}"; $"PostalCode={(m.BillingAddress?.PostalDest ?? m.PostalDest).AtPlz?.Plz}";
Process.Start(new ProcessStartInfo(url) { Process.Start(new ProcessStartInfo(url) {
UseShellExecute = true, UseShellExecute = true,
@ -811,5 +811,26 @@ namespace Elwig.Windows {
} }
CheckBox_Changed(sender, evt); CheckBox_Changed(sender, evt);
} }
private void JuridicalPersonInput_Changed(object sender, RoutedEventArgs evt) {
CheckBox_Changed(sender, evt);
if (ViewModel.IsJuridicalPerson) {
ViewModel.PersonalNameVisibility = Visibility.Hidden;
ViewModel.JuridicalNameVisibility = Visibility.Visible;
NameInput.Margin = new(0, 40, 10, 0);
NameInput.SetValue(Grid.ColumnSpanProperty, 3);
BirthdayLabel.Content = "Gründung:";
DeceasedInput.Content = "Aufgelöst";
} else {
ViewModel.JuridicalNameVisibility = Visibility.Hidden;
ViewModel.PersonalNameVisibility = Visibility.Visible;
NameInput.Margin = new(0, 70, 0, 0);
NameInput.SetValue(Grid.ColumnSpanProperty, 1);
BirthdayLabel.Content = "Geburtstag:";
DeceasedInput.Content = "Verstorben";
}
ValidateRequiredInputs();
UpdateButtons();
}
} }
} }

View File

@ -74,7 +74,7 @@
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Nachname" Binding="{Binding FamilyName}" Width="100"/> <DataGridTextColumn Header="Nachname" Binding="{Binding Name}" Width="100"/>
<DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="90"/> <DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="90"/>
<DataGridTextColumn Header="GA" Binding="{Binding BusinessShares, StringFormat='{}{0:N0} '}" Width="35"> <DataGridTextColumn Header="GA" Binding="{Binding BusinessShares, StringFormat='{}{0:N0} '}" Width="35">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>

View File

@ -45,12 +45,12 @@ namespace Elwig.Windows {
var members = await ctx.Members var members = await ctx.Members
.Select(m => new { .Select(m => new {
m.MgNr, m.MgNr,
m.FamilyName, m.Name,
m.GivenName, m.GivenName,
m.BusinessShares, m.BusinessShares,
m.IsActive, m.IsActive,
}) })
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToListAsync(); .ToListAsync();
@ -70,7 +70,7 @@ namespace Elwig.Windows {
var list = members var list = members
.Select(m => new { .Select(m => new {
m.MgNr, m.FamilyName, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.IsActive, m.IsActive,
BusinessShares = m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0), BusinessShares = m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0),
DeliveryObligation = (m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0)) * season.MinKgPerBusinessShare, DeliveryObligation = (m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0)) * season.MinKgPerBusinessShare,
@ -78,7 +78,7 @@ namespace Elwig.Windows {
Adjust = history.TryGetValue(m.MgNr, out int v2) ? (int?)v2 : null, Adjust = history.TryGetValue(m.MgNr, out int v2) ? (int?)v2 : null,
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.FamilyName, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.BusinessShares,
Weight = weight.GetValueOrDefault(m.MgNr, 0), Weight = weight.GetValueOrDefault(m.MgNr, 0),
OverUnder = weight.TryGetValue(m.MgNr, out int v1) ? OverUnder = weight.TryGetValue(m.MgNr, out int v1) ?
@ -89,7 +89,7 @@ namespace Elwig.Windows {
AdjustAmount = m.Adjust * -season.BusinessShareValue, AdjustAmount = m.Adjust * -season.BusinessShareValue,
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.FamilyName, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.BusinessShares, m.Weight, m.OverUnder,
PenaltyBs = m.OverUnder != null && m.OverUnder < 0 ? PenaltyBs = m.OverUnder != null && m.OverUnder < 0 ?
(season.PenaltyPerKg * m.OverUnder ?? 0) + (season.PenaltyPerKg * m.OverUnder ?? 0) +
@ -106,7 +106,7 @@ namespace Elwig.Windows {
Custom = CustomPayments!.GetValueOrDefault(m.MgNr, null)?.Amount, Custom = CustomPayments!.GetValueOrDefault(m.MgNr, null)?.Amount,
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.FamilyName, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.BusinessShares, m.Weight, m.OverUnder,
PenaltyBs = m.PenaltyBs == null || m.PenaltyBs == 0 ? (decimal?)null : Math.Round((decimal)m.PenaltyBs, 2), PenaltyBs = m.PenaltyBs == null || m.PenaltyBs == 0 ? (decimal?)null : Math.Round((decimal)m.PenaltyBs, 2),
PenaltyAc = m.PenaltyAc == null ? (decimal?)null : Math.Round((decimal)m.PenaltyAc, 2), PenaltyAc = m.PenaltyAc == null ? (decimal?)null : Math.Round((decimal)m.PenaltyAc, 2),
@ -115,13 +115,13 @@ namespace Elwig.Windows {
m.Custom m.Custom
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.FamilyName, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.BusinessShares, m.Weight, m.OverUnder,
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.Custom, m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.Custom,
Total = (m.PenaltyBs ?? 0) + (m.PenaltyAc ?? 0) + (m.AdjustAmount ?? 0) + (m.Custom ?? 0), Total = (m.PenaltyBs ?? 0) + (m.PenaltyAc ?? 0) + (m.AdjustAmount ?? 0) + (m.Custom ?? 0),
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.FamilyName, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.BusinessShares, m.Weight, m.OverUnder,
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.Custom, m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.Custom,
m.Total, m.Total,
@ -130,7 +130,7 @@ namespace Elwig.Windows {
}) })
.Where(m => m.OverUnder != null || m.Adjust != null || m.PenaltyBs != null || m.PenaltyAc != null || m.Custom != null) .Where(m => m.OverUnder != null || m.Adjust != null || m.PenaltyBs != null || m.PenaltyAc != null || m.Custom != null)
.OrderByDescending(m => m.OverUnder ?? 0) .OrderByDescending(m => m.OverUnder ?? 0)
.ThenBy(m => m.FamilyName) .ThenBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToList(); .ToList();
@ -146,7 +146,7 @@ namespace Elwig.Windows {
NonDeliveries.Text = $"{list.Count(r => r.Weight == 0):N0}"; NonDeliveries.Text = $"{list.Count(r => r.Weight == 0):N0}";
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
.OrderBy(m => m.FamilyName) .OrderBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
.ThenBy(m => m.MgNr) .ThenBy(m => m.MgNr)
.ToListAsync()); .ToListAsync());

View File

@ -36,7 +36,7 @@ namespace Tests.E2ETests {
Window.FindElement(By.WpfId("MgNrInput")).SendKeys("9999"); Window.FindElement(By.WpfId("MgNrInput")).SendKeys("9999");
Window.FindElement(By.WpfId("GivenNameInput")).SendKeys("Norbert"); Window.FindElement(By.WpfId("GivenNameInput")).SendKeys("Norbert");
Window.FindElement(By.WpfId("FamilyNameInput")).SendKeys("Neuling"); Window.FindElement(By.WpfId("NameInput")).SendKeys("Neuling");
Window.FindElement(By.WpfId("PrefixInput")).SendKeys("Ing."); Window.FindElement(By.WpfId("PrefixInput")).SendKeys("Ing.");
Window.FindElement(By.WpfId("SuffixInput")).SendKeys("jun."); Window.FindElement(By.WpfId("SuffixInput")).SendKeys("jun.");
Window.FindElement(By.WpfId("BirthdayInput")).SendKeys("1987"); Window.FindElement(By.WpfId("BirthdayInput")).SendKeys("1987");

View File

@ -66,7 +66,7 @@ INSERT INTO wb_kg (kgnr, glnr) VALUES
(15216, 2), (15216, 2),
(15224, 2); (15224, 2);
INSERT INTO member (mgnr, given_name, family_name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr, iban, lfbis_nr, ustid_nr) VALUES INSERT INTO member (mgnr, given_name, name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr, iban, lfbis_nr, ustid_nr) VALUES
(101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109, 'AT811234567890123457', '0123463', NULL ), (101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109, 'AT811234567890123457', '0123463', NULL ),
(102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684'), (102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684'),
(103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224, 'AT271234567890123459', '0123480', NULL ), (103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224, 'AT271234567890123459', '0123480', NULL ),

View File

@ -1 +1 @@
curl --fail -s -L "https://elwig.at/files/create.sql?v=26" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql" curl --fail -s -L "https://elwig.at/files/create.sql?v=27" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"