MemberAdminWindow: Add pending member movement export
This commit is contained in:
@@ -274,11 +274,11 @@ namespace Elwig.Documents {
|
|||||||
.AddCells(NewBusinessSharesCells(new()));
|
.AddCells(NewBusinessSharesCells(new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
var recorded = history.Aggregate(new MemberHistoryPoint(), (s, h) => new(
|
var recorded = history.Aggregate(new MemberHistoryPoint(), (s, h) => new(
|
||||||
s.Shares + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Normal ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Normal ? h.Shares : 0),
|
s.Shares + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Normal ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Normal && h.FromType == BusinessShareType.Normal ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Normal ? h.Shares : 0),
|
||||||
s.SharesRed + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Red ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Red ? h.Shares : 0),
|
s.SharesRed + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Red ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Red && h.FromType == BusinessShareType.Red ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Red ? h.Shares : 0),
|
||||||
s.SharesWhite + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.White ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.White ? h.Shares : 0),
|
s.SharesWhite + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.White ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.White && h.FromType == BusinessShareType.White ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.White ? h.Shares : 0),
|
||||||
s.SharesDormant + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Dormant ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Dormant ? h.Shares : 0)));
|
s.SharesDormant + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Dormant ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Dormant && h.FromType == BusinessShareType.Dormant ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Dormant ? h.Shares : 0)));
|
||||||
var cur = new MemberHistoryPoint(Member.Shares - recorded.Shares, Member.SharesRed - recorded.SharesRed, Member.SharesWhite - recorded.SharesWhite, Member.SharesDormant - recorded.SharesDormant);
|
var cur = new MemberHistoryPoint(Member.Shares - recorded.Shares, Member.SharesRed - recorded.SharesRed, Member.SharesWhite - recorded.SharesWhite, Member.SharesDormant - recorded.SharesDormant);
|
||||||
|
|
||||||
if (cur.Shares != 0 || cur.SharesRed != 0 || cur.SharesWhite != 0 || cur.SharesDormant != 0) {
|
if (cur.Shares != 0 || cur.SharesRed != 0 || cur.SharesWhite != 0 || cur.SharesDormant != 0) {
|
||||||
@@ -297,7 +297,7 @@ namespace Elwig.Documents {
|
|||||||
DateOnly? lastDate = null;
|
DateOnly? lastDate = null;
|
||||||
foreach (var row in history) {
|
foreach (var row in history) {
|
||||||
int s = 0, r = 0, w = 0, d = 0;
|
int s = 0, r = 0, w = 0, d = 0;
|
||||||
if (row.FromMgNr == Member.MgNr) {
|
if (row.FromMgNr == Member.MgNr && !(row.FromMgNr == row.ToMgNr && row.FromType == row.ToType)) {
|
||||||
switch (row.FromType) {
|
switch (row.FromType) {
|
||||||
case BusinessShareType.Normal: s -= row.Shares; break;
|
case BusinessShareType.Normal: s -= row.Shares; break;
|
||||||
case BusinessShareType.Red: r -= row.Shares; break;
|
case BusinessShareType.Red: r -= row.Shares; break;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Elwig.Models;
|
||||||
using Elwig.Models.Dtos;
|
using Elwig.Models.Dtos;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Services;
|
using Elwig.Services;
|
||||||
@@ -531,6 +532,44 @@ namespace Elwig.Helpers {
|
|||||||
return _memberHistory[year].GetValueOrDefault(mgnr, new());
|
return _memberHistory[year].GetValueOrDefault(mgnr, new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<int, SortedDictionary<DateOnly, MemberHistoryPoint>>> GetMemberHistory() {
|
||||||
|
var today = DateOnly.FromDateTime(DateTime.Today).AddDays(1);
|
||||||
|
var history = new Dictionary<int, SortedDictionary<DateOnly, MemberHistoryPoint>>();
|
||||||
|
|
||||||
|
var members = await Members.ToListAsync();
|
||||||
|
foreach (var m in members) {
|
||||||
|
history[m.MgNr] = new() {
|
||||||
|
[today] = new(m.Shares, m.SharesRed, m.SharesWhite, m.SharesDormant),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var hist = await MemberHistory.OrderByDescending(h => h.DateNoticeString).ToListAsync();
|
||||||
|
foreach (var h in hist) {
|
||||||
|
if (h.FromMgNr is int from) {
|
||||||
|
var latest = history[from].Last().Value;
|
||||||
|
switch (h.FromType) {
|
||||||
|
case BusinessShareType.Normal: latest.Shares += h.Shares; break;
|
||||||
|
case BusinessShareType.Red: latest.SharesRed += h.Shares; break;
|
||||||
|
case BusinessShareType.White: latest.SharesWhite += h.Shares; break;
|
||||||
|
case BusinessShareType.Dormant: latest.SharesDormant += h.Shares; break;
|
||||||
|
}
|
||||||
|
history[from][h.DateNotice] = latest;
|
||||||
|
}
|
||||||
|
if (h.ToMgNr is int to) {
|
||||||
|
var latest = history[to].Last().Value;
|
||||||
|
switch (h.ToType) {
|
||||||
|
case BusinessShareType.Normal: latest.Shares -= h.Shares; break;
|
||||||
|
case BusinessShareType.Red: latest.SharesRed -= h.Shares; break;
|
||||||
|
case BusinessShareType.White: latest.SharesWhite -= h.Shares; break;
|
||||||
|
case BusinessShareType.Dormant: latest.SharesDormant -= h.Shares; break;
|
||||||
|
}
|
||||||
|
history[to][h.DateNotice] = latest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, AreaCmtBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
public async Task<Dictionary<string, AreaCmtBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||||
if (!_memberAreaCommitmentBuckets.ContainsKey(year))
|
if (!_memberAreaCommitmentBuckets.ContainsKey(year))
|
||||||
await FetchMemberAreaCommitmentBuckets(year, cnx);
|
await FetchMemberAreaCommitmentBuckets(year, cnx);
|
||||||
|
|||||||
@@ -46,10 +46,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
await ExportAsync(rows);
|
await ExportAsync(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Export(int year) {
|
|
||||||
ExportAsync(year).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string FormatRow(Row row) {
|
public override string FormatRow(Row row) {
|
||||||
var (member, delivery) = row;
|
var (member, delivery) = row;
|
||||||
var (lfBisNr, familyName, name, billingName, address, plz, ort, vollablieferer, area) = member;
|
var (lfBisNr, familyName, name, billingName, address, plz, ort, vollablieferer, area) = member;
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
_writer.Dispose();
|
_writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask DisposeAsync() {
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
return _writer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExportAsync(IEnumerable<T> data, IProgress<double>? progress = null) {
|
public async Task ExportAsync(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
int count = data.Count() + 2, i = 0;
|
int count = data.Count() + 2, i = 0;
|
||||||
@@ -50,10 +45,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
progress?.Report(100.0);
|
progress?.Report(100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
|
||||||
ExportAsync(data, progress).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FormatRow(IEnumerable row) {
|
public string FormatRow(IEnumerable row) {
|
||||||
return string.Join(Separator, row);
|
return string.Join(Separator, row);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
Writer.Dispose();
|
Writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask DisposeAsync() {
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
return Writer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Export(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
|
||||||
ExportAsync(transactions, progress).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExportAsync(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
public async Task ExportAsync(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
||||||
if (transactions.Any(tx => tx.Amount < 0)) {
|
if (transactions.Any(tx => tx.Amount < 0)) {
|
||||||
throw new ArgumentException("Tranaction amount may not be negative");
|
throw new ArgumentException("Tranaction amount may not be negative");
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
namespace Elwig.Helpers.Export {
|
||||||
public interface IExporter<T> : IDisposable, IAsyncDisposable {
|
public interface IExporter<T> : IDisposable {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default file extension of the exported files to be used (whithout a preceding ".")
|
/// The default file extension of the exported files to be used (whithout a preceding ".")
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -14,7 +14,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The data to be exported</param>
|
/// <param name="data">The data to be exported</param>
|
||||||
/// <param name="progress">The progress object to report to</param>
|
/// <param name="progress">The progress object to report to</param>
|
||||||
void Export(IEnumerable<T> data, IProgress<double>? progress = null);
|
void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||||
|
ExportAsync(data, progress).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Asynchronosly export the given data to the given file.
|
/// Asynchronosly export the given data to the given file.
|
||||||
|
|||||||
@@ -109,8 +109,13 @@ namespace Elwig.Helpers.Export {
|
|||||||
<style:paragraph-properties fo:text-align="center"/>
|
<style:paragraph-properties fo:text-align="center"/>
|
||||||
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
||||||
</style:style>
|
</style:style>
|
||||||
|
<style:style style:name="sectionheader" style:family="table-cell" style:parent-style-name="default">
|
||||||
|
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/>
|
||||||
|
<style:paragraph-properties fo:text-align="left"/>
|
||||||
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" fo:font-size="14pt"/>
|
||||||
|
</style:style>
|
||||||
<style:style style:name="th" style:family="table-cell" style:parent-style-name="default">
|
<style:style style:name="th" style:family="table-cell" style:parent-style-name="default">
|
||||||
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle"/>
|
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle" fo:wrap-option="wrap"/>
|
||||||
<style:paragraph-properties fo:text-align="center"/>
|
<style:paragraph-properties fo:text-align="center"/>
|
||||||
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
||||||
</style:style>
|
</style:style>
|
||||||
@@ -211,35 +216,59 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Content.WriteAsync(
|
await Content.WriteAsync($"""
|
||||||
$" <table:table-row>\r\n" +
|
<table:table-row>
|
||||||
FormatCell(table.FullName, colSpan: totalSpan, style: "header") +
|
{FormatCell(table.FullName, colSpan: totalSpan, style: "header")}
|
||||||
$" </table:table-row>\r\n" +
|
</table:table-row>
|
||||||
$" <table:table-row>\r\n" +
|
<table:table-row>
|
||||||
FormatCell(table.Subtitle, colSpan: totalSpan, style: "subheader") +
|
{FormatCell(table.Subtitle, colSpan: totalSpan, style: "subheader")}
|
||||||
$" </table:table-row>\r\n" +
|
</table:table-row>
|
||||||
$" <table:table-row>\r\n" +
|
<table:table-row>
|
||||||
$" <table:table-cell table:number-columns-repeated=\"{totalSpan}\"/>\r\n" +
|
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||||
$" </table:table-row>\r\n" +
|
</table:table-row>
|
||||||
$" <table:table-row>\r\n");
|
""");
|
||||||
foreach (var (name, span, units) in table.ColumnNames.Zip(table.ColumnSpans, table.ColumnUnits)) {
|
|
||||||
var hasUnits = units.Length > 0;
|
|
||||||
await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
|
|
||||||
}
|
|
||||||
await Content.WriteAsync(" </table:table-row>\r\n <table:table-row>\r\n");
|
|
||||||
foreach (var (span, units) in table.ColumnSpans.Zip(table.ColumnUnits)) {
|
|
||||||
if (units.Length == 0) {
|
|
||||||
await Content.WriteAsync($" <table:covered-table-cell table:number-columns-repeated=\"{span}\"/>\r\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach (var u in units) {
|
|
||||||
await Content.WriteAsync(FormatCell(u == null ? null : $"[{u}]", style: "th"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await Content.WriteAsync(" </table:table-row>\r\n");
|
|
||||||
|
|
||||||
foreach (var row in table.GetData()) {
|
var firstSection = true;
|
||||||
await FormatRow(row, table.ColumnUnits, mergeSubRowCells);
|
foreach (var sec in table.GetData()) {
|
||||||
|
if (!firstSection) {
|
||||||
|
await Content.WriteAsync($"""
|
||||||
|
<table:table-row>
|
||||||
|
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||||
|
</table:table-row>
|
||||||
|
<table:table-row>
|
||||||
|
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||||
|
</table:table-row>
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
if (sec.Name != null) {
|
||||||
|
await Content.WriteAsync($"""
|
||||||
|
<table:table-row>
|
||||||
|
{FormatCell(sec.Name, colSpan: totalSpan, style: "sectionheader")}
|
||||||
|
</table:table-row>
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
await Content.WriteAsync(" <table:table-row>\r\n");
|
||||||
|
foreach (var (name, span, units) in table.ColumnNames.Zip(table.ColumnSpans, table.ColumnUnits)) {
|
||||||
|
var hasUnits = units.Length > 0;
|
||||||
|
await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
|
||||||
|
}
|
||||||
|
await Content.WriteAsync(" </table:table-row>\r\n <table:table-row>\r\n");
|
||||||
|
foreach (var (span, units) in table.ColumnSpans.Zip(table.ColumnUnits)) {
|
||||||
|
if (units.Length == 0) {
|
||||||
|
await Content.WriteAsync($" <table:covered-table-cell table:number-columns-repeated=\"{span}\"/>\r\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach (var u in units) {
|
||||||
|
await Content.WriteAsync(FormatCell(u == null ? null : $"[{u}]", style: "th"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Content.WriteAsync(" </table:table-row>\r\n");
|
||||||
|
|
||||||
|
foreach (var row in sec.Rows) {
|
||||||
|
await FormatRow(row, table.ColumnUnits, mergeSubRowCells);
|
||||||
|
}
|
||||||
|
firstSection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Content.WriteAsync(" </table:table>\r\n");
|
await Content.WriteAsync(" </table:table>\r\n");
|
||||||
@@ -314,7 +343,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
c = $"<{ct} office:value-type=\"float\" calcext:value-type=\"float\" office:value=\"{v.ToString(CultureInfo.InvariantCulture)}\"{add}><text:p>{data}</text:p></{ct}>";
|
c = $"<{ct} office:value-type=\"float\" calcext:value-type=\"float\" office:value=\"{v.ToString(CultureInfo.InvariantCulture)}\"{add}><text:p>{data}</text:p></{ct}>";
|
||||||
} else {
|
} else {
|
||||||
c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}><text:p>{SecurityElement.Escape(data.ToString())}</text:p></{ct}>";
|
var lines = string.Join("", data.ToString()?.Split('\n').Select(l => $"<text:p>{SecurityElement.Escape(l)}</text:p>") ?? []);
|
||||||
|
c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}>{lines}</{ct}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-columns-repeated=\"{colSpan - 1}\"/>\r\n" : "");
|
return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-columns-repeated=\"{colSpan - 1}\"/>\r\n" : "");
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
private readonly StreamWriter _writer;
|
private readonly StreamWriter _writer;
|
||||||
|
|
||||||
public VCard(string filename) : this(filename, Utils.UTF8) { }
|
public VCard(string filename) :
|
||||||
|
this(filename, Utils.UTF8) {
|
||||||
|
}
|
||||||
|
|
||||||
public VCard(string filename, Encoding encoding) {
|
public VCard(string filename, Encoding encoding) {
|
||||||
_writer = new StreamWriter(filename, false, encoding);
|
_writer = new StreamWriter(filename, false, encoding);
|
||||||
@@ -24,11 +26,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
_writer.Dispose();
|
_writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask DisposeAsync() {
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
return _writer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExportAsync(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
public async Task ExportAsync(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
int count = data.Count() + 1, i = 0;
|
int count = data.Count() + 1, i = 0;
|
||||||
@@ -58,10 +55,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
progress?.Report(100.0);
|
progress?.Report(100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Export(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
|
||||||
ExportAsync(data, progress).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string? Escape(string? text) {
|
private static string? Escape(string? text) {
|
||||||
return text?.Replace("\\", "\\\\").Replace(",", "\\,").Replace(";", "\\;").Replace("\n", "\\n").Replace("\r", "");
|
return text?.Replace("\\", "\\\\").Replace(",", "\\,").Replace(";", "\\;").Replace("\n", "\\n").Replace("\r", "");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@@ -9,13 +10,14 @@ namespace Elwig.Models.Dtos {
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string FullName { get; set; }
|
public string FullName { get; set; }
|
||||||
public string? Subtitle { get; set; }
|
public string? Subtitle { get; set; }
|
||||||
public IEnumerable<T> Rows { get; private set; }
|
public IEnumerable<(string? Name, IEnumerable<T> Rows)> Sections { get; private set; }
|
||||||
|
public IEnumerable<T> Rows => Sections.SelectMany(s => s.Rows);
|
||||||
public int RowNum => Rows.Count();
|
public int RowNum => Rows.Count();
|
||||||
public int ColNum => ColumnNames.Count();
|
public int ColNum => ColumnNames.Count();
|
||||||
|
|
||||||
public IEnumerable<(string, Type?)> ColumnDefs => _map.Select(m => (m.Item1, m.Item2?.PropertyType ?? m.Item3?.FieldType));
|
public IEnumerable<(string Name, Type? Type)> ColumnDefs => _map.Select(m => (m.Name, m.PInfo?.PropertyType ?? m.FInfo?.FieldType));
|
||||||
public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Item1);
|
public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Name);
|
||||||
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Item2);
|
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Type);
|
||||||
public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
|
public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
|
||||||
public IEnumerable<int> ColumnSpans { get; private set; }
|
public IEnumerable<int> ColumnSpans { get; private set; }
|
||||||
public IEnumerable<int?> ColumnWidths { get; private set; }
|
public IEnumerable<int?> ColumnWidths { get; private set; }
|
||||||
@@ -23,21 +25,25 @@ namespace Elwig.Models.Dtos {
|
|||||||
|
|
||||||
private readonly PropertyInfo[] _properties;
|
private readonly PropertyInfo[] _properties;
|
||||||
private readonly FieldInfo[] _fields;
|
private readonly FieldInfo[] _fields;
|
||||||
private readonly (string, PropertyInfo?, FieldInfo?)[] _map;
|
private readonly (string Name, PropertyInfo? PInfo, FieldInfo? FInfo)[] _map;
|
||||||
|
|
||||||
public DataTable(string name, string fullName, string subtitle, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
|
public DataTable(string name, string fullName, string subtitle, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
this(name, fullName, rows, colNames) {
|
this(name, fullName, sections, colNames) {
|
||||||
Subtitle = subtitle;
|
Subtitle = subtitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) {
|
public DataTable(string name, string fullName, string subtitle, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
|
this(name, fullName, subtitle, [(null, rows)], colNames) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) {
|
||||||
_fields = typeof(T).GetFields();
|
_fields = typeof(T).GetFields();
|
||||||
_properties = typeof(T).GetProperties();
|
_properties = typeof(T).GetProperties();
|
||||||
colNames ??= [.. _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null))];
|
colNames ??= [.. _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null))];
|
||||||
_map = [.. colNames.Select(n => (n.Item2, _properties.FirstOrDefault(p => p?.Name == n.Item1, null), _fields.FirstOrDefault(f => f?.Name == n.Item1, null)))];
|
_map = [.. colNames.Select(n => (n.Name, _properties.FirstOrDefault(p => p?.Name == n.Property, null), _fields.FirstOrDefault(f => f?.Name == n.Property, null)))];
|
||||||
Name = name;
|
Name = name;
|
||||||
FullName = fullName;
|
FullName = fullName;
|
||||||
Rows = rows;
|
Sections = sections;
|
||||||
ColumnFlatTypes = [.. ColumnTypes.SelectMany(type => {
|
ColumnFlatTypes = [.. ColumnTypes.SelectMany(type => {
|
||||||
var elType = type?.GetElementType();
|
var elType = type?.GetElementType();
|
||||||
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => (Type?)f.FieldType) :
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => (Type?)f.FieldType) :
|
||||||
@@ -50,44 +56,56 @@ namespace Elwig.Models.Dtos {
|
|||||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length :
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length :
|
||||||
1;
|
1;
|
||||||
})];
|
})];
|
||||||
ColumnWidths = [.. colNames.Select(c => c.Item4)];
|
ColumnWidths = [.. colNames.Select(c => c.Width)];
|
||||||
ColumnUnits = [.. colNames.Select(c => c.Item3?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? [])];
|
ColumnUnits = [.. colNames.Select(c => c.Unit?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? [])];
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)null))) {
|
this(name, fullName, [(null, rows)], colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||||
|
this(name, fullName, rows, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||||
|
this(name, fullName, rows, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
this(name, name, rows, colNames) {
|
this(name, name, rows, colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||||
this(name, name, rows, colNames) {
|
this(name, name, rows, colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||||
this(name, name, rows, colNames) {
|
this(name, name, rows, colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||||
this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)c.Item4))) {
|
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<(string, object?)> GetNamedRowData(T row) {
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||||
return _map.Select(i => (i.Item1, i.Item2?.GetValue(row) ?? i.Item3?.GetValue(row)));
|
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<object?> GetRowData(T row) {
|
protected IEnumerable<(string Name, object? Value)> GetNamedRowValues(T row) {
|
||||||
return GetNamedRowData(row).Select(i => i.Item2);
|
return _map.Select(i => (i.Name, i.PInfo?.GetValue(row) ?? i.FInfo?.GetValue(row)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IEnumerable<object?>> GetData() {
|
protected IEnumerable<object?> GetRowValues(T row) {
|
||||||
return Rows.Select(GetRowData);
|
return GetNamedRowValues(row).Select(i => i.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IEnumerable<(string, object?)>> GetNamedData() {
|
public IEnumerable<(string? Name, IEnumerable<IEnumerable<object?>> Rows)> GetData() {
|
||||||
return Rows.Select(GetNamedRowData);
|
return Sections.Select(s => (s.Name, s.Rows.Select(GetRowValues)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(string? Name, IEnumerable<IEnumerable<(string Name, object? Value)>> Rows)> GetNamedData() {
|
||||||
|
return Sections.Select(s => (s.Name, s.Rows.Select(GetNamedRowValues)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Models.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Elwig.Models.Dtos {
|
||||||
|
public class MemberMovementData : DataTable<MemberMovementDataRow> {
|
||||||
|
|
||||||
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
|
("Type", "\u2026 durch", null, 30),
|
||||||
|
("MgNr", "MgNr.", null, 12),
|
||||||
|
("Name1", "Name", null, 40),
|
||||||
|
("Name2", "Vorname", null, 25),
|
||||||
|
("Address", "Adresse", null, 50),
|
||||||
|
("Plz", "PLZ", null, 10),
|
||||||
|
("Locality", "Ort", null, 50),
|
||||||
|
("Date", "Datum", null, 20),
|
||||||
|
("SharesOld", "GA\nalt", null, 10),
|
||||||
|
("SharesDiff", "GA\nDiff.", null, 10),
|
||||||
|
("SharesNew", "GA\nneu", null, 10),
|
||||||
|
("Costs", "Kosten", "€", 15),
|
||||||
|
];
|
||||||
|
|
||||||
|
private MemberMovementData(string name, IEnumerable<(string? Name, IEnumerable<MemberMovementDataRow> Rows)> sections) :
|
||||||
|
base("Mitgl.-Bewegungen", name, sections, FieldNames) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemberMovementData FromMemberHistory(string name, IEnumerable<MemberHistory> rows, Dictionary<int, SortedDictionary<DateOnly, MemberHistoryPoint>> history) {
|
||||||
|
(string? Name, List<MemberMovementDataRow> Rows)[] sections = [
|
||||||
|
("Beitritt", []),
|
||||||
|
("Nachzeichnung (GA)", []),
|
||||||
|
("Überschreibung", []),
|
||||||
|
("Kündigung (GA)", []),
|
||||||
|
("Austritt", []),
|
||||||
|
];
|
||||||
|
foreach (var h in rows.OrderBy(r => r.DateNotice).ThenBy(r => r.ToMgNr).ThenBy(r => r.FromMgNr)) {
|
||||||
|
|
||||||
|
int cat;
|
||||||
|
if (h.ToMgNr == h.FromMgNr) {
|
||||||
|
// Umwandlung
|
||||||
|
if (h.ToType == BusinessShareType.Dormant) {
|
||||||
|
// Kündigung (GA)
|
||||||
|
cat = 3;
|
||||||
|
} else if (h.FromType == h.ToType) {
|
||||||
|
// Überschreibung
|
||||||
|
cat = 2;
|
||||||
|
} else {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
} else if (h.DateNotice <= h.ToMember?.EntryDate && h.DateNotice >= h.FromMember?.ExitDate) {
|
||||||
|
// Überschreibung
|
||||||
|
cat = 2;
|
||||||
|
} else if (h.DateNotice <= h.ToMember?.EntryDate) {
|
||||||
|
// Beitritt
|
||||||
|
cat = 0;
|
||||||
|
} else if (h.DateNotice >= h.FromMember?.ExitDate) {
|
||||||
|
// Austritt
|
||||||
|
cat = 4;
|
||||||
|
} else if (h.ToMember == null) {
|
||||||
|
// Auszahlung
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// Nachzeichnung (GA)
|
||||||
|
cat = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member a;
|
||||||
|
Member? b = null;
|
||||||
|
if (h.FromMember != null && h.ToMember != null) {
|
||||||
|
if (cat <= 1) {
|
||||||
|
a = h.ToMember;
|
||||||
|
b = h.FromMember;
|
||||||
|
} else {
|
||||||
|
a = h.FromMember;
|
||||||
|
b = h.ToMember;
|
||||||
|
}
|
||||||
|
} else if (h.FromMember != null) {
|
||||||
|
a = h.FromMember;
|
||||||
|
} else if (h.ToMember != null) {
|
||||||
|
a = h.ToMember;
|
||||||
|
} else {
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldA = history[a.MgNr].GetValueOrDefault(h.DateNotice);
|
||||||
|
var d = new MemberMovementDataRow {
|
||||||
|
Type = [h.ReasonPretty],
|
||||||
|
|
||||||
|
MgNr = [a.MgNr],
|
||||||
|
Name1 = [a.Name],
|
||||||
|
Name2 = [a.AdministrativeName2],
|
||||||
|
Address = [a.Address],
|
||||||
|
Plz = [a.PostalDest.AtPlz!.Plz],
|
||||||
|
Locality = [a.PostalDest.AtPlz.Ort.Name],
|
||||||
|
|
||||||
|
Date = h.DateNotice,
|
||||||
|
SharesOld = [oldA.Shares + oldA.SharesRed + oldA.SharesWhite],
|
||||||
|
SharesDiff = [cat != 3 && a == h.ToMember ? h.Shares : -h.Shares],
|
||||||
|
Costs = [h.FromMember == null ? h.TotalValue : null],
|
||||||
|
};
|
||||||
|
d.SharesNew = [d.SharesOld[^1] + (h.FromMgNr == h.ToMgNr ? 0 : d.SharesDiff[^1])];
|
||||||
|
|
||||||
|
if (b != null) {
|
||||||
|
var oldB = history[b.MgNr].GetValueOrDefault(h.DateNotice);
|
||||||
|
d.Type = [..d.Type, "\u2026 " + (cat <= 1 ? "von" : "an")];
|
||||||
|
|
||||||
|
d.MgNr = [.. d.MgNr, b.MgNr];
|
||||||
|
d.Name1 = [.. d.Name1, b.Name];
|
||||||
|
d.Name2 = [.. d.Name2, b.AdministrativeName2];
|
||||||
|
d.Address = [.. d.Address, b.Address];
|
||||||
|
d.Plz = [.. d.Plz, b.PostalDest.AtPlz!.Plz];
|
||||||
|
d.Locality = [.. d.Locality, b.PostalDest.AtPlz.Ort.Name];
|
||||||
|
|
||||||
|
d.SharesOld = [.. d.SharesOld, oldB.Shares + oldB.SharesRed + oldB.SharesWhite];
|
||||||
|
d.SharesDiff = [.. d.SharesDiff, b == h.ToMember ? h.Shares : -h.Shares];
|
||||||
|
d.SharesNew = [.. d.SharesNew, d.SharesOld[^1] + d.SharesDiff[^1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
sections[cat].Rows.Add(d);
|
||||||
|
}
|
||||||
|
return new MemberMovementData($"Mitglieder-Bewegungen {name}", sections.Select(s => (s.Name, (IEnumerable<MemberMovementDataRow>)s.Rows)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MemberMovementDataRow {
|
||||||
|
public string[] Type = [];
|
||||||
|
|
||||||
|
public int[] MgNr = [];
|
||||||
|
public string[] Name1 = [];
|
||||||
|
public string?[] Name2 = [];
|
||||||
|
public string[] Address = [];
|
||||||
|
public int[] Plz = [];
|
||||||
|
public string[] Locality = [];
|
||||||
|
|
||||||
|
public DateOnly Date;
|
||||||
|
public int?[] SharesOld = [];
|
||||||
|
public int[] SharesDiff = [];
|
||||||
|
public int?[] SharesNew = [];
|
||||||
|
public decimal?[] Costs = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -104,10 +104,10 @@ namespace Elwig.Models.Entities {
|
|||||||
|
|
||||||
public string FormatReasonPhrase(int mgnr) {
|
public string FormatReasonPhrase(int mgnr) {
|
||||||
if (Reason == REASON_TRANSFER) {
|
if (Reason == REASON_TRANSFER) {
|
||||||
if (FromMgNr == mgnr) {
|
if (ToMgNr == 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} von {FromMember?.FullAdministrativeName ?? "Vorgänger"}" + (Comment != null ? $", {Comment}" : "");
|
||||||
|
} else if (FromMgNr == mgnr) {
|
||||||
|
return $"{ReasonPretty} an {ToMember?.FullAdministrativeName ?? "Nachfolger"}" + (Comment != null ? $", {Comment}" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ReasonPretty + (Comment != null ? $", {Comment}" : "");
|
return ReasonPretty + (Comment != null ? $", {Comment}" : "");
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Export;
|
||||||
using Elwig.Models;
|
using Elwig.Models;
|
||||||
|
using Elwig.Models.Dtos;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.ViewModels;
|
using Elwig.ViewModels;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@@ -10,6 +12,10 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Services {
|
namespace Elwig.Services {
|
||||||
public static class MemberBusinessSharesService {
|
public static class MemberBusinessSharesService {
|
||||||
|
|
||||||
|
public enum ExportSubject {
|
||||||
|
Pending,
|
||||||
|
};
|
||||||
|
|
||||||
public static async Task InitInputs(this MemberBusinessSharesViewModel vm) {
|
public static async Task InitInputs(this MemberBusinessSharesViewModel vm) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
vm.DateNoticeString = $"{DateTime.Today:dd.MM.yyyy}";
|
vm.DateNoticeString = $"{DateTime.Today:dd.MM.yyyy}";
|
||||||
@@ -97,5 +103,19 @@ namespace Elwig.Services {
|
|||||||
await tx.CommitAsync();
|
await tx.CommitAsync();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task GenerateMemberMovements(ExportSubject subject, ExportMode mode) {
|
||||||
|
var today = DateTime.Today;
|
||||||
|
var filename = InteractionService.SaveFile($"Ausstehende Mitgl.-Bewegungen {today:dd.MM.yyyy}", $"MitglBewegungen_{today:yyyy-MM-dd}", "ods");
|
||||||
|
if (filename == null)
|
||||||
|
return;
|
||||||
|
await Utils.RunForeground(async () => {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
var hist = await ctx.MemberHistory.Where(h => !h.CompanyHasSigned).ToListAsync();
|
||||||
|
var data = MemberMovementData.FromMemberHistory($"Ausstehend ({today:dd.MM.yyyy})", hist, await ctx.GetMemberHistory());
|
||||||
|
using var ods = new OdsFile(filename);
|
||||||
|
await ods.AddTable(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@
|
|||||||
Click="Menu_CreditNote_Email_Click"/>
|
Click="Menu_CreditNote_Email_Click"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Mitgliederliste" x:Name="Menu_List">
|
<MenuItem Header="Mitgliederliste" x:Name="Menu_List">
|
||||||
<MenuItem x:Name="Menu_List_SaveActive" Header="...mit Aktiven speichern (Excel)"
|
<MenuItem x:Name="Menu_List_SaveActive" Header="...mit Aktiven speichern... (Excel)"
|
||||||
Click="Menu_List_SaveActive_Click" InputGestureText="Strg+L"/>
|
Click="Menu_List_SaveActive_Click" InputGestureText="Strg+L"/>
|
||||||
<MenuItem x:Name="Menu_List_ShowActive" Header="...mit Aktiven anzeigen (PDF)"
|
<MenuItem x:Name="Menu_List_ShowActive" Header="...mit Aktiven anzeigen (PDF)"
|
||||||
Click="Menu_List_ShowActive_Click" InputGestureText="Strg+O"/>
|
Click="Menu_List_ShowActive_Click" InputGestureText="Strg+O"/>
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
<MenuItem x:Name="Menu_List_PrintActive" Header="...mit Aktiven drucken"
|
<MenuItem x:Name="Menu_List_PrintActive" Header="...mit Aktiven drucken"
|
||||||
Click="Menu_List_PrintActive_Click" InputGestureText="Strg+Shift+O"/>
|
Click="Menu_List_PrintActive_Click" InputGestureText="Strg+Shift+O"/>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
<MenuItem x:Name="Menu_List_SaveFilters" Header="...aus Filtern speichern (Excel)"
|
<MenuItem x:Name="Menu_List_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
||||||
Click="Menu_List_SaveFilters_Click"/>
|
Click="Menu_List_SaveFilters_Click"/>
|
||||||
<MenuItem x:Name="Menu_List_ShowFilters" Header="...aus Filtern anzeigen (PDF)"
|
<MenuItem x:Name="Menu_List_ShowFilters" Header="...aus Filtern anzeigen (PDF)"
|
||||||
Click="Menu_List_ShowFilters_Click"/>
|
Click="Menu_List_ShowFilters_Click"/>
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
<MenuItem x:Name="Menu_List_PrintFilters" Header="...aus Filtern drucken"
|
<MenuItem x:Name="Menu_List_PrintFilters" Header="...aus Filtern drucken"
|
||||||
Click="Menu_List_PrintFilters_Click"/>
|
Click="Menu_List_PrintFilters_Click"/>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
<MenuItem x:Name="Menu_List_SaveAll" Header="...mit allen speichern (Excel)"
|
<MenuItem x:Name="Menu_List_SaveAll" Header="...mit allen speichern... (Excel)"
|
||||||
Click="Menu_List_SaveAll_Click"/>
|
Click="Menu_List_SaveAll_Click"/>
|
||||||
<MenuItem x:Name="Menu_List_ShowAll" Header="...mit allen anzeigen (PDF)"
|
<MenuItem x:Name="Menu_List_ShowAll" Header="...mit allen anzeigen (PDF)"
|
||||||
Click="Menu_List_ShowAll_Click"/>
|
Click="Menu_List_ShowAll_Click"/>
|
||||||
@@ -147,6 +147,10 @@
|
|||||||
IsCheckable="True" IsChecked="{Binding MemberListOrderByOrt, Mode=TwoWay}"
|
IsCheckable="True" IsChecked="{Binding MemberListOrderByOrt, Mode=TwoWay}"
|
||||||
Click="Menu_List_Order_Click"/>
|
Click="Menu_List_Order_Click"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="Geschäftsanteile" x:Name="Menu_BusinessShares">
|
||||||
|
<MenuItem x:Name="Menu_BusinessShares_SavePending" Header="Ausstehende Mitlg.-Bewegungen speichern... (Excel)"
|
||||||
|
Click="Menu_BusinessShares_SavePending_Click"/>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem Header="Export">
|
<MenuItem Header="Export">
|
||||||
<MenuItem x:Name="Menu_Export_ExportSelected" Header="...von ausgewähltem Mitglied speichern..." IsEnabled="False"
|
<MenuItem x:Name="Menu_Export_ExportSelected" Header="...von ausgewähltem Mitglied speichern..." IsEnabled="False"
|
||||||
Click="Menu_Export_ExportSelected_Click"/>
|
Click="Menu_Export_ExportSelected_Click"/>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Elwig.Dialogs;
|
using Elwig.Dialogs;
|
||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Export;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Services;
|
using Elwig.Services;
|
||||||
using Elwig.ViewModels;
|
using Elwig.ViewModels;
|
||||||
@@ -114,6 +115,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!App.Client.EnableMemberHistory) {
|
if (!App.Client.EnableMemberHistory) {
|
||||||
|
Menu_BusinessShares.Visibility = Visibility.Collapsed;
|
||||||
BusinessSharesButton.Visibility = Visibility.Hidden;
|
BusinessSharesButton.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -809,6 +811,10 @@ namespace Elwig.Windows {
|
|||||||
await App.Client.UpdateValues();
|
await App.Client.UpdateValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void Menu_BusinessShares_SavePending_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
await MemberBusinessSharesService.GenerateMemberMovements(MemberBusinessSharesService.ExportSubject.Pending, ExportMode.SaveList);
|
||||||
|
}
|
||||||
|
|
||||||
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
|
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
|
||||||
if (!IsEditing && !IsCreating) {
|
if (!IsEditing && !IsCreating) {
|
||||||
SearchInput.Focus();
|
SearchInput.Focus();
|
||||||
|
|||||||
Reference in New Issue
Block a user