[#20][#80] Elwig: Update member_history and add different types of shares
Test / Run tests (push) Successful in 2m52s
Test / Run tests (push) Successful in 2m52s
This commit is contained in:
@@ -14,6 +14,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Helpers {
|
||||
|
||||
public record struct MemberHistoryPoint(int Shares, int SharesRed, int SharesWhite, int SharesDormant);
|
||||
public record struct AreaComBucket(int Area, int Obligation, int Right);
|
||||
public record struct UnderDelivery(int Weight, int Diff);
|
||||
public record struct MemberBucket(string Name, int Area, int Obligation, int Right, int Delivery, int DeliveryStrict, int DeliveryTotal, int Payment);
|
||||
@@ -146,6 +147,7 @@ namespace Elwig.Helpers {
|
||||
.Include(s => s.Modifiers)
|
||||
.OrderByDescending(s => s.Year));
|
||||
|
||||
private readonly Dictionary<int, Dictionary<int, MemberHistoryPoint>> _memberHistory = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = [];
|
||||
@@ -230,6 +232,9 @@ namespace Elwig.Helpers {
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Schedule).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Variety).AutoInclude();
|
||||
modelBuilder.Entity<DeliverySchedule>().Navigation(s => s.Branch).AutoInclude();
|
||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.FromMember).AutoInclude();
|
||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.ToMember).AutoInclude();
|
||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.Currency).AutoInclude();
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
@@ -397,6 +402,22 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FetchMemberHistory(int year, SqliteConnection? cnx = null) {
|
||||
var ownCnx = cnx == null;
|
||||
cnx ??= await ConnectAsync();
|
||||
var history = new Dictionary<int, MemberHistoryPoint>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"SELECT mgnr, shares, shares_red, shares_white, shares_dormant FROM v_member_history WHERE year = {year}";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
var mgnr = reader.GetInt32(0);
|
||||
history[mgnr] = new(reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3), reader.GetInt32(4));
|
||||
}
|
||||
}
|
||||
if (ownCnx) await cnx.DisposeAsync();
|
||||
_memberHistory[year] = history;
|
||||
}
|
||||
|
||||
private async Task FetchMemberAreaCommitmentBuckets(int year, SqliteConnection? cnx = null) {
|
||||
var ownCnx = cnx == null;
|
||||
cnx ??= await ConnectAsync();
|
||||
@@ -487,6 +508,12 @@ namespace Elwig.Helpers {
|
||||
_memberUnderDelivery[year] = buckets;
|
||||
}
|
||||
|
||||
public async Task<MemberHistoryPoint> GetMemberHistory(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||
if (!_memberHistory.ContainsKey(year))
|
||||
await FetchMemberHistory(year, cnx);
|
||||
return _memberHistory[year].GetValueOrDefault(mgnr, new());
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||
if (!_memberAreaCommitmentBuckets.ContainsKey(year))
|
||||
await FetchMemberAreaCommitmentBuckets(year, cnx);
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Elwig.Helpers {
|
||||
public static class AppDbUpdater {
|
||||
|
||||
// Don't forget to update value in Tests/fetch-resources.bat!
|
||||
public static readonly int RequiredSchemaVersion = 39;
|
||||
public static readonly int RequiredSchemaVersion = 40;
|
||||
|
||||
private static int VersionOffset = 0;
|
||||
|
||||
|
||||
@@ -50,45 +50,29 @@ namespace Elwig.Helpers.Billing {
|
||||
""");
|
||||
}
|
||||
|
||||
public async Task AutoAdjustBusinessShares(DateOnly date, int allowanceKg = 0, double allowanceBs = 0, int allowanceKgPerBs = 0, double allowanceRel = 0, int addMinBs = 1) {
|
||||
if (addMinBs < 1) addMinBs = 1;
|
||||
public async Task AutoAdjustBusinessShares(DateOnly date, int allowanceKg = 0, double allowanceShares = 0, int allowanceKgPerShare = 0, double allowanceRel = 0, int addMinShares = 1) {
|
||||
if (addMinShares < 1) addMinShares = 1;
|
||||
using var cnx = await AppDbContext.ConnectAsync();
|
||||
await cnx.ExecuteBatch($"""
|
||||
UPDATE member
|
||||
SET business_shares = member.business_shares - h.business_shares
|
||||
FROM member_history h
|
||||
WHERE h.date = '{Year}-11-30' AND h.type = 'auto' AND h.mgnr = member.mgnr AND member.active;
|
||||
|
||||
INSERT INTO member_history (mgnr, date, type, business_shares)
|
||||
SELECT u.mgnr,
|
||||
'{date:yyyy-MM-dd}',
|
||||
'auto',
|
||||
CEIL((u.diff - {allowanceKg}.0 - {allowanceKgPerBs}.0 * u.business_shares) / s.max_kg_per_bs
|
||||
- {allowanceBs.ToString(CultureInfo.InvariantCulture)}
|
||||
- {allowanceRel.ToString(CultureInfo.InvariantCulture)} * u.business_shares) AS bs
|
||||
DELETE FROM member_history WHERE source = 'elwig' AND reason = 'auto' AND SUBSTR(date, 1, 4) = '{Year}';
|
||||
INSERT INTO member_history (histnr, from_mgnr, from_type, to_mgnr, to_type, date, reason, source, shares, value_per_share, currency)
|
||||
SELECT COALESCE((SELECT MAX(histnr) AS histnr FROM member_history), 0) + ROW_NUMBER() OVER(ORDER BY m.mgnr),
|
||||
NULL, NULL, u.mgnr, 1, '{date:yyyy-MM-dd}', 'auto', 'elwig',
|
||||
CEIL((u.diff - {allowanceKg}.0 - {allowanceKgPerShare}.0 * u.shares) / s.max_kg_per_share
|
||||
- {allowanceShares.ToString(CultureInfo.InvariantCulture)}
|
||||
- {allowanceRel.ToString(CultureInfo.InvariantCulture)} * u.shares) AS adjust_shares,
|
||||
s.share_value / POW(10, s.precision - 2), s.currency
|
||||
FROM v_total_under_delivery u
|
||||
JOIN season s ON s.year = u.year
|
||||
JOIN member m ON m.mgnr = u.mgnr
|
||||
WHERE s.year = {Year} AND bs >= {addMinBs} AND m.active
|
||||
ON CONFLICT DO UPDATE
|
||||
SET business_shares = excluded.business_shares;
|
||||
|
||||
UPDATE member
|
||||
SET business_shares = member.business_shares + h.business_shares
|
||||
FROM member_history h
|
||||
WHERE h.date = '{Year}-11-30' AND h.type = 'auto' AND h.mgnr = member.mgnr;
|
||||
WHERE s.year = {Year} AND adjust_shares >= {addMinShares} AND m.active
|
||||
""");
|
||||
}
|
||||
|
||||
public async Task UnAdjustBusinessShares() {
|
||||
using var cnx = await AppDbContext.ConnectAsync();
|
||||
await cnx.ExecuteBatch($"""
|
||||
UPDATE member
|
||||
SET business_shares = member.business_shares - h.business_shares
|
||||
FROM member_history h
|
||||
WHERE h.date = '{Year}-11-30' AND h.type = 'auto' AND h.mgnr = member.mgnr AND member.active;
|
||||
|
||||
DELETE FROM member_history WHERE date = '{Year}-11-30' AND type = 'auto';
|
||||
DELETE FROM member_history WHERE source = 'elwig' AND reason = 'auto' AND SUBSTR(date, 1, 4) = '{Year}';
|
||||
""");
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Elwig.Helpers.Billing {
|
||||
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
|
||||
ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) +
|
||||
ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) +
|
||||
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) +
|
||||
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0)) +
|
||||
IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0)
|
||||
AS modifiers,
|
||||
IIF(lc.amount < 0, 0, lc.modifiers) AS prev_modifiers
|
||||
@@ -137,11 +137,11 @@ namespace Elwig.Helpers.Billing {
|
||||
await cnx.ExecuteBatch($"""
|
||||
INSERT INTO payment_member (year, avnr, mgnr, net_amount, mod_abs, mod_rel)
|
||||
SELECT c.year, {AvNr}, s.mgnr, 0,
|
||||
ROUND(s.sum * COALESCE(m.abs, 0)),
|
||||
ROUND(s.weight_total * COALESCE(m.abs, 0)),
|
||||
COALESCE(m.rel, 0)
|
||||
FROM (SELECT {Year} AS year, m.mgnr,
|
||||
ROUND(AVG(COALESCE(a.sum, b.sum)) * {multiplier}) AS baseline,
|
||||
COUNT(*) = {lastYears} AND MIN(COALESCE(a.sum, b.sum)) > 0 AS allowed
|
||||
ROUND(AVG(COALESCE(a.weight_total, b.weight_total)) * {multiplier}) AS baseline,
|
||||
COUNT(*) = {lastYears} AND MIN(COALESCE(a.weight_total, b.weight_total)) > 0 AS allowed
|
||||
FROM member m
|
||||
LEFT JOIN v_stat_member a ON a.mgnr = m.mgnr
|
||||
FULL OUTER JOIN v_stat_member b ON b.mgnr = m.predecessor_mgnr AND b.year = a.year AND {(includePredecessor ? "TRUE" : "FALSE")}
|
||||
@@ -150,7 +150,7 @@ namespace Elwig.Helpers.Billing {
|
||||
HAVING allowed) c
|
||||
JOIN v_stat_member s ON (s.year, s.mgnr) = (c.year, c.mgnr)
|
||||
LEFT JOIN modifier m ON m.year = c.year AND m.name LIKE '{modName}'
|
||||
WHERE sum >= baseline
|
||||
WHERE weight_total >= baseline
|
||||
ON CONFLICT DO UPDATE
|
||||
SET mod_abs = mod_abs + excluded.mod_abs,
|
||||
mod_rel = mod_rel + excluded.mod_rel
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Elwig.Helpers {
|
||||
public int ExportEbicsVersion;
|
||||
public int ExportEbicsAddress;
|
||||
|
||||
public (int? AllowanceKg, double? AllowanceBs, int? AllowanceKgPerBs, double? AllowancePercent, int? MinBs) AutoAdjustBs;
|
||||
public (int? AllowanceKg, double? AllowanceShares, int? AllowanceKgPerShare, double? AllowancePercent, int? MinShares) AutoAdjustShares;
|
||||
|
||||
public ClientParameters(AppDbContext ctx) : this(ctx.ClientParameters.ToDictionary(e => e.Param, e => e.Value)) { }
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
|
||||
var autoAdjust = (parameters.GetValueOrDefault("AUTOADJUST_BUSINESSSHARES") ?? "").Split(';');
|
||||
AutoAdjustBs = autoAdjust.Length == 5 ? (
|
||||
AutoAdjustShares = autoAdjust.Length == 5 ? (
|
||||
int.TryParse(autoAdjust[0], out var v1) ? v1 : null,
|
||||
double.TryParse(autoAdjust[1], out var v2) ? v2 : null,
|
||||
int.TryParse(autoAdjust[2], out var v3) ? v3 : null,
|
||||
@@ -235,9 +235,9 @@ namespace Elwig.Helpers {
|
||||
case 1: exportEbicsAddress = "LINES"; break;
|
||||
case 2: exportEbicsAddress = "FULL"; break;
|
||||
}
|
||||
string autoAdjust = $"{AutoAdjustBs.AllowanceKg};{AutoAdjustBs.AllowanceBs?.ToString(CultureInfo.InvariantCulture)};" +
|
||||
$"{AutoAdjustBs.AllowanceKgPerBs};{AutoAdjustBs.AllowancePercent?.ToString(CultureInfo.InvariantCulture)};" +
|
||||
$"{AutoAdjustBs.MinBs}";
|
||||
string autoAdjust = $"{AutoAdjustShares.AllowanceKg};{AutoAdjustShares.AllowanceShares?.ToString(CultureInfo.InvariantCulture)};" +
|
||||
$"{AutoAdjustShares.AllowanceKgPerShare};{AutoAdjustShares.AllowancePercent?.ToString(CultureInfo.InvariantCulture)};" +
|
||||
$"{AutoAdjustShares.MinShares}";
|
||||
return [
|
||||
("CLIENT_NAME_TOKEN", NameToken),
|
||||
("CLIENT_NAME_SHORT", NameShort),
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user