[#20] MemberAdminWindow: Add MemberBusinessSharesAdminWindow to manage member shares

This commit is contained in:
2026-07-08 22:04:20 +02:00
parent 1169ba5101
commit 918555f2b8
29 changed files with 987 additions and 153 deletions
+5
View File
@@ -0,0 +1,5 @@
namespace Elwig.Models {
public enum BusinessShareType {
Normal = 1, Red = 2, White = 3, Dormant = 9,
}
}
+3 -5
View File
@@ -19,7 +19,7 @@ namespace Elwig.Models.Dtos {
("Locality", "Ort", null, 60),
("DefaultKg", "Stammgemeinde", null, 60),
("Branch", "Zweigstelle", null, 40),
("SharesTotal", "GA", null, 10),
("SharesActive", "GA", null, 10),
("BillingName", "Rechnungsname", null, 60),
("BillingAddress", "Rechnungsadresse", null, 60),
("BillingPlz", "PLZ", null, 10),
@@ -69,8 +69,7 @@ namespace Elwig.Models.Dtos {
public int Shares;
public int SharesRed;
public int SharesWhite;
public int SharesDormant;
public int SharesTotal;
public int SharesActive;
public string Address;
public int Plz;
public string Locality;
@@ -105,8 +104,7 @@ namespace Elwig.Models.Dtos {
Shares = m.Shares;
SharesRed = m.SharesRed;
SharesWhite = m.SharesWhite;
SharesDormant = m.SharesDormant;
SharesTotal = Shares + SharesRed + SharesWhite + SharesDormant;
SharesActive = Shares + SharesRed + SharesWhite;
Address = m.Address;
Plz = m.PostalDest.AtPlz!.Plz;
Locality = m.PostalDest.AtPlz!.Ort.Name;
+2 -2
View File
@@ -42,6 +42,8 @@ namespace Elwig.Models.Entities {
[NotMapped]
public string ShortName => (!string.IsNullOrWhiteSpace(GivenName) ? $"{GivenName} " : "") + Name;
[NotMapped]
public string FullAdministrativeName => $"{AdministrativeName} ({MgNr})";
[NotMapped]
public string AdministrativeName => AdministrativeName1 + (!string.IsNullOrWhiteSpace(AdministrativeName2) ? $" {AdministrativeName2}" : "");
[NotMapped]
public string AdministrativeName1 => IsJuridicalPerson ? Name : Name.Replace('ß', 'ẞ').ToUpper();
@@ -79,8 +81,6 @@ namespace Elwig.Models.Entities {
[Column("shares_dormant")]
public int SharesDormant { get; set; }
[NotMapped]
public int SharesTotal => Shares + SharesRed + SharesWhite + SharesDormant;
[NotMapped]
public int SharesActive => Shares + SharesRed + SharesWhite;
+68 -9
View File
@@ -6,29 +6,69 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace Elwig.Models.Entities {
[Table("member_history"), PrimaryKey("HistNr")]
public class MemberHistory {
public const string REASON_PURCHASE = "purchase"; // Kauf
public const string REASON_CONVERT = "convert"; // Änderung
public const string REASON_TRANSFER = "transfer"; // Übertragung
public const string REASON_PRESCRIPTION = "prescription"; // Vorschreibung
public const string REASON_EXCLUSION = "exclusion"; // Ausschluss
public const string REASON_DECEASED = "deceased"; // Tod
public const string REASON_RETIREMENT = "retirement"; // Kündigung/stilllegen
public const string REASON_PAYOUT = "payout"; // Auszahlung
[Column("histnr")]
public int HistNr { get; set; }
[Column("from_mgnr")]
public int? FromMgNr { get; set; }
[Column("from_type")]
public int? FromType { get; set; }
public int? FromTypeValue { get; set; }
[NotMapped]
public BusinessShareType? FromType {
get => (BusinessShareType?)FromTypeValue;
set => FromTypeValue = (int?)value;
}
[Column("to_mgnr")]
public int? ToMgNr { get; set; }
[Column("to_type")]
public int? ToType { get; set; }
[Column("date")]
public required string DateString { get; set; }
public int? ToTypeValue { get; set; }
[NotMapped]
public DateOnly Date {
get => DateOnly.ParseExact(DateString, "yyyy-MM-dd");
public BusinessShareType? ToType {
get => (BusinessShareType?)ToTypeValue;
set => ToTypeValue = (int?)value;
}
[Column("date_notice")]
public required string DateNoticeString { get; set; }
[NotMapped]
public DateOnly DateNotice {
get => DateOnly.ParseExact(DateNoticeString, "yyyy-MM-dd");
set => value.ToString("yyyy-MM-dd");
}
[Column("date_effective")]
public required string DateEffectiveString { get; set; }
[NotMapped]
public DateOnly DateEffective {
get => DateOnly.ParseExact(DateEffectiveString, "yyyy-MM-dd");
set => value.ToString("yyyy-MM-dd");
}
[Column("reason")]
public required string Reason { get; set; }
[NotMapped]
public string ReasonPretty => Reason switch {
REASON_PURCHASE => "Kauf",
REASON_CONVERT => "Änderung",
REASON_TRANSFER => "Übertragung",
REASON_PRESCRIPTION => "Vorschreibung",
REASON_EXCLUSION => "Ausschluss",
REASON_DECEASED => "Tod",
REASON_RETIREMENT => "Kündigung",
REASON_PAYOUT => "Auszahlung",
_ => Reason,
};
[Column("source")]
public required string Source { get; set; }
@@ -36,6 +76,9 @@ namespace Elwig.Models.Entities {
[Column("shares")]
public int Shares { get; set; }
[Column("signed")]
public bool MemberHasSigned { get; set; }
[Column("value_per_share")]
public long? ValuePerShareValue { get; set; }
[NotMapped]
@@ -56,11 +99,27 @@ namespace Elwig.Models.Entities {
[Column("comment")]
public string? Comment { get; set; }
public string FormatReasonPhrase(int mgnr) {
if (Reason == REASON_TRANSFER) {
if (FromMgNr == mgnr) {
return $"{ReasonPretty} an {ToMember?.FullAdministrativeName ?? "Nachfolger"}" + (Comment != null ? $", {Comment}" : "");
} else if (ToMgNr == mgnr) {
return $"{ReasonPretty} von {FromMember?.FullAdministrativeName ?? "Vorgänger"}" + (Comment != null ? $", {Comment}" : "");
}
}
return ReasonPretty + (Comment != null ? $", {Comment}" : "");
}
[NotMapped]
public int? PoVMgNr { get; set; }
[NotMapped]
public string PoVReasonPhrase => FormatReasonPhrase(PoVMgNr ?? 0);
[ForeignKey("FromMgNr")]
public virtual Member FromMember { get; private set; } = null!;
public virtual Member? FromMember { get; private set; } = null!;
[ForeignKey("ToMgNr")]
public virtual Member ToMember { get; private set; } = null!;
public virtual Member? ToMember { get; private set; } = null!;
[ForeignKey("CurrencyCode")]
public virtual Currency Currency { get; private set; } = null!;