Compare commits
8
Commits
db8afa59b7
..
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09642e643c | ||
|
|
b262e17293 | ||
|
|
4f4d026b7b | ||
|
|
abb9e5a577 | ||
|
|
0e586cc438 | ||
|
|
829ad106cf | ||
|
|
ba7c37fd70 | ||
|
|
66a1185dc3 |
No files matched your search
@@ -7,12 +7,6 @@
|
|||||||
<ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/>
|
<ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/>
|
||||||
<ctrl:WidthToMarginConverter x:Key="WidthToMarginConverter"/>
|
<ctrl:WidthToMarginConverter x:Key="WidthToMarginConverter"/>
|
||||||
|
|
||||||
<DataTemplate x:Key="PostalDestTemplate">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<TextBlock Text="{Binding Dest}"/>
|
|
||||||
<TextBlock Text="{Binding Ort.Name, StringFormat='{} ({0})'}"/>
|
|
||||||
</StackPanel>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate x:Key="KgNrTemplate">
|
<DataTemplate x:Key="KgNrTemplate">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<TextBlock Text="{Binding Name}"/>
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Part.DPNr}" Width="20" TextAlignment="Right"
|
<TextBlock Text="{Binding Part.DPNr}" Width="20" TextAlignment="Right"
|
||||||
VerticalAlignment="Center" Margin="0,0,5,0" FontSize="14"/>
|
VerticalAlignment="Center" Margin="0,0,5,0" FontSize="14"/>
|
||||||
<TextBlock Text="{Binding Part.SortId}" Width="40" TextAlignment="Center"
|
<TextBlock Text="{Binding Part.SortId}" Foreground="{Binding Part.Variety.Color}" Width="40" TextAlignment="Center"
|
||||||
VerticalAlignment="Center" Margin="0,0,0,0" FontSize="14"/>
|
VerticalAlignment="Center" Margin="0,0,0,0" FontSize="14"/>
|
||||||
<TextBlock Text="{Binding Part.Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"
|
<TextBlock Text="{Binding Part.Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Elwig.Helpers;
|
|||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Windows;
|
using Elwig.Windows;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace Elwig.Documents {
|
|||||||
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 6, 0));
|
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 6, 0));
|
||||||
doc.Add(NewAreaCmtTable(ActiveAreaCommitments));
|
doc.Add(NewAreaCmtTable(ActiveAreaCommitments));
|
||||||
}
|
}
|
||||||
if (App.Client.EnableMemberHistory) {
|
if (App.Client.EnableMemberHistory && App.Client.ModeMemberDataSheetShares > 0) {
|
||||||
bool firstOnPage = false;
|
bool firstOnPage = false;
|
||||||
if (pdf.GetNumberOfPages() == 1) {
|
if (pdf.GetNumberOfPages() == 1) {
|
||||||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||||||
@@ -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;
|
||||||
|
|||||||
+2
-2
@@ -25,8 +25,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="156.0.8076" />
|
<PackageReference Include="bblanchon.PDFium.Win32" Version="156.0.8076" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="itext" Version="9.7.0" />
|
<PackageReference Include="itext" Version="9.8.0" />
|
||||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.7.0" />
|
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.8.0" />
|
||||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||||
<PackageReference Include="MailKit" Version="4.18.1" />
|
<PackageReference Include="MailKit" Version="4.18.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" />
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ namespace Elwig.Helpers {
|
|||||||
public int ModeBusinessShares;
|
public int ModeBusinessShares;
|
||||||
public bool HasRedWhite => ModeBusinessShares == 1;
|
public bool HasRedWhite => ModeBusinessShares == 1;
|
||||||
|
|
||||||
|
public int ModeMemberDataSheetShares;
|
||||||
public int ModeDeliveryNoteStats;
|
public int ModeDeliveryNoteStats;
|
||||||
public int ModeWineQualityStatistics;
|
public int ModeWineQualityStatistics;
|
||||||
public int OrderingMemberList;
|
public int OrderingMemberList;
|
||||||
@@ -127,6 +128,10 @@ namespace Elwig.Helpers {
|
|||||||
case "SIMPLE": ModeBusinessShares = 0; break;
|
case "SIMPLE": ModeBusinessShares = 0; break;
|
||||||
case "RED_WHITE": ModeBusinessShares = 1; break;
|
case "RED_WHITE": ModeBusinessShares = 1; break;
|
||||||
}
|
}
|
||||||
|
switch (parameters.GetValueOrDefault("MODE_MEMBERDATASHEET_SHARES", "FULL")?.ToUpper()) {
|
||||||
|
case "NONE": ModeMemberDataSheetShares = 0; break;
|
||||||
|
case "FULL": ModeMemberDataSheetShares = 1; break;
|
||||||
|
}
|
||||||
switch (parameters.GetValueOrDefault("MODE_DELIVERYNOTE_STATS", "SHORT")?.ToUpper()) {
|
switch (parameters.GetValueOrDefault("MODE_DELIVERYNOTE_STATS", "SHORT")?.ToUpper()) {
|
||||||
case "NONE": ModeDeliveryNoteStats = 0; break;
|
case "NONE": ModeDeliveryNoteStats = 0; break;
|
||||||
case "GA_ONLY": ModeDeliveryNoteStats = 1; break;
|
case "GA_ONLY": ModeDeliveryNoteStats = 1; break;
|
||||||
@@ -209,6 +214,11 @@ namespace Elwig.Helpers {
|
|||||||
case 0: businessShares = "SIMPLE"; break;
|
case 0: businessShares = "SIMPLE"; break;
|
||||||
case 1: businessShares = "RED_WHITE"; break;
|
case 1: businessShares = "RED_WHITE"; break;
|
||||||
}
|
}
|
||||||
|
string memberDataSheetShares = "FULL";
|
||||||
|
switch (ModeMemberDataSheetShares) {
|
||||||
|
case 0: memberDataSheetShares = "NONE"; break;
|
||||||
|
case 1: memberDataSheetShares = "FULL"; break;
|
||||||
|
}
|
||||||
string deliveryNoteStats = "SHORT";
|
string deliveryNoteStats = "SHORT";
|
||||||
switch (ModeDeliveryNoteStats) {
|
switch (ModeDeliveryNoteStats) {
|
||||||
case 0: deliveryNoteStats = "NONE"; break;
|
case 0: deliveryNoteStats = "NONE"; break;
|
||||||
@@ -279,6 +289,7 @@ namespace Elwig.Helpers {
|
|||||||
("CLIENT_ORGANIC_AUTHORITYCODE", OrganicAuthorityCode),
|
("CLIENT_ORGANIC_AUTHORITYCODE", OrganicAuthorityCode),
|
||||||
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
|
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
|
||||||
("MODE_BUSINESSSHARES", businessShares),
|
("MODE_BUSINESSSHARES", businessShares),
|
||||||
|
("MODE_MEMBERDATASHEET_SHARES", memberDataSheetShares),
|
||||||
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
|
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
|
||||||
("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics),
|
("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics),
|
||||||
("ORDERING_MEMBERLIST", orderingMemberList),
|
("ORDERING_MEMBERLIST", orderingMemberList),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
using Row = Tuple<(string?, string?, string?, string?, string, int, string, bool, int), (string, int, string, string, string, int, string, double, double)>;
|
using Row = Tuple<(string?, string?, string?, string?, string, int, string, bool, int), (string, int, string, string, string, int, string, double, double)>;
|
||||||
|
|
||||||
public class Bki : Csv<Row> {
|
public class Bki : CsvFile<Row> {
|
||||||
|
|
||||||
private readonly string _clientData;
|
private readonly string _clientData;
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
namespace Elwig.Helpers.Export {
|
||||||
public abstract class Csv<T> : IExporter<T> {
|
public abstract class CsvFile<T> : IExporter<T> {
|
||||||
|
|
||||||
public static string FileExtension => "csv";
|
public static string FileExtension => "csv";
|
||||||
|
|
||||||
@@ -15,11 +15,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
protected readonly char Separator;
|
protected readonly char Separator;
|
||||||
protected string? Header;
|
protected string? Header;
|
||||||
|
|
||||||
public Csv(string filename, char separator = ';') :
|
public CsvFile(string filename, char separator = ';') :
|
||||||
this(filename, separator, Utils.UTF8) {
|
this(filename, separator, Utils.UTF8) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Csv(string filename, char separator, Encoding encoding) {
|
public CsvFile(string filename, char separator, Encoding encoding) {
|
||||||
_writer = new StreamWriter(filename, false, encoding);
|
_writer = new StreamWriter(filename, false, encoding);
|
||||||
Separator = separator;
|
Separator = separator;
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -61,7 +52,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
public abstract string FormatRow(T row);
|
public abstract string FormatRow(T row);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CsvSimple : Csv<IEnumerable<object?>> {
|
public class CsvSimple : CsvFile<IEnumerable<object?>> {
|
||||||
|
|
||||||
public CsvSimple(string filename, char separator, Encoding encoding) :
|
public CsvSimple(string filename, char separator, Encoding encoding) :
|
||||||
base(filename, separator, encoding) {
|
base(filename, separator, encoding) {
|
||||||
@@ -9,7 +9,7 @@ using System.Security;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
namespace Elwig.Helpers.Export {
|
||||||
public class Ebics(PaymentVar variant, string filename, int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) : IBankingExporter {
|
public class Ebics(PaymentVar variant, string filename, int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) : IExporter<Transaction> {
|
||||||
|
|
||||||
public enum AddressMode { Omit = 0, Lines = 1, Full = 2 }
|
public enum AddressMode { Omit = 0, Lines = 1, Full = 2 }
|
||||||
|
|
||||||
@@ -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");
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
using Elwig.Models.Dtos;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
|
||||||
public class Elba : Csv<Transaction>, IBankingExporter {
|
|
||||||
|
|
||||||
public static new string FileExtension => "elba";
|
|
||||||
|
|
||||||
public Elba(string filename) : base(filename) { }
|
|
||||||
|
|
||||||
public override string FormatRow(Transaction row) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using Elwig.Models.Dtos;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for exporting banking data
|
|
||||||
/// </summary>
|
|
||||||
public interface IBankingExporter : IExporter<Transaction> { }
|
|
||||||
}
|
|
||||||
@@ -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,70 +25,87 @@ 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)).ToList();
|
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))).ToArray();
|
_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 => f.FieldType) :
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => (Type?)f.FieldType) :
|
||||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => f.FieldType) :
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => (Type?)f.FieldType) :
|
||||||
[type];
|
[type];
|
||||||
}).ToList();
|
})];
|
||||||
ColumnSpans = ColumnTypes.Select(type => {
|
ColumnSpans = [.. ColumnTypes.Select(type => {
|
||||||
var elType = type?.GetElementType();
|
var elType = type?.GetElementType();
|
||||||
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Length :
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Length :
|
||||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length : 1;
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length :
|
||||||
}).ToList();
|
1;
|
||||||
ColumnWidths = colNames.Select(c => c.Item4).ToList();
|
})];
|
||||||
ColumnUnits = colNames.Select(c => c.Item3?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? []).ToList();
|
ColumnWidths = [.. colNames.Select(c => c.Width)];
|
||||||
|
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 = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,9 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("dest")]
|
[Column("dest")]
|
||||||
public string Dest { get; private set; } = null!;
|
public string Dest { get; private set; } = null!;
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public string FullDest => $"{Ort.Name} ({Dest})";
|
||||||
|
|
||||||
[ForeignKey("Plz")]
|
[ForeignKey("Plz")]
|
||||||
public virtual AT_Plz AtPlz { get; private set; } = null!;
|
public virtual AT_Plz AtPlz { get; private set; } = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -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}" : "");
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ UPDATE client_parameter SET param = 'CLIENT_ORGANIC_AUTHORITYCODE' WHERE param =
|
|||||||
UPDATE member_telephone_number SET comment = NULL WHERE comment = '';
|
UPDATE member_telephone_number SET comment = NULL WHERE comment = '';
|
||||||
UPDATE member_email_address SET comment = NULL WHERE comment = '';
|
UPDATE member_email_address SET comment = NULL WHERE comment = '';
|
||||||
|
|
||||||
UPDATE member SET address = 'Untere Weißgerberstraße' WHERE address = 'U. Weißgasse Straße';
|
UPDATE member SET address = CONCAT('Untere Weißgerberstraße ', SUBSTR(address, 21)) WHERE address LIKE 'U. Weißgasse Straße %';
|
||||||
UPDATE member SET address = 'Edgar-Penzig-Franz-Straße' WHERE address = 'Edgar-Penzing-Franz-Straße';
|
UPDATE member SET address = CONCAT('Edgar-Penzig-Franz-Straße ', SUBSTR(address, 28)) WHERE address LIKE 'Edgar-Penzing-Franz-Straße %';
|
||||||
|
|
||||||
UPDATE member
|
UPDATE member
|
||||||
SET address = NORMALIZE_ADDRESS(address, (SELECT o.name FROM AT_plz_dest p JOIN AT_ort o ON o.okz = p.okz WHERE p.id = member.postal_dest))
|
SET address = NORMALIZE_ADDRESS(address, (SELECT o.name FROM AT_plz_dest p JOIN AT_ort o ON o.okz = p.okz WHERE p.id = member.postal_dest))
|
||||||
|
|||||||
@@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ namespace Elwig.ViewModels {
|
|||||||
public partial string? WeightString { get; set; }
|
public partial string? WeightString { get; set; }
|
||||||
public int? Weight {
|
public int? Weight {
|
||||||
get => int.TryParse(WeightString?.Replace(Utils.GroupSeparator, ""), out var w) ? w : null;
|
get => int.TryParse(WeightString?.Replace(Utils.GroupSeparator, ""), out var w) ? w : null;
|
||||||
set => WeightString = $"{value:N0}";
|
set => WeightString = value > 0 ? $"{value:N0}" : null;
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public partial string? TareString { get; set; } = "-";
|
public partial string? TareString { get; set; } = "-";
|
||||||
|
|||||||
@@ -195,7 +195,7 @@
|
|||||||
<Label Content="PLZ/Ort:" Margin="10,70,0,10"/>
|
<Label Content="PLZ/Ort:" Margin="10,70,0,10"/>
|
||||||
<TextBox x:Name="BranchPlzInput" Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
<TextBox x:Name="BranchPlzInput" Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
||||||
TextChanged="BranchPlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
TextChanged="BranchPlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||||
<ComboBox x:Name="BranchOrtInput" ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
<ComboBox x:Name="BranchOrtInput" DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||||
Margin="47,70,10,0" Grid.Column="1" Grid.ColumnSpan="3" Width="253" HorizontalAlignment="Left"
|
Margin="47,70,10,0" Grid.Column="1" Grid.ColumnSpan="3" Width="253" HorizontalAlignment="Left"
|
||||||
SelectionChanged="Branch_Changed"/>
|
SelectionChanged="Branch_Changed"/>
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
||||||
<Label Content="Mitgliederbewegungen:" Margin="10,40,10,10"/>
|
<Label Content="Mitgliederbewegungen:" Margin="10,40,10,10"/>
|
||||||
<CheckBox x:Name="ParameterBusinessShareHistoryInput" Content="Mit Elwig erfassen" Margin="160,45,10,15"
|
<CheckBox x:Name="ParameterBusinessShareHistoryInput" Content="Mit Elwig erfassen" Margin="160,45,10,15"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -611,6 +611,13 @@
|
|||||||
<TabItem Header="Textelemente">
|
<TabItem Header="Textelemente">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
<GroupBox Header="Stammdatenblatt" Margin="10,10,10,10" Height="70">
|
||||||
|
<Grid>
|
||||||
|
<CheckBox x:Name="ModeMemberDataSheetShares" Content="Verlauf der Geschäftsanteile anzeigen" Margin="15,15,10,15"
|
||||||
|
HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||||
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||||
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
<GroupBox Header="Lieferschein" Margin="10,10,10,10" Height="180">
|
<GroupBox Header="Lieferschein" Margin="10,10,10,10" Height="180">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ namespace Elwig.Windows {
|
|||||||
ClientEmailAddressInput.Text = p.EmailAddress;
|
ClientEmailAddressInput.Text = p.EmailAddress;
|
||||||
ClientWebsiteInput.Text = p.Website;
|
ClientWebsiteInput.Text = p.Website;
|
||||||
|
|
||||||
|
ModeMemberDataSheetShares.IsChecked = p.ModeMemberDataSheetShares > 0;
|
||||||
TextElementDeliveryNote.Text = p.TextDeliveryNote;
|
TextElementDeliveryNote.Text = p.TextDeliveryNote;
|
||||||
switch (p.ModeDeliveryNoteStats) {
|
switch (p.ModeDeliveryNoteStats) {
|
||||||
case 0: ModeDeliveryNoteNone.IsChecked = true; break;
|
case 0: ModeDeliveryNoteNone.IsChecked = true; break;
|
||||||
@@ -381,6 +382,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
p.ModeBusinessShares = ParameterBusinessShareModeInput.SelectedIndex;
|
p.ModeBusinessShares = ParameterBusinessShareModeInput.SelectedIndex;
|
||||||
p.EnableMemberHistory = ParameterBusinessShareHistoryInput.IsChecked ?? false;
|
p.EnableMemberHistory = ParameterBusinessShareHistoryInput.IsChecked ?? false;
|
||||||
|
p.ModeMemberDataSheetShares = ModeMemberDataSheetShares.IsChecked == true ? 1 : 0;
|
||||||
p.TextDeliveryNote = string.IsNullOrWhiteSpace(TextElementDeliveryNote.Text) ? null : TextElementDeliveryNote.Text;
|
p.TextDeliveryNote = string.IsNullOrWhiteSpace(TextElementDeliveryNote.Text) ? null : TextElementDeliveryNote.Text;
|
||||||
p.ModeDeliveryNoteStats = (ModeDeliveryNoteNone.IsChecked == true) ? 0 : (ModeDeliveryNoteGaOnly.IsChecked == true) ? 1 : (ModeDeliveryNoteShort.IsChecked == true) ? 2 : (ModeDeliveryNoteFull.IsChecked == true) ? 3 : 2;
|
p.ModeDeliveryNoteStats = (ModeDeliveryNoteNone.IsChecked == true) ? 0 : (ModeDeliveryNoteGaOnly.IsChecked == true) ? 1 : (ModeDeliveryNoteShort.IsChecked == true) ? 2 : (ModeDeliveryNoteFull.IsChecked == true) ? 3 : 2;
|
||||||
p.TextDeliveryConfirmation = string.IsNullOrWhiteSpace(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text;
|
p.TextDeliveryConfirmation = string.IsNullOrWhiteSpace(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text;
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ namespace Elwig.Windows {
|
|||||||
var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare);
|
var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare);
|
||||||
if (correction == null) return;
|
if (correction == null) return;
|
||||||
ViewModel.Weight += lastCorrection - correction;
|
ViewModel.Weight += lastCorrection - correction;
|
||||||
if (ViewModel.WeighingData is string s) {
|
if (ViewModel.Weight != null && ViewModel.WeighingData is string s) {
|
||||||
ViewModel.TargetTare = correction == 0 ? null : (ViewModel.ActualTare ?? 0) + correction;
|
ViewModel.TargetTare = correction == 0 ? null : (ViewModel.ActualTare ?? 0) + correction;
|
||||||
ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare;
|
ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare;
|
||||||
var obj = JsonNode.Parse(s)!.AsObject();
|
var obj = JsonNode.Parse(s)!.AsObject();
|
||||||
@@ -1514,7 +1514,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
InputTextChanged((TextBox)sender);
|
InputTextChanged((TextBox)sender, new ValidationResult(ViewModel.Weight > 0, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TemperatureAcidInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void TemperatureAcidInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
|||||||
@@ -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"/>
|
||||||
@@ -378,7 +382,7 @@
|
|||||||
Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
||||||
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||||
<ComboBox x:Name="OrtInput" SelectedItem="{Binding Ort, Mode=TwoWay}" ItemsSource="{Binding OrtSource, Mode=TwoWay}"
|
<ComboBox x:Name="OrtInput" SelectedItem="{Binding Ort, Mode=TwoWay}" ItemsSource="{Binding OrtSource, Mode=TwoWay}"
|
||||||
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||||
SelectionChanged="OrtInput_SelectionChanged"
|
SelectionChanged="OrtInput_SelectionChanged"
|
||||||
Margin="47,160,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
Margin="47,160,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -611,7 +615,7 @@
|
|||||||
Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
||||||
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||||
<ComboBox x:Name="BillingOrtInput" SelectedItem="{Binding BillingOrt, Mode=TwoWay}" ItemsSource="{Binding BillingOrtSource, Mode=TwoWay}"
|
<ComboBox x:Name="BillingOrtInput" SelectedItem="{Binding BillingOrt, Mode=TwoWay}" ItemsSource="{Binding BillingOrtSource, Mode=TwoWay}"
|
||||||
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||||
SelectionChanged="OrtInput_SelectionChanged"
|
SelectionChanged="OrtInput_SelectionChanged"
|
||||||
Margin="47,70,10,0" Grid.Column="1"/>
|
Margin="47,70,10,0" Grid.Column="1"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -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