[#20][#80] Elwig: Update member_history and add different types of shares
Test / Run tests (push) Successful in 2m0s

This commit is contained in:
2026-07-01 11:01:15 +02:00
parent 4ebe07f579
commit feee6ad1ec
37 changed files with 858 additions and 264 deletions
+87 -8
View File
@@ -59,6 +59,7 @@ namespace Elwig.Helpers.Export {
List<BillingAddr> BillingAddresses,
List<MemberTelNr> TelephoneNumbers,
List<MemberEmailAddr> EmailAddresses,
List<MemberHistory> MemberHistory,
List<AreaCom> AreaCommitments,
List<AreaComContract> Contracts,
List<WbRd> Riede,
@@ -76,7 +77,7 @@ namespace Elwig.Helpers.Export {
foreach (var filename in filenames) {
try {
data.Add(new([], [], [], [], [], [], [], new([], [], [], [], [], new() {
data.Add(new([], [], [], [], [], [], [], new([], [], [], [], [], [], new() {
["member"] = [],
["area_commitment_contract"] = [],
["area_commitment"] = [],
@@ -142,6 +143,17 @@ namespace Elwig.Helpers.Export {
}
}
var historyJson = zip.GetEntry("member_history.json");
if (historyJson != null) {
using var reader = new StreamReader(historyJson.Open(), Utils.UTF8);
string? line;
while ((line = await reader.ReadLineAsync()) != null) {
var obj = JsonNode.Parse(line)!.AsObject();
var h = obj.ToMemberHistory();
r.MemberHistory.Add(h);
}
}
// legacy area commitments
var areaComsJson = zip.GetEntry("area_commitments.json");
if (areaComsJson != null) {
@@ -222,7 +234,7 @@ namespace Elwig.Helpers.Export {
var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, areaCommitments, contracts, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, history, areaCommitments, contracts, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
var branch = branches[meta.ZwstId];
var device = meta.Device;
@@ -234,6 +246,12 @@ namespace Elwig.Helpers.Export {
.Select(k => k.KgNr)
.ToListAsync();
var histNrs = history.Select(h => h.HistNr).ToList();
var duplicateHistNrs = await ctx.MemberHistory
.Where(h => histNrs.Contains(h.HistNr))
.Select(h => h.HistNr)
.ToListAsync();
var mgnrs = members.Select(m => m.MgNr).ToList();
var duplicateMgNrs = await ctx.Members
.Where(m => mgnrs.Contains(m.MgNr))
@@ -323,6 +341,11 @@ namespace Elwig.Helpers.Export {
importedMembers.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, members.Count - n - o, meta.MemberFilters));
}
if (importDuplicateMembers || importNewMembers) {
ctx.UpdateRange(history.Where(h => duplicateHistNrs.Contains(h.HistNr)));
ctx.AddRange(history.Where(h => !duplicateHistNrs.Contains(h.HistNr)));
}
if (importDuplicateContracts) {
ctx.RemoveRange(ctx.AreaCommitments.IgnoreAutoIncludes().Where(c => duplicateFbNrs.Contains(c.FbNr)));
ctx.UpdateRange(contracts.Where(c => duplicateFbNrs.Contains(c.FbNr)));
@@ -379,7 +402,9 @@ namespace Elwig.Helpers.Export {
importedDeliveries.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, deliveries.Count - n - o, meta.DeliveryFilters));
}
await ctx.Database.ExecuteSqlAsync($"UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS'");
await ctx.SaveChangesAsync();
await ctx.Database.ExecuteSqlAsync($"UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS'");
var primaryKeys = new Dictionary<string, string>() {
["member"] = "mgnr, 0, 0",
@@ -442,16 +467,18 @@ namespace Elwig.Helpers.Export {
$"{branch} (Gerät {device}) {(duplicate ? "überschrieben" : "importiert")} werden?", true);
}
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
return new ElwigExport {
Members = (members, filters),
History = (history, ["von exportierten Mitgliedern"]),
WbKgs = (wbKgs, ["von exportierten Mitgliedern"]),
}.Export(filename);
}
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
return new ElwigExport {
Members = (members, filters),
History = (history, ["von exportierten Mitgliedern"]),
AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
WbKgs = (wbKgs, ["von exportierten Mitgliedern und Flächenbindungen"]),
}.Export(filename);
@@ -467,6 +494,7 @@ namespace Elwig.Helpers.Export {
public class ElwigExport {
public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
public (IEnumerable<MemberHistory> History, IEnumerable<string> Filters)? History { get; set; }
public (IEnumerable<AreaComContract> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; }
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
@@ -486,17 +514,21 @@ namespace Elwig.Helpers.Export {
["zwstid"] = App.ZwstId,
["device"] = Environment.MachineName,
};
if (WbKgs != null) {
if (WbKgs != null)
obj["wb_kgs"] = new JsonObject {
["count"] = WbKgs.Value.WbKgs.Count(),
["filters"] = new JsonArray(WbKgs.Value.Filters.Select(f => (JsonNode)f).ToArray()),
};
}
if (Members != null)
obj["members"] = new JsonObject {
["count"] = Members.Value.Members.Count(),
["filters"] = new JsonArray(Members.Value.Filters.Select(f => (JsonNode)f).ToArray()),
};
if (History != null)
obj["member_history"] = new JsonObject {
["count"] = History.Value.History.Count(),
["filters"] = new JsonArray(History.Value.Filters.Select(f => (JsonNode)f).ToArray()),
};
if (AreaComs != null)
obj["area_commitment_contracts"] = new JsonObject {
["count"] = AreaComs.Value.AreaComs.Count(),
@@ -527,6 +559,13 @@ namespace Elwig.Helpers.Export {
await writer.WriteLineAsync(m.ToJson().ToJsonString(Utils.JsonOpts));
}
}
if (History != null) {
var json = zip.CreateEntry("member_history.json", CompressionLevel.SmallestSize);
using var writer = new StreamWriter(json.Open(), Utils.UTF8);
foreach (var h in History.Value.History) {
await writer.WriteLineAsync(h.ToJson().ToJsonString(Utils.JsonOpts));
}
}
if (AreaComs != null) {
var json = zip.CreateEntry("area_commitment_contracts.json", CompressionLevel.SmallestSize);
using var writer = new StreamWriter(json.Open(), Utils.UTF8);
@@ -585,7 +624,10 @@ namespace Elwig.Helpers.Export {
["birthday"] = m.Birthday,
["entry_date"] = m.EntryDate != null ? $"{m.EntryDate:yyyy-MM-dd}" : null,
["exit_date"] = m.ExitDate != null ? $"{m.ExitDate:yyyy-MM-dd}" : null,
["business_shares"] = m.BusinessShares,
["shares"] = m.Shares,
["shares_red"] = m.SharesRed,
["shares_white"] = m.SharesWhite,
["shares_dormant"] = m.SharesDormant,
["accounting_nr"] = m.AccountingNr,
["zwstid"] = m.ZwstId,
["lfbis_nr"] = m.LfbisNr,
@@ -654,7 +696,10 @@ namespace Elwig.Helpers.Export {
Birthday = json["birthday"]?.AsValue().GetValue<string>(),
EntryDateString = json["entry_date"]?.AsValue().GetValue<string>(),
ExitDateString = json["exit_date"]?.AsValue().GetValue<string>(),
BusinessShares = json["business_shares"]?.AsValue().GetValue<int>() ?? 0,
Shares = json["shares"]?.AsValue().GetValue<int>() ?? json["business_shares"]?.AsValue().GetValue<int>() ?? 0,
SharesRed = json["shares_red"]?.AsValue().GetValue<int>() ?? 0,
SharesWhite = json["shares_white"]?.AsValue().GetValue<int>() ?? 0,
SharesDormant = json["shares_dormant"]?.AsValue().GetValue<int>() ?? 0,
AccountingNr = json["accounting_nr"]?.AsValue().GetValue<string>(),
ZwstId = json["zwstid"]?.AsValue().GetValue<string>(),
LfbisNr = json["lfbis_nr"]?.AsValue().GetValue<string>(),
@@ -699,6 +744,40 @@ namespace Elwig.Helpers.Export {
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
}
public static JsonObject ToJson(this MemberHistory h) {
return new JsonObject {
["histnr"] = h.HistNr,
["from_mgnr"] = h.FromMgNr,
["from_type"] = h.FromType,
["to_mgnr"] = h.ToMgNr,
["to_type"] = h.ToType,
["date"] = h.DateString,
["reason"] = h.Reason,
["source"] = h.Source,
["shares"] = h.Shares,
["value_per_share"] = h.ValuePerShare,
["currency"] = h.CurrencyCode,
["comment"] = h.Comment,
};
}
public static MemberHistory ToMemberHistory(this JsonNode json) {
return new MemberHistory {
HistNr = json["histnr"]!.AsValue().GetValue<int>(),
FromMgNr = json["from_mgnr"]?.AsValue().GetValue<int>(),
FromType = json["from_type"]?.AsValue().GetValue<int>(),
ToMgNr = json["to_mgnr"]?.AsValue().GetValue<int>(),
ToType = json["to_type"]?.AsValue().GetValue<int>(),
DateString = json["date"]!.AsValue().GetValue<string>(),
Reason = json["reason"]!.AsValue().GetValue<string>(),
Source = json["source"]!.AsValue().GetValue<string>(),
Shares = json["shares"]!.AsValue().GetValue<int>(),
ValuePerShare = json["value_per_share"]?.AsValue().GetValue<decimal>(),
CurrencyCode = json["currency"]?.AsValue().GetValue<string>(),
Comment = json["comment"]?.AsValue().GetValue<string>(),
};
}
public static JsonObject ToJson(this AreaComContract c) {
return new JsonObject {
["fbnr"] = c.FbNr,