Compare commits
3
Commits
main
..
611313dbd2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
611313dbd2 | ||
|
|
895969b6ae | ||
|
|
54126814f3 |
No files matched your search
+401
-453
File diff suppressed because it is too large.
Load diff
@@ -7,6 +7,12 @@
|
||||
<ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/>
|
||||
<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">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
|
||||
+16
-17
@@ -339,21 +339,20 @@ namespace Elwig {
|
||||
|
||||
public static async Task CheckForUpdates(bool showAlert = false) {
|
||||
if (Config.UpdateUrl == null) return;
|
||||
try {
|
||||
var latest = await Utils.GetLatestInstallerUrl(Config.UpdateUrl);
|
||||
if (new Version(latest.Version) > Version) {
|
||||
await MainDispatcher.BeginInvoke(() => {
|
||||
var d = new UpdateDialog(latest.Version, latest.Url, latest.Size);
|
||||
if (d.ShowDialog() == true) {
|
||||
ShutdownNow();
|
||||
}
|
||||
});
|
||||
} else if (showAlert) {
|
||||
InteractionService.ShowInformation("Nach Updates suchen", $"Elwig ist auf dem aktuellsten Stand! (Version: {latest.Version})");
|
||||
var latest = await Utils.GetLatestInstallerUrl(Config.UpdateUrl);
|
||||
if (latest != null && new Version(latest.Value.Version) > Version) {
|
||||
await MainDispatcher.BeginInvoke(() => {
|
||||
var d = new UpdateDialog(latest.Value.Version, latest.Value.Url, latest.Value.Size);
|
||||
if (d.ShowDialog() == true) {
|
||||
ShutdownNow();
|
||||
}
|
||||
});
|
||||
} else if (showAlert) {
|
||||
if (latest == null) {
|
||||
InteractionService.ShowError("Nach Updates suchen", "Informationen konnten nicht abgerufen werden!");
|
||||
} else {
|
||||
InteractionService.ShowInformation("Nach Updates suchen", $"Elwig ist auf dem aktuellsten Stand! (Version: {latest.Value.Version})");
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
if (showAlert)
|
||||
InteractionService.ShowException("Nach Updates suchen", $"Informationen konnten nicht abgerufen werden!", exc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,15 +394,15 @@ namespace Elwig {
|
||||
return FocusWindow<DeliveryAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember?.MgNr == mgnr);
|
||||
}
|
||||
|
||||
public static AreaCmtAdminWindow FocusMemberAreaCmts(int mgnr) {
|
||||
return FocusWindow<AreaCmtAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember.MgNr == mgnr);
|
||||
public static AreaComAdminWindow FocusMemberAreaComs(int mgnr) {
|
||||
return FocusWindow<AreaComAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember.MgNr == mgnr);
|
||||
}
|
||||
|
||||
public static BaseDataWindow FocusBaseData() {
|
||||
return FocusWindow<BaseDataWindow>(() => new());
|
||||
}
|
||||
|
||||
public static BaseDataWindow FocusBaseDataAreaCmtType() {
|
||||
public static BaseDataWindow FocusBaseDataAreaComType() {
|
||||
var w = FocusBaseData();
|
||||
w.AreaCommitmentTypes.Focus();
|
||||
return w;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Window x:Class="Elwig.Dialogs.AreaCmtModifyDialog"
|
||||
<Window x:Class="Elwig.Dialogs.AreaComModifyDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
+2
-2
@@ -4,7 +4,7 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Elwig.Dialogs {
|
||||
public partial class AreaCmtModifyDialog : Window {
|
||||
public partial class AreaComModifyDialog : Window {
|
||||
|
||||
public int? YearTo { get; set; }
|
||||
public bool ModifyRetroactively { get; set; }
|
||||
@@ -13,7 +13,7 @@ namespace Elwig.Dialogs {
|
||||
public string OrigYearTo { get; set; }
|
||||
public string Area { get; set; }
|
||||
|
||||
public AreaCmtModifyDialog(int? yearFrom, int? yearTo, int area, bool delete, bool forceRetroactive = false) {
|
||||
public AreaComModifyDialog(int? yearFrom, int? yearTo, int area, bool delete, bool forceRetroactive = false) {
|
||||
Area = $"{area:N0}";
|
||||
OrigYearFrom = $"{yearFrom}";
|
||||
OrigYearTo = $"{yearTo}";
|
||||
@@ -1,4 +1,4 @@
|
||||
<Window x:Class="Elwig.Dialogs.AreaCmtTransferDialog"
|
||||
<Window x:Class="Elwig.Dialogs.AreaComTransferDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -35,11 +35,11 @@
|
||||
<TextBlock x:Name="QuestionBlock1" TextAlignment="Center" Margin="0,10,0,0"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
Sollen die aktiven Flächenbindungen des angegebenen Vorgängers<LineBreak/>
|
||||
übernommen werden? (<Run Text="{Binding AreaCmtNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
||||
übernommen werden? (<Run Text="{Binding AreaComNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
||||
</TextBlock>
|
||||
<TextBlock x:Name="QuestionBlock2" TextAlignment="Center" Margin="0,10,0,0" Visibility="Hidden"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
Sollen die aktiven Flächenbindungen gekündigt werden? (<Run Text="{Binding AreaCmtNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
||||
Sollen die aktiven Flächenbindungen gekündigt werden? (<Run Text="{Binding AreaComNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
||||
</TextBlock>
|
||||
|
||||
<Label x:Name="SeasonLabel" Content="Saison:" Margin="0,50,100,0"
|
||||
+6
-6
@@ -3,17 +3,17 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Elwig.Dialogs {
|
||||
public partial class AreaCmtTransferDialog : Window {
|
||||
public partial class AreaComTransferDialog : Window {
|
||||
|
||||
public int CancelSeason => SuccessorSeason - 1;
|
||||
public int SuccessorSeason { get; set; }
|
||||
|
||||
public string AreaCmtNum { get; set; }
|
||||
public string AreaComNum { get; set; }
|
||||
public string Area { get; set; }
|
||||
|
||||
public AreaCmtTransferDialog(string name, int areaCmtNum, int area) {
|
||||
public AreaComTransferDialog(string name, int areaComNum, int area) {
|
||||
SuccessorSeason = Utils.FollowingSeason;
|
||||
AreaCmtNum = $"{areaCmtNum:N0}";
|
||||
AreaComNum = $"{areaComNum:N0}";
|
||||
Area = $"{area:N0}";
|
||||
InitializeComponent();
|
||||
SeasonInput.Text = $"{SuccessorSeason}";
|
||||
@@ -28,9 +28,9 @@ namespace Elwig.Dialogs {
|
||||
SeasonLabel.Margin = new(0, 40, 100, 0);
|
||||
}
|
||||
|
||||
public AreaCmtTransferDialog(string name, string successorName, int areaCmtNum, int area) {
|
||||
public AreaComTransferDialog(string name, string successorName, int areaComNum, int area) {
|
||||
SuccessorSeason = Utils.FollowingSeason;
|
||||
AreaCmtNum = $"{areaCmtNum:N0}";
|
||||
AreaComNum = $"{areaComNum:N0}";
|
||||
Area = $"{area:N0}";
|
||||
InitializeComponent();
|
||||
SeasonInput.Text = $"{SuccessorSeason}";
|
||||
@@ -47,9 +47,9 @@
|
||||
TextChanged="NameInput_TextChanged"/>
|
||||
|
||||
<Label Content="Beim Löschen müssen folgende Daten auch gelöscht werden:" Margin="10,120,10,10"/>
|
||||
<CheckBox x:Name="AreaCmtInput" Content="Flächenbindungen" Margin="40,145,0,0"
|
||||
<CheckBox x:Name="AreaComInput" Content="Flächenbindungen" Margin="40,145,0,0"
|
||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||
IsChecked="{Binding DeleteAreaCmts}"/>
|
||||
IsChecked="{Binding DeleteAreaComs}"/>
|
||||
<CheckBox x:Name="DeliveryInput" Content="Lieferungen" Margin="40,165,0,0"
|
||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||
IsChecked="{Binding DeleteDeliveries}"/>
|
||||
|
||||
@@ -8,16 +8,16 @@ namespace Elwig.Dialogs {
|
||||
|
||||
protected string[] NameParts;
|
||||
|
||||
public bool DeleteAreaCmts { get; set; }
|
||||
public bool DeleteAreaComs { get; set; }
|
||||
public bool DeleteDeliveries { get; set; }
|
||||
public bool DeletePaymentData { get; set; }
|
||||
|
||||
public DeleteMemberDialog(int mgnr, string name, int numAreaCmts, int numDeliveries, int numCredits) {
|
||||
public DeleteMemberDialog(int mgnr, string name, int numAreaComs, int numDeliveries, int numCredits) {
|
||||
NameParts = name.ToLower().Split(' ').Where(p => p.Length > 0).Append($"{mgnr}").ToArray();
|
||||
InitializeComponent();
|
||||
Title += " - " + name;
|
||||
AreaCmtInput.IsEnabled = numAreaCmts != 0;
|
||||
AreaCmtInput.Content += $" ({numAreaCmts:N0})";
|
||||
AreaComInput.IsEnabled = numAreaComs != 0;
|
||||
AreaComInput.Content += $" ({numAreaComs:N0})";
|
||||
DeliveryInput.IsEnabled = numDeliveries != 0;
|
||||
DeliveryInput.Content += $" ({numDeliveries:N0})";
|
||||
PaymentInput.IsEnabled = numCredits != 0;
|
||||
@@ -43,7 +43,7 @@ namespace Elwig.Dialogs {
|
||||
private void Update() {
|
||||
var t = NameInput.Text.ToLower().Split(' ');
|
||||
var nameValid = NameParts.All(t.Contains);
|
||||
UpdateCheckBox(AreaCmtInput);
|
||||
UpdateCheckBox(AreaComInput);
|
||||
UpdateCheckBox(DeliveryInput);
|
||||
UpdateCheckBox(PaymentInput);
|
||||
if (!nameValid) {
|
||||
@@ -52,7 +52,7 @@ namespace Elwig.Dialogs {
|
||||
ControlUtils.ClearInputState(NameInput);
|
||||
}
|
||||
ConfirmButton.IsEnabled =
|
||||
(!AreaCmtInput.IsEnabled || DeleteAreaCmts) &&
|
||||
(!AreaComInput.IsEnabled || DeleteAreaComs) &&
|
||||
(!DeliveryInput.IsEnabled || DeleteDeliveries) &&
|
||||
(!PaymentInput.IsEnabled || DeletePaymentData) &&
|
||||
nameValid;
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Part.DPNr}" Width="20" TextAlignment="Right"
|
||||
VerticalAlignment="Center" Margin="0,0,5,0" FontSize="14"/>
|
||||
<TextBlock Text="{Binding Part.SortId}" Foreground="{Binding Part.Variety.Color}" Width="40" TextAlignment="Center"
|
||||
<TextBlock Text="{Binding Part.SortId}" Width="40" TextAlignment="Center"
|
||||
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"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
@@ -2,6 +2,7 @@ using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.Windows;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Elwig.Documents {
|
||||
public int MemberDeliveredWeightWhite;
|
||||
public List<MemberHistory> MemberHistory = [];
|
||||
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||
public List<AreaCmt> ActiveAreaCommitments = [];
|
||||
public List<AreaCom> ActiveAreaCommitments = [];
|
||||
|
||||
public MemberDataSheet(Member m) :
|
||||
base($"{Name} {m.AdministrativeName}", m, DateOnly.FromDateTime(m.ModifiedAt)) {
|
||||
@@ -68,9 +68,9 @@ namespace Elwig.Documents {
|
||||
firstOnPage = true;
|
||||
}
|
||||
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(NewAreaComTable(ActiveAreaCommitments));
|
||||
}
|
||||
if (App.Client.EnableMemberHistory && App.Client.ModeMemberDataSheetShares > 0) {
|
||||
if (App.Client.EnableMemberHistory) {
|
||||
bool firstOnPage = false;
|
||||
if (pdf.GetNumberOfPages() == 1) {
|
||||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||||
@@ -177,10 +177,10 @@ namespace Elwig.Documents {
|
||||
return tbl;
|
||||
}
|
||||
|
||||
protected Table NewAreaCmtTable(IEnumerable<AreaCmt> activeAreaCmts) {
|
||||
var areaCmts = activeAreaCmts.GroupBy(a => a.AreaCmtType).Select(group => new {
|
||||
protected Table NewAreaComTable(IEnumerable<AreaCom> activeAreaComs) {
|
||||
var areaComs = activeAreaComs.GroupBy(a => a.AreaComType).Select(group => new {
|
||||
Type = group.Key,
|
||||
AreaCmts = group.OrderBy(c => c.Contract.Kg.AtKg.Name).ToList(),
|
||||
AreaComs = group.OrderBy(c => c.Contract.Kg.AtKg.Name).ToList(),
|
||||
Size = group.Sum(c => c.Area)
|
||||
}).OrderByDescending(a => a.Size).ToList();
|
||||
|
||||
@@ -199,7 +199,7 @@ namespace Elwig.Documents {
|
||||
.AddHeaderCell(NewTh("[m²]"));
|
||||
|
||||
var lastContract = "";
|
||||
foreach (var contractType in areaCmts) {
|
||||
foreach (var contractType in areaComs) {
|
||||
tbl.AddCell(NewCell(new KernedParagraph(10).Add(BoldItalic($"{contractType.Type.WineVar.Name} {(contractType.Type.WineAttr != null ? "(" + contractType.Type.WineAttr + ")" : "")}")), colspan: 3)
|
||||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER))
|
||||
.AddCell(NewCell(new KernedParagraph(10).Add(Bold($"{contractType.Size:N0}")).SetTextAlignment(TextAlignment.RIGHT))
|
||||
@@ -207,20 +207,20 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewCell(colspan: 2)
|
||||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER));
|
||||
|
||||
foreach (var areaCmt in contractType.AreaCmts) {
|
||||
var c = areaCmt.Contract;
|
||||
foreach (var areaCom in contractType.AreaComs) {
|
||||
var c = areaCom.Contract;
|
||||
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{c.Kg.AtKg.Name} ")).Add(Normal($"({c.Kg.AtKg.KgNr:00000})", 8))))
|
||||
.AddCell(NewTd(c.Rd?.Name))
|
||||
.AddCell(NewTd(Regex.Replace(areaCmt.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
||||
.AddCell(NewTd($"{areaCmt.Area:N0}", right: true))
|
||||
.AddCell(NewTd(areaCmt.WineCult?.Name, center: true))
|
||||
.AddCell(NewTd(Regex.Replace(areaCom.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
||||
.AddCell(NewTd($"{areaCom.Area:N0}", right: true))
|
||||
.AddCell(NewTd(areaCom.WineCult?.Name, center: true))
|
||||
.AddCell(NewTd(c.YearTo == null ? (c.YearFrom == null ? "unbefristet" : $"ab {c.YearFrom}") : (c.YearFrom == null ? $"bis {c.YearTo}" : $"{c.YearFrom}–{c.YearTo}"), center: true));
|
||||
lastContract = contractType.Type.DisplayName;
|
||||
}
|
||||
}
|
||||
|
||||
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
tbl.AddCell(NewTd($"{activeAreaCmts.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
tbl.AddCell(NewTd($"{activeAreaComs.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
|
||||
return tbl;
|
||||
@@ -274,11 +274,11 @@ namespace Elwig.Documents {
|
||||
.AddCells(NewBusinessSharesCells(new()));
|
||||
}
|
||||
|
||||
var recorded = history.Aggregate(new MemberHistoryPoint(), (s, h) => new(
|
||||
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.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.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.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Dormant && h.FromType == BusinessShareType.Dormant ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Dormant ? h.Shares : 0)));
|
||||
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.SharesRed + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Red ? h.Shares : 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.SharesDormant + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Dormant ? h.Shares : 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);
|
||||
|
||||
if (cur.Shares != 0 || cur.SharesRed != 0 || cur.SharesWhite != 0 || cur.SharesDormant != 0) {
|
||||
@@ -297,7 +297,7 @@ namespace Elwig.Documents {
|
||||
DateOnly? lastDate = null;
|
||||
foreach (var row in history) {
|
||||
int s = 0, r = 0, w = 0, d = 0;
|
||||
if (row.FromMgNr == Member.MgNr && !(row.FromMgNr == row.ToMgNr && row.FromType == row.ToType)) {
|
||||
if (row.FromMgNr == Member.MgNr) {
|
||||
switch (row.FromType) {
|
||||
case BusinessShareType.Normal: s -= row.Shares; break;
|
||||
case BusinessShareType.Red: r -= row.Shares; break;
|
||||
|
||||
@@ -16,14 +16,14 @@ namespace Elwig.Documents {
|
||||
public string Filter;
|
||||
public List<MemberListRow> Members;
|
||||
|
||||
public string[] AreaCmtFilters;
|
||||
public bool FilterAreaCmts => AreaCmtFilters.Length > 0;
|
||||
public string[] AreaComFilters;
|
||||
public bool FilterAreaComs => AreaComFilters.Length > 0;
|
||||
|
||||
public MemberList(string filter, IEnumerable<MemberListRow> members) :
|
||||
base(Name) {
|
||||
Filter = filter;
|
||||
Members = [.. members];
|
||||
AreaCmtFilters = [..members
|
||||
AreaComFilters = [..members
|
||||
.SelectMany(m => m.AreaCommitmentsFiltered)
|
||||
.Select(c => c.VtrgId)
|
||||
.Distinct()
|
||||
@@ -46,11 +46,11 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
protected Table NewMemberTable(List<MemberListRow> members) {
|
||||
var tbl = new Table(AreaCmtFilters.Length > 1 ? ColsMM(8, 38, 36, 8, 18, 12, 5, 16, 12, 12) : ColsMM(8, 42, 40, 8, 20, 12, 5, 18, 12), true)
|
||||
var tbl = new Table(AreaComFilters.Length > 1 ? ColsMM(8, 38, 36, 8, 18, 12, 5, 16, 12, 12) : ColsMM(8, 42, 40, 8, 20, 12, 5, 18, 12), true)
|
||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||
|
||||
var headerSpan = FilterAreaCmts ? 3 : 2;
|
||||
var headerSpan = FilterAreaComs ? 3 : 2;
|
||||
tbl.AddHeaderCell(NewTh("Nr.", rowspan: headerSpan))
|
||||
.AddHeaderCell(NewTh("Name", rowspan: headerSpan, left: true))
|
||||
.AddHeaderCell(NewTh("Adresse", rowspan: headerSpan, left: true))
|
||||
@@ -59,21 +59,21 @@ namespace Elwig.Documents {
|
||||
.AddHeaderCell(NewTh("Betr.-Nr.", rowspan: headerSpan))
|
||||
.AddHeaderCell(NewTh("GA", rowspan: headerSpan).SetPaddingLeft(0).SetPaddingRight(0))
|
||||
.AddHeaderCell(NewTh("Stamm-KG", rowspan: headerSpan, left: true))
|
||||
.AddHeaderCell(NewTh("Geb. Fl.", colspan: FilterAreaCmts ? AreaCmtFilters.Length : 1));
|
||||
if (FilterAreaCmts) {
|
||||
foreach (var vtrgId in AreaCmtFilters) {
|
||||
.AddHeaderCell(NewTh("Geb. Fl.", colspan: FilterAreaComs ? AreaComFilters.Length : 1));
|
||||
if (FilterAreaComs) {
|
||||
foreach (var vtrgId in AreaComFilters) {
|
||||
tbl.AddHeaderCell(NewTh(vtrgId));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < (FilterAreaCmts ? AreaCmtFilters.Length : 1); i++) {
|
||||
for (int i = 0; i < (FilterAreaComs ? AreaComFilters.Length : 1); i++) {
|
||||
tbl.AddHeaderCell(NewTh("[m²]"));
|
||||
}
|
||||
|
||||
string? lastBranch = members.Select(m => m.Branch).Distinct().Count() == 1 ? null : "";
|
||||
foreach (var m in members) {
|
||||
if (lastBranch != null && m.Branch != lastBranch) {
|
||||
tbl.AddCell(NewCell(colspan: 8 + Math.Max(AreaCmtFilters.Length, 1)).SetHeightMM(5).SetKeepWithNext(true));
|
||||
tbl.AddCell(NewCell(new KernedParagraph(m.Branch ?? "", 16).SetFont(BF), colspan: 8 + Math.Max(AreaCmtFilters.Length, 1))
|
||||
tbl.AddCell(NewCell(colspan: 8 + Math.Max(AreaComFilters.Length, 1)).SetHeightMM(5).SetKeepWithNext(true));
|
||||
tbl.AddCell(NewCell(new KernedParagraph(m.Branch ?? "", 16).SetFont(BF), colspan: 8 + Math.Max(AreaComFilters.Length, 1))
|
||||
.SetPaddingsMM(1, 2, 1, 2)
|
||||
.SetBorder(new SolidBorder(BorderThickness))
|
||||
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0)));
|
||||
@@ -88,8 +88,8 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewTd(m.LfbisNr ?? "", 8))
|
||||
.AddCell(NewTd($"{m.SharesActive:N0}", 8, right: true).SetPaddingLeft(0).SetPaddingRight(0))
|
||||
.AddCell(NewTd(m.DefaultKg ?? "", 6));
|
||||
if (AreaCmtFilters.Length > 0) {
|
||||
foreach (var v in AreaCmtFilters) {
|
||||
if (AreaComFilters.Length > 0) {
|
||||
foreach (var v in AreaComFilters) {
|
||||
tbl.AddCell(NewTd($"{m.AreaCommitmentsFiltered.FirstOrDefault(c => c.VtrgId == v).Area:N0}", 8, right: true));
|
||||
}
|
||||
} else {
|
||||
@@ -101,7 +101,7 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewTd(m.BillingAddress ?? "", 8))
|
||||
.AddCell(NewTd($"{m.BillingPlz}", 8))
|
||||
.AddCell(NewTd(m.BillingLocality ?? "", 6))
|
||||
.AddCell(NewTd(colspan: 3 + Math.Max(AreaCmtFilters.Length, 1)));
|
||||
.AddCell(NewTd(colspan: 3 + Math.Max(AreaComFilters.Length, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -9,7 +9,7 @@
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||
<Version>1.2.0.1</Version>
|
||||
<Version>1.1.2.2</Version>
|
||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ApplicationManifest>App.manifest</ApplicationManifest>
|
||||
@@ -23,11 +23,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="157.0.8086" />
|
||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="156.0.8076" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||
<PackageReference Include="itext" Version="9.8.0" />
|
||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.8.0" />
|
||||
<PackageReference Include="LinqKit" Version="1.4.0" />
|
||||
<PackageReference Include="itext" Version="9.7.0" />
|
||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.7.0" />
|
||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||
<PackageReference Include="MailKit" Version="4.18.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.12" />
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Elwig.Models;
|
||||
using Elwig.Models.Dtos;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.Services;
|
||||
@@ -16,7 +15,7 @@ using System.Threading.Tasks;
|
||||
namespace Elwig.Helpers {
|
||||
|
||||
public record struct MemberHistoryPoint(int Shares, int SharesRed, int SharesWhite, int SharesDormant);
|
||||
public record struct AreaCmtBucket(int Area, int Obligation, int Right);
|
||||
public record struct AreaComBucket(int Area, int Obligation, int Right);
|
||||
public record struct UnderDelivery(int Weight, int Diff);
|
||||
public record struct MemberBucket(string Name, int Area, int Obligation, int Right, int Delivery, int DeliveryStrict, int DeliveryTotal, int Payment);
|
||||
public record struct MemberStat(string Variety, string Discr, int Weight);
|
||||
@@ -44,14 +43,14 @@ namespace Elwig.Helpers {
|
||||
public DbSet<WineAttr> WineAttributes { get; private set; }
|
||||
public DbSet<WineCult> WineCultivations { get; private set; }
|
||||
public DbSet<Branch> Branches { get; private set; }
|
||||
public DbSet<AreaCmtType> AreaCommitmentTypes { get; private set; }
|
||||
public DbSet<AreaComType> AreaCommitmentTypes { get; private set; }
|
||||
public DbSet<Member> Members { get; private set; }
|
||||
public DbSet<BillingAddr> BillingAddresses { get; private set; }
|
||||
public DbSet<MemberTelNr> MemberTelephoneNrs { get; private set; }
|
||||
public DbSet<MemberEmailAddr> MemberEmailAddrs { get; private set; }
|
||||
public DbSet<MemberHistory> MemberHistory { get; private set; }
|
||||
public DbSet<AreaCmtContract> AreaCommitmentContracts { get; private set; }
|
||||
public DbSet<AreaCmt> AreaCommitments { get; private set; }
|
||||
public DbSet<AreaComContract> AreaCommitmentContracts { get; private set; }
|
||||
public DbSet<AreaCom> AreaCommitments { get; private set; }
|
||||
public DbSet<Season> Seasons { get; private set; }
|
||||
public DbSet<DeliverySchedule> DeliverySchedules { get; private set; }
|
||||
public DbSet<DeliveryScheduleWineVar> DeliveryScheduleWineVarieties { get; private set; }
|
||||
@@ -68,10 +67,10 @@ namespace Elwig.Helpers {
|
||||
public DbSet<DeliveryPartBucket> DeliveryPartBuckets { get; private set; }
|
||||
|
||||
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
||||
public DbSet<AreaCmtUnderDeliveryRowSingle> AreaCmtUnderDeliveryRows { get; private set; }
|
||||
public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
|
||||
public DbSet<MemberDeliveryPerVarietyRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
||||
public DbSet<MemberAreaCmtTotalsRowSingle> MemberAreaCmtTotalsRows { get; private set; }
|
||||
public DbSet<MemberAreaCmtsRow> MemberAreaCmtsRows { get; private set; }
|
||||
public DbSet<MemberAreaComTotalsRowSingle> MemberAreaComTotalsRows { get; private set; }
|
||||
public DbSet<MemberAreaComsRow> MemberAreaComsRows { get; private set; }
|
||||
public DbSet<CreditNoteDeliveryRowSingle> CreditNoteDeliveryRows { get; private set; }
|
||||
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
||||
public DbSet<WeightBreakdownRow> WeightBreakDownRows { get; private set; }
|
||||
@@ -133,8 +132,8 @@ namespace Elwig.Helpers {
|
||||
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr)
|
||||
.AsSplitQuery());
|
||||
|
||||
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<AreaCmt>> _compiledQueryAreaCommitments =
|
||||
EF.CompileAsyncQuery<AppDbContext, int?, AreaCmt>((ctx, fbnr) => ctx.AreaCommitments
|
||||
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<AreaCom>> _compiledQueryAreaCommitments =
|
||||
EF.CompileAsyncQuery<AppDbContext, int?, AreaCom>((ctx, fbnr) => ctx.AreaCommitments
|
||||
.Where(c => fbnr == null || c.FbNr == fbnr)
|
||||
.OrderBy(c => c.FbNr).ThenBy(c => c.RevNr));
|
||||
|
||||
@@ -150,7 +149,7 @@ namespace Elwig.Helpers {
|
||||
.OrderByDescending(s => s.Year));
|
||||
|
||||
private readonly Dictionary<int, Dictionary<int, MemberHistoryPoint>> _memberHistory = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaCmtBucket>>> _memberAreaCommitmentBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = [];
|
||||
@@ -230,13 +229,13 @@ namespace Elwig.Helpers {
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Kg).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Rd).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPartModifier>().Navigation(m => m.Modifier).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmtContract>().Navigation(c => c.Kg).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmtContract>().Navigation(c => c.Rd).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmt>().Navigation(c => c.Contract).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmt>().Navigation(c => c.WineCult).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmt>().Navigation(c => c.AreaCmtType).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmtType>().Navigation(c => c.WineVar).AutoInclude();
|
||||
modelBuilder.Entity<AreaCmtType>().Navigation(c => c.WineAttr).AutoInclude();
|
||||
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Kg).AutoInclude();
|
||||
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Rd).AutoInclude();
|
||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.Contract).AutoInclude();
|
||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.WineCult).AutoInclude();
|
||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.AreaComType).AutoInclude();
|
||||
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineVar).AutoInclude();
|
||||
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineAttr).AutoInclude();
|
||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Credit).AutoInclude();
|
||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Member).AutoInclude();
|
||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Variant).AutoInclude();
|
||||
@@ -439,7 +438,7 @@ namespace Elwig.Helpers {
|
||||
private async Task FetchMemberAreaCommitmentBuckets(int year, SqliteConnection? cnx = null) {
|
||||
var ownCnx = cnx == null;
|
||||
cnx ??= await ConnectAsync();
|
||||
var buckets = new Dictionary<int, Dictionary<string, AreaCmtBucket>>();
|
||||
var buckets = new Dictionary<int, Dictionary<string, AreaComBucket>>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"SELECT mgnr, bucket, area, min_kg, max_kg FROM v_area_commitment_bucket WHERE year = {year}";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
@@ -532,45 +531,7 @@ namespace Elwig.Helpers {
|
||||
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, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||
if (!_memberAreaCommitmentBuckets.ContainsKey(year))
|
||||
await FetchMemberAreaCommitmentBuckets(year, cnx);
|
||||
return _memberAreaCommitmentBuckets[year].GetValueOrDefault(mgnr, []);
|
||||
|
||||
@@ -13,32 +13,32 @@ namespace Elwig.Helpers.Billing {
|
||||
protected readonly Season Season;
|
||||
protected readonly Dictionary<string, string> Attributes;
|
||||
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
||||
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaCmtTypes;
|
||||
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
||||
|
||||
protected Billing(int year, Season season,
|
||||
Dictionary<string, string> attributes,
|
||||
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaCmtTypes
|
||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes
|
||||
) {
|
||||
Year = year;
|
||||
Season = season;
|
||||
Attributes = attributes;
|
||||
Modifiers = modifiers;
|
||||
AreaCmtTypes = areaCmtTypes;
|
||||
AreaComTypes = areaComTypes;
|
||||
}
|
||||
|
||||
protected static async Task<(Season, Dictionary<string, string>, Dictionary<string, (decimal?, decimal?)>, Dictionary<string, (string, string?, string?, int?, decimal?)>)> LoadData(AppDbContext ctx, int year) {
|
||||
var season = await ctx.FetchSeasons(year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a.Name);
|
||||
var modifiers = await ctx.FetchModifiers(year).ToDictionaryAsync(m => m.ModId, m => (m.Abs, m.Rel));
|
||||
var areaCmtTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||
return (season, attributes, modifiers, areaCmtTypes);
|
||||
var areaComTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||
return (season, attributes, modifiers, areaComTypes);
|
||||
}
|
||||
|
||||
public static async Task<Billing> Create(int year) {
|
||||
using var ctx = new AppDbContext();
|
||||
var (season, attributes, modifiers, areaCmtTypes) = await LoadData(ctx, year);
|
||||
return new Billing(year, season, attributes, modifiers, areaCmtTypes);
|
||||
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
||||
return new Billing(year, season, attributes, modifiers, areaComTypes);
|
||||
}
|
||||
|
||||
public async Task FinishSeason() {
|
||||
@@ -115,7 +115,7 @@ namespace Elwig.Helpers.Billing {
|
||||
}
|
||||
|
||||
int lastMgNr = 0;
|
||||
Dictionary<string, AreaCmtBucket>? rightsAndObligations = null;
|
||||
Dictionary<string, AreaComBucket>? rightsAndObligations = null;
|
||||
Dictionary<string, int> used = [];
|
||||
foreach (var (mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, contracted) in deliveries) {
|
||||
if (lastMgNr != mgnr) {
|
||||
@@ -140,7 +140,7 @@ namespace Elwig.Helpers.Billing {
|
||||
foreach (var p in Utils.Permutate(attributes, attributes.Intersect(attrForced))) {
|
||||
var c = p.Count();
|
||||
var key = sortid + string.Join("", p);
|
||||
if (rightsAndObligations.TryGetValue(key, out AreaCmtBucket value)) {
|
||||
if (rightsAndObligations.TryGetValue(key, out AreaComBucket value)) {
|
||||
int i = (c == 0) ? 1 : 2;
|
||||
var u = used.GetValueOrDefault(key, 0);
|
||||
var vr = Math.Max(0, Math.Min(value.Right - u, w));
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace Elwig.Helpers.Billing {
|
||||
} else {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
var ctrd = obj["ctrd"] ?? obj["geb"];
|
||||
var ctrd = obj["contracted"] ?? obj["geb"];
|
||||
if (ctrd is JsonObject) {
|
||||
c2 = GetCurveData(ctrd.AsObject(), cMode);
|
||||
} else if (ctrd?.AsValue().TryGetValue(out decimal v) == true) {
|
||||
@@ -287,9 +287,11 @@ namespace Elwig.Helpers.Billing {
|
||||
curve["data"] = GraphToJson(entry.DataGraph, entry.Mode.ToString().ToLower());
|
||||
|
||||
if (entry.ContractedFlatBonus != null) {
|
||||
curve["ctrd"] = (decimal)entry.ContractedFlatBonus;
|
||||
curve["contracted"] = (decimal)entry.ContractedFlatBonus;
|
||||
curve.Remove("geb");
|
||||
} else if (entry.ContractedGraph != null) {
|
||||
curve["ctrd"] = GraphToJson(entry.ContractedGraph, entry.Mode.ToString().ToLower());
|
||||
curve["contracted"] = GraphToJson(entry.ContractedGraph, entry.Mode.ToString().ToLower());
|
||||
curve.Remove("geb");
|
||||
}
|
||||
|
||||
return curve;
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace Elwig.Helpers.Billing {
|
||||
protected BillingVariant(int year, int avnr, Season season,
|
||||
Dictionary<string, string> attributes,
|
||||
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaCmtTypes,
|
||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes,
|
||||
PaymentVar paymentVar, PaymentBillingData data) :
|
||||
base(year, season, attributes, modifiers, areaCmtTypes) {
|
||||
base(year, season, attributes, modifiers, areaComTypes) {
|
||||
AvNr = avnr;
|
||||
PaymentVariant = paymentVar;
|
||||
Data = data;
|
||||
@@ -32,9 +32,9 @@ namespace Elwig.Helpers.Billing {
|
||||
|
||||
public static async Task<BillingVariant> Create(int year, int avnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
var (season, attributes, modifiers, areaCmtTypes) = await LoadData(ctx, year);
|
||||
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
||||
var (paymentVar, data) = await LoadData(ctx, year, avnr);
|
||||
return new BillingVariant(year, avnr, season, attributes, modifiers, areaCmtTypes, paymentVar, data);
|
||||
return new BillingVariant(year, avnr, season, attributes, modifiers, areaComTypes, paymentVar, data);
|
||||
}
|
||||
|
||||
public async Task Calculate(bool strictPrices = true, bool? honorContracted = null, bool? allowAttrsIntoLower = null, bool? avoidUnderDeliveries = null) {
|
||||
@@ -170,7 +170,7 @@ namespace Elwig.Helpers.Billing {
|
||||
|
||||
protected async Task CalculatePrices(SqliteConnection cnx, bool strict = true) {
|
||||
var invalid = new HashSet<string>();
|
||||
var parts = new List<(int Year, int DId, int DPNr, int BktNr, string SortId, string? AttrId, string? CultId, string Discr, int Value, double Oe, double Kmw, string QualId, bool AttrAreaCmt)>();
|
||||
var parts = new List<(int Year, int DId, int DPNr, int BktNr, string SortId, string? AttrId, string? CultId, string Discr, int Value, double Oe, double Kmw, string QualId, bool AttrAreaCom)>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"""
|
||||
SELECT d.year, d.did, d.dpnr, b.bktnr, d.sortid, d.attrid, d.cultid, b.discr, b.value, d.oe, d.kmw, d.qualid, COALESCE(a.area_com, TRUE)
|
||||
@@ -197,8 +197,8 @@ namespace Elwig.Helpers.Billing {
|
||||
continue;
|
||||
var unctrd = part.Discr == "_";
|
||||
var payAttrId = (part.Discr is "" or "_") ? null : part.Discr;
|
||||
var attrId = part.AttrAreaCmt ? payAttrId : part.AttrId;
|
||||
var ctrd = !unctrd && (payAttrId == attrId || !part.AttrAreaCmt);
|
||||
var attrId = part.AttrAreaCom ? payAttrId : part.AttrId;
|
||||
var ctrd = !unctrd && (payAttrId == attrId || !part.AttrAreaCom);
|
||||
decimal price = 0;
|
||||
try {
|
||||
price = Data.CalculatePrice(part.SortId, attrId, part.CultId, part.QualId, ctrd, part.Oe, part.Kmw);
|
||||
|
||||
@@ -61,7 +61,6 @@ namespace Elwig.Helpers {
|
||||
public int ModeBusinessShares;
|
||||
public bool HasRedWhite => ModeBusinessShares == 1;
|
||||
|
||||
public int ModeMemberDataSheetShares;
|
||||
public int ModeDeliveryNoteStats;
|
||||
public int ModeWineQualityStatistics;
|
||||
public int OrderingMemberList;
|
||||
@@ -128,10 +127,6 @@ namespace Elwig.Helpers {
|
||||
case "SIMPLE": ModeBusinessShares = 0; 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()) {
|
||||
case "NONE": ModeDeliveryNoteStats = 0; break;
|
||||
case "GA_ONLY": ModeDeliveryNoteStats = 1; break;
|
||||
@@ -214,11 +209,6 @@ namespace Elwig.Helpers {
|
||||
case 0: businessShares = "SIMPLE"; 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";
|
||||
switch (ModeDeliveryNoteStats) {
|
||||
case 0: deliveryNoteStats = "NONE"; break;
|
||||
@@ -289,7 +279,6 @@ namespace Elwig.Helpers {
|
||||
("CLIENT_ORGANIC_AUTHORITYCODE", OrganicAuthorityCode),
|
||||
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
|
||||
("MODE_BUSINESSSHARES", businessShares),
|
||||
("MODE_MEMBERDATASHEET_SHARES", memberDataSheetShares),
|
||||
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
|
||||
("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics),
|
||||
("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)>;
|
||||
|
||||
public class Bki : CsvFile<Row> {
|
||||
public class Bki : Csv<Row> {
|
||||
|
||||
private readonly string _clientData;
|
||||
|
||||
@@ -46,6 +46,10 @@ namespace Elwig.Helpers.Export {
|
||||
await ExportAsync(rows);
|
||||
}
|
||||
|
||||
public void Export(int year) {
|
||||
ExportAsync(year).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override string FormatRow(Row row) {
|
||||
var (member, delivery) = row;
|
||||
var (lfBisNr, familyName, name, billingName, address, plz, ort, vollablieferer, area) = member;
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Helpers.Export {
|
||||
public abstract class CsvFile<T> : IExporter<T> {
|
||||
public abstract class Csv<T> : IExporter<T> {
|
||||
|
||||
public static string FileExtension => "csv";
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace Elwig.Helpers.Export {
|
||||
protected readonly char Separator;
|
||||
protected string? Header;
|
||||
|
||||
public CsvFile(string filename, char separator = ';') :
|
||||
public Csv(string filename, char separator = ';') :
|
||||
this(filename, separator, Utils.UTF8) {
|
||||
}
|
||||
|
||||
public CsvFile(string filename, char separator, Encoding encoding) {
|
||||
public Csv(string filename, char separator, Encoding encoding) {
|
||||
_writer = new StreamWriter(filename, false, encoding);
|
||||
Separator = separator;
|
||||
}
|
||||
@@ -29,6 +29,11 @@ namespace Elwig.Helpers.Export {
|
||||
_writer.Dispose();
|
||||
}
|
||||
|
||||
public ValueTask DisposeAsync() {
|
||||
GC.SuppressFinalize(this);
|
||||
return _writer.DisposeAsync();
|
||||
}
|
||||
|
||||
public async Task ExportAsync(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||
progress?.Report(0.0);
|
||||
int count = data.Count() + 2, i = 0;
|
||||
@@ -45,6 +50,10 @@ namespace Elwig.Helpers.Export {
|
||||
progress?.Report(100.0);
|
||||
}
|
||||
|
||||
public void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||
ExportAsync(data, progress).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public string FormatRow(IEnumerable row) {
|
||||
return string.Join(Separator, row);
|
||||
}
|
||||
@@ -52,7 +61,7 @@ namespace Elwig.Helpers.Export {
|
||||
public abstract string FormatRow(T row);
|
||||
}
|
||||
|
||||
public class CsvSimple : CsvFile<IEnumerable<object?>> {
|
||||
public class CsvSimple : Csv<IEnumerable<object?>> {
|
||||
|
||||
public CsvSimple(string filename, char separator, Encoding encoding) :
|
||||
base(filename, separator, encoding) {
|
||||
@@ -9,7 +9,7 @@ using System.Security;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Helpers.Export {
|
||||
public class Ebics(PaymentVar variant, string filename, int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) : IExporter<Transaction> {
|
||||
public class Ebics(PaymentVar variant, string filename, int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) : IBankingExporter {
|
||||
|
||||
public enum AddressMode { Omit = 0, Lines = 1, Full = 2 }
|
||||
|
||||
@@ -28,6 +28,15 @@ namespace Elwig.Helpers.Export {
|
||||
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) {
|
||||
if (transactions.Any(tx => tx.Amount < 0)) {
|
||||
throw new ArgumentException("Tranaction amount may not be negative");
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,8 +63,8 @@ namespace Elwig.Helpers.Export {
|
||||
List<MemberTelNr> TelephoneNumbers,
|
||||
List<MemberEmailAddr> EmailAddresses,
|
||||
List<MemberHistory> MemberHistory,
|
||||
List<AreaCmt> AreaCommitments,
|
||||
List<AreaCmtContract> Contracts,
|
||||
List<AreaCom> AreaCommitments,
|
||||
List<AreaComContract> Contracts,
|
||||
List<WbRd> Riede,
|
||||
List<WbKg> WbKgs,
|
||||
List<WbGl> WbGls,
|
||||
@@ -75,7 +75,7 @@ namespace Elwig.Helpers.Export {
|
||||
|
||||
var metaData = new List<(string FileName, string ZwstId, string Device,
|
||||
int? MemberNum, string? MemberFilters,
|
||||
int? AreaCmtNum, string? AreaCmtFilters,
|
||||
int? AreaComNum, string? AreaComFilters,
|
||||
int? DeliveryNum, string? DeliveryFilters)>();
|
||||
|
||||
foreach (var filename in filenames) {
|
||||
@@ -105,14 +105,14 @@ namespace Elwig.Helpers.Export {
|
||||
var meta = await JsonNode.ParseAsync(metaJson!.Open());
|
||||
var memberCount = meta!["members"]?["count"]?.AsValue().GetValue<int>();
|
||||
var memberFilters = meta!["members"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||
var areaCmtCount = meta!["area_commitment_contracts"]?["count"]?.AsValue().GetValue<int>();
|
||||
var areaCmtFilters = meta!["area_commitment_contracts"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||
var areaComCount = meta!["area_commitment_contracts"]?["count"]?.AsValue().GetValue<int>();
|
||||
var areaComFilters = meta!["area_commitment_contracts"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||
var deliveryCount = meta!["deliveries"]?["count"]?.AsValue().GetValue<int>();
|
||||
var deliveryFilters = meta!["deliveries"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||
metaData.Add((Path.GetFileName(filename),
|
||||
meta["zwstid"]!.AsValue().GetValue<string>(), meta["device"]!.AsValue().GetValue<string>(),
|
||||
memberCount, memberFilters != null ? string.Join(" / ", memberFilters) : null,
|
||||
areaCmtCount, areaCmtFilters != null ? string.Join(" / ", areaCmtFilters) : null,
|
||||
areaComCount, areaComFilters != null ? string.Join(" / ", areaComFilters) : null,
|
||||
deliveryCount, deliveryFilters != null ? string.Join(" / ", deliveryFilters) : null));
|
||||
|
||||
var wbKgsJson = zip.GetEntry("wb_kgs.json");
|
||||
@@ -159,21 +159,21 @@ namespace Elwig.Helpers.Export {
|
||||
}
|
||||
|
||||
// legacy area commitments
|
||||
var areaCmtsJson = zip.GetEntry("area_commitments.json");
|
||||
if (areaCmtsJson != null) {
|
||||
using var reader = new StreamReader(areaCmtsJson.Open(), Utils.UTF8);
|
||||
var areaComsJson = zip.GetEntry("area_commitments.json");
|
||||
if (areaComsJson != null) {
|
||||
using var reader = new StreamReader(areaComsJson.Open(), Utils.UTF8);
|
||||
string? line;
|
||||
while ((line = await reader.ReadLineAsync()) != null) {
|
||||
var obj = JsonNode.Parse(line)!.AsObject();
|
||||
var (contract, areaCmt, wbrd, timestamps) = obj.ToAreaCmt(kgs, currentWbKgs, currentWbRde);
|
||||
var (contract, areaCom, wbrd, timestamps) = obj.ToAreaCom(kgs, currentWbKgs, currentWbRde);
|
||||
r.Contracts.Add(contract);
|
||||
r.AreaCommitments.Add(areaCmt);
|
||||
r.AreaCommitments.Add(areaCom);
|
||||
if (wbrd != null) {
|
||||
r.Riede.Add(wbrd);
|
||||
}
|
||||
if (timestamps.HasValue) {
|
||||
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||
r.Timestamps["area_commitment"].Add((areaCmt.FbNr, areaCmt.RevNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||
r.Timestamps["area_commitment"].Add((areaCom.FbNr, areaCom.RevNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,17 +184,17 @@ namespace Elwig.Helpers.Export {
|
||||
string? line;
|
||||
while ((line = await reader.ReadLineAsync()) != null) {
|
||||
var obj = JsonNode.Parse(line)!.AsObject();
|
||||
var (contract, areaCmts, wbrd, timestamps) = obj.ToAreaCmtContract(kgs, currentWbKgs, currentWbRde);
|
||||
var (contract, areaComs, wbrd, timestamps) = obj.ToAreaComContract(kgs, currentWbKgs, currentWbRde);
|
||||
r.Contracts.Add(contract);
|
||||
r.AreaCommitments.AddRange(areaCmts.Select(v => v.Item1));
|
||||
r.AreaCommitments.AddRange(areaComs.Select(v => v.Item1));
|
||||
if (wbrd != null) {
|
||||
r.Riede.Add(wbrd);
|
||||
}
|
||||
if (timestamps.HasValue)
|
||||
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||
foreach (var (areaCmt, ts) in areaCmts) {
|
||||
foreach (var (areaCom, ts) in areaComs) {
|
||||
if (!ts.HasValue) continue;
|
||||
r.Timestamps["area_commitment"].Add((areaCmt.FbNr, areaCmt.RevNr, 0, ts.Value.CreatedAt, ts.Value.ModifiedAt));
|
||||
r.Timestamps["area_commitment"].Add((areaCom.FbNr, areaCom.RevNr, 0, ts.Value.CreatedAt, ts.Value.ModifiedAt));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ namespace Elwig.Helpers.Export {
|
||||
}
|
||||
|
||||
var importedMembers = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||
var importedAreaCmts = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||
var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||
var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
||||
|
||||
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, history, areaCommitments, contracts, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
|
||||
@@ -365,7 +365,7 @@ namespace Elwig.Helpers.Export {
|
||||
ctx.AddRange(riede);
|
||||
var n = importNewContracts ? contracts.Count - duplicateFbNrs.Count : 0;
|
||||
var o = importDuplicateContracts ? duplicateFbNrs.Count : 0;
|
||||
importedAreaCmts.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, contracts.Count - n - o, meta.AreaCmtFilters));
|
||||
importedAreaComs.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, contracts.Count - n - o, meta.AreaComFilters));
|
||||
}
|
||||
|
||||
if (allowedDuplicateLsNrs.Count > 0) {
|
||||
@@ -447,8 +447,8 @@ namespace Elwig.Helpers.Export {
|
||||
$" ({d.New} neu, {d.Overwritten} überschrieben, {d.NotImported} nicht importiert)\n" +
|
||||
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
||||
$" Filter: {d.Filters}"),
|
||||
$"Flächenbindungen: {importedAreaCmts.Sum(d => d.New + d.Overwritten)}",
|
||||
..importedAreaCmts.Select(d =>
|
||||
$"Flächenbindungen: {importedAreaComs.Sum(d => d.New + d.Overwritten)}",
|
||||
..importedAreaComs.Select(d =>
|
||||
$" {d.FileName} ({d.New + d.Overwritten})\n" +
|
||||
$" ({d.New} importiert, {d.Overwritten} überschreiben, {d.NotImported} nicht importiert)\n" +
|
||||
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
||||
@@ -481,11 +481,11 @@ namespace Elwig.Helpers.Export {
|
||||
}.Export(filename);
|
||||
}
|
||||
|
||||
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<AreaCmtContract> areaCmts, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
|
||||
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
|
||||
return new ElwigExport {
|
||||
Members = (members, filters),
|
||||
History = (history, ["von exportierten Mitgliedern"]),
|
||||
AreaCmts = (areaCmts, ["von exportierten Mitgliedern"]),
|
||||
AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
|
||||
WbKgs = (wbKgs, ["von exportierten Mitgliedern und Flächenbindungen"]),
|
||||
}.Export(filename);
|
||||
}
|
||||
@@ -501,7 +501,7 @@ namespace Elwig.Helpers.Export {
|
||||
public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
|
||||
public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
|
||||
public (IEnumerable<MemberHistory> History, IEnumerable<string> Filters)? History { get; set; }
|
||||
public (IEnumerable<AreaCmtContract> AreaCmts, IEnumerable<string> Filters)? AreaCmts { get; set; }
|
||||
public (IEnumerable<AreaComContract> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; }
|
||||
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
|
||||
|
||||
public async Task Export(string filename) {
|
||||
@@ -535,11 +535,11 @@ namespace Elwig.Helpers.Export {
|
||||
["count"] = History.Value.History.Count(),
|
||||
["filters"] = new JsonArray(History.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||
};
|
||||
if (AreaCmts != null)
|
||||
if (AreaComs != null)
|
||||
obj["area_commitment_contracts"] = new JsonObject {
|
||||
["count"] = AreaCmts.Value.AreaCmts.Count(),
|
||||
["revisions"] = AreaCmts.Value.AreaCmts.Sum(c => c.Revisions.Count),
|
||||
["filters"] = new JsonArray(AreaCmts.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||
["count"] = AreaComs.Value.AreaComs.Count(),
|
||||
["revisions"] = AreaComs.Value.AreaComs.Sum(c => c.Revisions.Count),
|
||||
["filters"] = new JsonArray(AreaComs.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||
};
|
||||
if (Deliveries != null)
|
||||
obj["deliveries"] = new JsonObject {
|
||||
@@ -572,10 +572,10 @@ namespace Elwig.Helpers.Export {
|
||||
await writer.WriteLineAsync(h.ToJson().ToJsonString(Utils.JsonOpts));
|
||||
}
|
||||
}
|
||||
if (AreaCmts != null) {
|
||||
if (AreaComs != null) {
|
||||
var json = zip.CreateEntry("area_commitment_contracts.json", CompressionLevel.SmallestSize);
|
||||
using var writer = new StreamWriter(json.Open(), Utils.UTF8);
|
||||
foreach (var c in AreaCmts.Value.AreaCmts) {
|
||||
foreach (var c in AreaComs.Value.AreaComs) {
|
||||
await writer.WriteLineAsync(c.ToJson().ToJsonString(Utils.JsonOpts));
|
||||
}
|
||||
}
|
||||
@@ -796,7 +796,7 @@ namespace Elwig.Helpers.Export {
|
||||
};
|
||||
}
|
||||
|
||||
public static JsonObject ToJson(this AreaCmtContract c) {
|
||||
public static JsonObject ToJson(this AreaComContract c) {
|
||||
return new JsonObject {
|
||||
["fbnr"] = c.FbNr,
|
||||
["kgnr"] = c.KgNr,
|
||||
@@ -808,7 +808,7 @@ namespace Elwig.Helpers.Export {
|
||||
};
|
||||
}
|
||||
|
||||
private static JsonObject ToJson(this AreaCmt c) {
|
||||
private static JsonObject ToJson(this AreaCom c) {
|
||||
return new JsonObject {
|
||||
["revnr"] = c.RevNr,
|
||||
["mgnr"] = c.MgNr,
|
||||
@@ -823,7 +823,7 @@ namespace Elwig.Helpers.Export {
|
||||
};
|
||||
}
|
||||
|
||||
public static (AreaCmtContract, List<(AreaCmt, (DateTime CreatedAt, DateTime ModifiedAt)?)>, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCmtContract(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||
public static (AreaComContract, List<(AreaCom, (DateTime CreatedAt, DateTime ModifiedAt)?)>, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaComContract(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
||||
var ried = json["ried"]?.AsValue().GetValue<string>();
|
||||
var fbnr = json["fbnr"]!.AsValue()!.GetValue<int>();
|
||||
@@ -848,16 +848,16 @@ namespace Elwig.Helpers.Export {
|
||||
}
|
||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||
return (new AreaCmtContract {
|
||||
return (new AreaComContract {
|
||||
FbNr = fbnr,
|
||||
KgNr = kgnr,
|
||||
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||
ImportedAt = DateTime.Now,
|
||||
}, [.. json["revisions"]!.AsArray().Select(r => r!.AsObject()).Select<JsonObject, (AreaCmt, (DateTime, DateTime)?)>(r => {
|
||||
}, [.. json["revisions"]!.AsArray().Select(r => r!.AsObject()).Select<JsonObject, (AreaCom, (DateTime, DateTime)?)>(r => {
|
||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||
return (new AreaCmt {
|
||||
return (new AreaCom {
|
||||
FbNr = fbnr,
|
||||
RevNr = r["revnr"]!.AsValue().GetValue<int>(),
|
||||
MgNr = r["mgnr"]!.AsValue().GetValue<int>(),
|
||||
@@ -877,7 +877,7 @@ namespace Elwig.Helpers.Export {
|
||||
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
|
||||
}
|
||||
|
||||
public static (AreaCmtContract, AreaCmt, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCmt(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||
public static (AreaComContract, AreaCom, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCom(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
||||
var ried = json["ried"]?.AsValue().GetValue<string>();
|
||||
if (!currentWbKgs.Values.Any(k => k.KgNr == kgnr)) {
|
||||
@@ -901,13 +901,13 @@ namespace Elwig.Helpers.Export {
|
||||
}
|
||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||
return (new AreaCmtContract {
|
||||
return (new AreaComContract {
|
||||
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
||||
KgNr = kgnr,
|
||||
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||
ImportedAt = DateTime.Now,
|
||||
}, new AreaCmt {
|
||||
}, new AreaCom {
|
||||
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
||||
RevNr = 1,
|
||||
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
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;
|
||||
|
||||
namespace Elwig.Helpers.Export {
|
||||
public interface IExporter<T> : IDisposable {
|
||||
public interface IExporter<T> : IDisposable, IAsyncDisposable {
|
||||
/// <summary>
|
||||
/// The default file extension of the exported files to be used (whithout a preceding ".")
|
||||
/// </summary>
|
||||
@@ -14,9 +14,7 @@ namespace Elwig.Helpers.Export {
|
||||
/// </summary>
|
||||
/// <param name="data">The data to be exported</param>
|
||||
/// <param name="progress">The progress object to report to</param>
|
||||
void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||
ExportAsync(data, progress).GetAwaiter().GetResult();
|
||||
}
|
||||
void Export(IEnumerable<T> data, IProgress<double>? progress = null);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronosly export the given data to the given file.
|
||||
|
||||
@@ -109,13 +109,8 @@ namespace Elwig.Helpers.Export {
|
||||
<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: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:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle" fo:wrap-option="wrap"/>
|
||||
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle"/>
|
||||
<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:style>
|
||||
@@ -216,59 +211,35 @@ namespace Elwig.Helpers.Export {
|
||||
}
|
||||
}
|
||||
|
||||
await Content.WriteAsync($"""
|
||||
<table:table-row>
|
||||
{FormatCell(table.FullName, colSpan: totalSpan, style: "header")}
|
||||
</table:table-row>
|
||||
<table:table-row>
|
||||
{FormatCell(table.Subtitle, colSpan: totalSpan, style: "subheader")}
|
||||
</table:table-row>
|
||||
<table:table-row>
|
||||
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||
</table:table-row>
|
||||
""");
|
||||
await Content.WriteAsync(
|
||||
$" <table:table-row>\r\n" +
|
||||
FormatCell(table.FullName, colSpan: totalSpan, style: "header") +
|
||||
$" </table:table-row>\r\n" +
|
||||
$" <table:table-row>\r\n" +
|
||||
FormatCell(table.Subtitle, colSpan: totalSpan, style: "subheader") +
|
||||
$" </table:table-row>\r\n" +
|
||||
$" <table:table-row>\r\n" +
|
||||
$" <table:table-cell table:number-columns-repeated=\"{totalSpan}\"/>\r\n" +
|
||||
$" </table:table-row>\r\n" +
|
||||
$" <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");
|
||||
|
||||
var firstSection = true;
|
||||
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;
|
||||
foreach (var row in table.GetData()) {
|
||||
await FormatRow(row, table.ColumnUnits, mergeSubRowCells);
|
||||
}
|
||||
|
||||
await Content.WriteAsync(" </table:table>\r\n");
|
||||
@@ -343,8 +314,7 @@ 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}>";
|
||||
} else {
|
||||
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}>";
|
||||
c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}><text:p>{SecurityElement.Escape(data.ToString())}</text:p></{ct}>";
|
||||
}
|
||||
|
||||
return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-columns-repeated=\"{colSpan - 1}\"/>\r\n" : "");
|
||||
@@ -13,9 +13,7 @@ namespace Elwig.Helpers.Export {
|
||||
|
||||
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) {
|
||||
_writer = new StreamWriter(filename, false, encoding);
|
||||
@@ -26,6 +24,11 @@ namespace Elwig.Helpers.Export {
|
||||
_writer.Dispose();
|
||||
}
|
||||
|
||||
public ValueTask DisposeAsync() {
|
||||
GC.SuppressFinalize(this);
|
||||
return _writer.DisposeAsync();
|
||||
}
|
||||
|
||||
public async Task ExportAsync(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
||||
progress?.Report(0.0);
|
||||
int count = data.Count() + 1, i = 0;
|
||||
@@ -55,6 +58,10 @@ namespace Elwig.Helpers.Export {
|
||||
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) {
|
||||
return text?.Replace("\\", "\\\\").Replace(",", "\\,").Replace(";", "\\;").Replace("\n", "\\n").Replace("\r", "");
|
||||
}
|
||||
|
||||
+19
-22
@@ -483,20 +483,12 @@ namespace Elwig.Helpers {
|
||||
return InternetGetConnectedState(out var _, 0);
|
||||
}
|
||||
|
||||
public static string ReplaceUmlaute(string s) {
|
||||
return s
|
||||
.Replace("ä", "ae").Replace("Ä", "Ae")
|
||||
.Replace("ö", "oe").Replace("Ö", "Oe")
|
||||
.Replace("ü", "ue").Replace("Ü", "Ue")
|
||||
.Replace("ß", "ss").Replace("ẞ", "SS");
|
||||
}
|
||||
|
||||
public static HttpClient GetHttpClient(string? username = null, string? password = null, string? accept = null) {
|
||||
var client = new HttpClient() {
|
||||
Timeout = TimeSpan.FromSeconds(5),
|
||||
};
|
||||
client.DefaultRequestHeaders.UserAgent.Clear();
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd($"Elwig/{App.Version} ({App.Client?.NameToken}, {ReplaceUmlaute(App.BranchName)}, {Environment.MachineName}, {Environment.OSVersion})");
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd($"Elwig/{App.Version} ({App.Client?.NameToken}, {App.BranchName}, {Environment.MachineName}, {Environment.OSVersion})");
|
||||
client.DefaultRequestHeaders.Accept.Clear();
|
||||
if (accept != null)
|
||||
client.DefaultRequestHeaders.Accept.Add(new(accept));
|
||||
@@ -505,13 +497,18 @@ namespace Elwig.Helpers {
|
||||
return client;
|
||||
}
|
||||
|
||||
public static async Task<(string Version, string Url, long Size)> GetLatestInstallerUrl(string url) {
|
||||
using var client = GetHttpClient(accept: "application/json");
|
||||
using var res = await client.GetAsync(url);
|
||||
res.EnsureSuccessStatusCode();
|
||||
var resJson = JsonNode.Parse(await res.Content.ReadAsStringAsync());
|
||||
var data = resJson!["data"]!.AsArray()[^1]!;
|
||||
return ((string)data["version"]!, (string)data["url"]!, (long)data["size"]!);
|
||||
public static async Task<(string Version, string Url, long Size)?> GetLatestInstallerUrl(string url) {
|
||||
try {
|
||||
using var client = GetHttpClient(accept: "application/json");
|
||||
using var res = await client.GetAsync(url);
|
||||
if (!res.IsSuccessStatusCode)
|
||||
return null;
|
||||
var resJson = JsonNode.Parse(await res.Content.ReadAsStringAsync());
|
||||
var data = resJson!["data"]!.AsArray()[^1]!;
|
||||
return ((string)data["version"]!, (string)data["url"]!, (long)data["size"]!);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task UploadExportData(string zip, string url, string username, string password) {
|
||||
@@ -665,16 +662,16 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
}
|
||||
|
||||
public static Expression<Func<AreaCmt, bool>> ActiveAreaCommitments() => ActiveAreaCommitments(CurrentYear);
|
||||
public static Expression<Func<AreaCmt, bool>> ActiveAreaCommitments(int year) =>
|
||||
public static Expression<Func<AreaCom, bool>> ActiveAreaCommitments() => ActiveAreaCommitments(CurrentYear);
|
||||
public static Expression<Func<AreaCom, bool>> ActiveAreaCommitments(int year) =>
|
||||
c => (c.YearFrom == null || c.YearFrom <= year) && (c.YearTo == null || c.YearTo >= year);
|
||||
|
||||
public static IQueryable<AreaCmt> ActiveAreaCommitments(IQueryable<AreaCmt> query) => ActiveAreaCommitments(query, CurrentYear);
|
||||
public static IQueryable<AreaCmt> ActiveAreaCommitments(IQueryable<AreaCmt> query, int year) =>
|
||||
public static IQueryable<AreaCom> ActiveAreaCommitments(IQueryable<AreaCom> query) => ActiveAreaCommitments(query, CurrentYear);
|
||||
public static IQueryable<AreaCom> ActiveAreaCommitments(IQueryable<AreaCom> query, int year) =>
|
||||
query.Where(ActiveAreaCommitments(year));
|
||||
|
||||
public static IEnumerable<AreaCmt> ActiveAreaCommitments(IEnumerable<AreaCmt> query) => ActiveAreaCommitments(query, CurrentYear);
|
||||
public static IEnumerable<AreaCmt> ActiveAreaCommitments(IEnumerable<AreaCmt> query, int year) =>
|
||||
public static IEnumerable<AreaCom> ActiveAreaCommitments(IEnumerable<AreaCom> query) => ActiveAreaCommitments(query, CurrentYear);
|
||||
public static IEnumerable<AreaCom> ActiveAreaCommitments(IEnumerable<AreaCom> query, int year) =>
|
||||
query.Where(c => ActiveAreaCommitments(year).Invoke(c));
|
||||
|
||||
public static async Task<(DateTime DateTime, string Type, int MgNr, string Name, string[] Addresses, string Subject, string[] Attachments)[]> GetSentMails(DateOnly? fromDate = null, DateOnly? toDate = null) {
|
||||
|
||||
@@ -577,7 +577,7 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
}
|
||||
|
||||
public static ValidationResult CheckFbNr(TextBox input, bool required, AreaCmtContract? c) {
|
||||
public static ValidationResult CheckFbNr(TextBox input, bool required, AreaComContract? c) {
|
||||
var res = CheckInteger(input, required);
|
||||
if (!res.IsValid) {
|
||||
return res;
|
||||
|
||||
+9
-9
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Models.Dtos {
|
||||
public class AreaCmtUnderDeliveryData : DataTable<AreaCmtUnderDeliveryRow> {
|
||||
public class AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
|
||||
|
||||
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||
("MgNr", "MgNr.", null, 12),
|
||||
@@ -21,19 +21,19 @@ namespace Elwig.Models.Dtos {
|
||||
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
||||
];
|
||||
|
||||
public AreaCmtUnderDeliveryData(IEnumerable<AreaCmtUnderDeliveryRow> rows, int year) :
|
||||
public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
|
||||
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
||||
}
|
||||
|
||||
public static async Task<AreaCmtUnderDeliveryData> ForSeason(DbSet<AreaCmtUnderDeliveryRowSingle> table, int year) {
|
||||
return new AreaCmtUnderDeliveryData(
|
||||
public static async Task<AreaComUnderDeliveryData> ForSeason(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
|
||||
return new AreaComUnderDeliveryData(
|
||||
(await FromDbSet(table, year)).GroupBy(
|
||||
r => r.MgNr,
|
||||
(k, g) => new AreaCmtUnderDeliveryRow(g)
|
||||
(k, g) => new AreaComUnderDeliveryRow(g)
|
||||
), year);
|
||||
}
|
||||
|
||||
private static async Task<IEnumerable<AreaCmtUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaCmtUnderDeliveryRowSingle> table, int year) {
|
||||
private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
|
||||
return await table.FromSql($"""
|
||||
SELECT m.mgnr, m.name AS name_1,
|
||||
COALESCE(m.prefix || ' ', '') || m.given_name ||
|
||||
@@ -51,7 +51,7 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
}
|
||||
|
||||
public class AreaCmtUnderDeliveryRow {
|
||||
public class AreaComUnderDeliveryRow {
|
||||
public int MgNr;
|
||||
public string Name1;
|
||||
public string? Name2;
|
||||
@@ -66,7 +66,7 @@ namespace Elwig.Models.Dtos {
|
||||
.Select(v => v.First < v.Second ? ((int?, double?))(v.First - v.Second, v.First * 100.0 / v.Second - 100.0) : (null, null))
|
||||
.ToArray();
|
||||
|
||||
public AreaCmtUnderDeliveryRow(IEnumerable<AreaCmtUnderDeliveryRowSingle> rows) {
|
||||
public AreaComUnderDeliveryRow(IEnumerable<AreaComUnderDeliveryRowSingle> rows) {
|
||||
var f = rows.First();
|
||||
MgNr = f.MgNr;
|
||||
Name1 = f.Name1;
|
||||
@@ -82,7 +82,7 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
|
||||
[Keyless]
|
||||
public class AreaCmtUnderDeliveryRowSingle {
|
||||
public class AreaComUnderDeliveryRowSingle {
|
||||
[Column("mgnr")]
|
||||
public int MgNr { get; set; }
|
||||
[Column("name_1")]
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -10,14 +9,13 @@ namespace Elwig.Models.Dtos {
|
||||
public string Name { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public string? Subtitle { get; set; }
|
||||
public IEnumerable<(string? Name, IEnumerable<T> Rows)> Sections { get; private set; }
|
||||
public IEnumerable<T> Rows => Sections.SelectMany(s => s.Rows);
|
||||
public IEnumerable<T> Rows { get; private set; }
|
||||
public int RowNum => Rows.Count();
|
||||
public int ColNum => ColumnNames.Count();
|
||||
|
||||
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.Name);
|
||||
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Type);
|
||||
public IEnumerable<(string, Type?)> ColumnDefs => _map.Select(m => (m.Item1, m.Item2?.PropertyType ?? m.Item3?.FieldType));
|
||||
public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Item1);
|
||||
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Item2);
|
||||
public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
|
||||
public IEnumerable<int> ColumnSpans { get; private set; }
|
||||
public IEnumerable<int?> ColumnWidths { get; private set; }
|
||||
@@ -25,87 +23,70 @@ namespace Elwig.Models.Dtos {
|
||||
|
||||
private readonly PropertyInfo[] _properties;
|
||||
private readonly FieldInfo[] _fields;
|
||||
private readonly (string Name, PropertyInfo? PInfo, FieldInfo? FInfo)[] _map;
|
||||
private readonly (string, PropertyInfo?, FieldInfo?)[] _map;
|
||||
|
||||
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, sections, colNames) {
|
||||
public DataTable(string name, string fullName, string subtitle, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
|
||||
this(name, fullName, rows, colNames) {
|
||||
Subtitle = subtitle;
|
||||
}
|
||||
|
||||
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) {
|
||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) {
|
||||
_fields = typeof(T).GetFields();
|
||||
_properties = typeof(T).GetProperties();
|
||||
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.Name, _properties.FirstOrDefault(p => p?.Name == n.Property, null), _fields.FirstOrDefault(f => f?.Name == n.Property, null)))];
|
||||
colNames ??= _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null)).ToList();
|
||||
_map = colNames.Select(n => (n.Item2, _properties.FirstOrDefault(p => p?.Name == n.Item1, null), _fields.FirstOrDefault(f => f?.Name == n.Item1, null))).ToArray();
|
||||
Name = name;
|
||||
FullName = fullName;
|
||||
Sections = sections;
|
||||
ColumnFlatTypes = [.. ColumnTypes.SelectMany(type => {
|
||||
Rows = rows;
|
||||
ColumnFlatTypes = ColumnTypes.SelectMany(type => {
|
||||
var elType = type?.GetElementType();
|
||||
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 => (Type?)f.FieldType) :
|
||||
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => f.FieldType) :
|
||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => f.FieldType) :
|
||||
[type];
|
||||
})];
|
||||
ColumnSpans = [.. ColumnTypes.Select(type => {
|
||||
}).ToList();
|
||||
ColumnSpans = ColumnTypes.Select(type => {
|
||||
var elType = type?.GetElementType();
|
||||
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;
|
||||
})];
|
||||
ColumnWidths = [.. colNames.Select(c => c.Width)];
|
||||
ColumnUnits = [.. colNames.Select(c => c.Unit?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? [])];
|
||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length : 1;
|
||||
}).ToList();
|
||||
ColumnWidths = colNames.Select(c => c.Item4).ToList();
|
||||
ColumnUnits = colNames.Select(c => c.Item3?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? []).ToList();
|
||||
}
|
||||
|
||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||
this(name, fullName, [(null, rows)], colNames) {
|
||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
|
||||
this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)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) :
|
||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
|
||||
this(name, name, rows, colNames) {
|
||||
}
|
||||
|
||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
|
||||
this(name, name, rows, colNames) {
|
||||
}
|
||||
|
||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
|
||||
this(name, name, rows, colNames) {
|
||||
}
|
||||
|
||||
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, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
|
||||
this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)c.Item4))) {
|
||||
}
|
||||
|
||||
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
||||
protected IEnumerable<(string, object?)> GetNamedRowData(T row) {
|
||||
return _map.Select(i => (i.Item1, i.Item2?.GetValue(row) ?? i.Item3?.GetValue(row)));
|
||||
}
|
||||
|
||||
protected IEnumerable<(string Name, object? Value)> GetNamedRowValues(T row) {
|
||||
return _map.Select(i => (i.Name, i.PInfo?.GetValue(row) ?? i.FInfo?.GetValue(row)));
|
||||
protected IEnumerable<object?> GetRowData(T row) {
|
||||
return GetNamedRowData(row).Select(i => i.Item2);
|
||||
}
|
||||
|
||||
protected IEnumerable<object?> GetRowValues(T row) {
|
||||
return GetNamedRowValues(row).Select(i => i.Value);
|
||||
public IEnumerable<IEnumerable<object?>> GetData() {
|
||||
return Rows.Select(GetRowData);
|
||||
}
|
||||
|
||||
public IEnumerable<(string? Name, IEnumerable<IEnumerable<object?>> Rows)> GetData() {
|
||||
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)));
|
||||
public IEnumerable<IEnumerable<(string, object?)>> GetNamedData() {
|
||||
return Rows.Select(GetNamedRowData);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Models.Dtos {
|
||||
class MemberAreaCmtTotalsData : DataTable<MemberAreaCmtTotalsRow> {
|
||||
class MemberAreaComTotalsData : DataTable<MemberAreaComTotalsRow> {
|
||||
|
||||
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||
("MgNr", "MgNr.", null, 12),
|
||||
@@ -21,19 +21,19 @@ namespace Elwig.Models.Dtos {
|
||||
("DeliveryRights", "Lieferrecht", "kg", 22),
|
||||
];
|
||||
|
||||
public MemberAreaCmtTotalsData(IEnumerable<MemberAreaCmtTotalsRow> rows, int year) :
|
||||
public MemberAreaComTotalsData(IEnumerable<MemberAreaComTotalsRow> rows, int year) :
|
||||
base($"Gebundene Fläche", $"Gebundene Fläche pro Mitglied {year}", rows, FieldNames) {
|
||||
}
|
||||
|
||||
public static async Task<MemberAreaCmtTotalsData> ForSeason(DbSet<MemberAreaCmtTotalsRowSingle> table, int year) {
|
||||
return new MemberAreaCmtTotalsData(
|
||||
public static async Task<MemberAreaComTotalsData> ForSeason(DbSet<MemberAreaComTotalsRowSingle> table, int year) {
|
||||
return new MemberAreaComTotalsData(
|
||||
(await FromDbSet(table, year)).GroupBy(
|
||||
r => r.MgNr,
|
||||
(k, g) => new MemberAreaCmtTotalsRow(g)
|
||||
(k, g) => new MemberAreaComTotalsRow(g)
|
||||
), year);
|
||||
}
|
||||
|
||||
private static async Task<IEnumerable<MemberAreaCmtTotalsRowSingle>> FromDbSet(DbSet<MemberAreaCmtTotalsRowSingle> table, int year) {
|
||||
private static async Task<IEnumerable<MemberAreaComTotalsRowSingle>> FromDbSet(DbSet<MemberAreaComTotalsRowSingle> table, int year) {
|
||||
return await table.FromSql($"""
|
||||
SELECT m.mgnr, m.name AS name_1,
|
||||
COALESCE(m.prefix || ' ', '') || m.given_name ||
|
||||
@@ -50,7 +50,7 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
}
|
||||
|
||||
public class MemberAreaCmtTotalsRow {
|
||||
public class MemberAreaComTotalsRow {
|
||||
public int MgNr;
|
||||
public string Name1;
|
||||
public string? Name2;
|
||||
@@ -63,7 +63,7 @@ namespace Elwig.Models.Dtos {
|
||||
public int[] DeliveryObligations;
|
||||
public int[] DeliveryRights;
|
||||
|
||||
public MemberAreaCmtTotalsRow(IEnumerable<MemberAreaCmtTotalsRowSingle> rows) {
|
||||
public MemberAreaComTotalsRow(IEnumerable<MemberAreaComTotalsRowSingle> rows) {
|
||||
var f = rows.First();
|
||||
MgNr = f.MgNr;
|
||||
Name1 = f.Name1;
|
||||
@@ -80,7 +80,7 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
|
||||
[Keyless]
|
||||
public class MemberAreaCmtTotalsRowSingle {
|
||||
public class MemberAreaComTotalsRowSingle {
|
||||
[Column("mgnr")]
|
||||
public int MgNr { get; set; }
|
||||
[Column("name_1")]
|
||||
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Models.Dtos {
|
||||
class MemberAreaCmtsData : DataTable<MemberAreaCmtsRow> {
|
||||
class MemberAreaComsData : DataTable<MemberAreaComsRow> {
|
||||
|
||||
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||
("MgNr", "MgNr.", null, 12),
|
||||
@@ -23,15 +23,15 @@ namespace Elwig.Models.Dtos {
|
||||
("MaxKg", "Lieferrecht", "kg", 22),
|
||||
];
|
||||
|
||||
public MemberAreaCmtsData(IEnumerable<MemberAreaCmtsRow> rows, int year) :
|
||||
public MemberAreaComsData(IEnumerable<MemberAreaComsRow> rows, int year) :
|
||||
base($"Flächenbindungen", $"Flächenbindungen pro Mitglied {year}", rows, FieldNames) {
|
||||
}
|
||||
|
||||
public static async Task<MemberAreaCmtsData> ForSeason(DbSet<MemberAreaCmtsRow> table, int year) {
|
||||
return new MemberAreaCmtsData(await FromDbSet(table, year), year);
|
||||
public static async Task<MemberAreaComsData> ForSeason(DbSet<MemberAreaComsRow> table, int year) {
|
||||
return new MemberAreaComsData(await FromDbSet(table, year), year);
|
||||
}
|
||||
|
||||
private static async Task<IEnumerable<MemberAreaCmtsRow>> FromDbSet(DbSet<MemberAreaCmtsRow> table, int year) {
|
||||
private static async Task<IEnumerable<MemberAreaComsRow>> FromDbSet(DbSet<MemberAreaComsRow> table, int year) {
|
||||
return await table.FromSql($"""
|
||||
SELECT m.mgnr, m.name AS name_1,
|
||||
COALESCE(m.prefix || ' ', '') || m.given_name ||
|
||||
@@ -56,7 +56,7 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
|
||||
[Keyless]
|
||||
public class MemberAreaCmtsRow {
|
||||
public class MemberAreaComsRow {
|
||||
[Column("mgnr")]
|
||||
public int MgNr { get; set; }
|
||||
[Column("name_1")]
|
||||
@@ -46,15 +46,15 @@ namespace Elwig.Models.Dtos {
|
||||
base(MemberList.Name, MemberList.Name, string.Join(" / ", filterNames), rows, FieldNames) {
|
||||
}
|
||||
|
||||
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCmt) {
|
||||
var areaCmts = await query.Include(m => m.AreaCommitments).ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
||||
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCom) {
|
||||
var areaComs = await query.Include(m => m.AreaCommitments).ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
||||
return new((await query
|
||||
.Include(m => m.Branch)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.ToListAsync()).Select(m => new MemberListRow(m,
|
||||
areaCmts[m.MgNr].Sum(c => c.Area),
|
||||
areaCmts[m.MgNr].Where(c => filterAreaCmt.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
||||
areaComs[m.MgNr].Sum(c => c.Area),
|
||||
areaComs[m.MgNr].Where(c => filterAreaCom.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
||||
filterNames);
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ namespace Elwig.Models.Dtos {
|
||||
public string? AdditionalContact;
|
||||
public string? Comment;
|
||||
|
||||
public MemberListRow(Member m, int? areaCmt = null, Dictionary<string, int>? filtered = null) {
|
||||
public MemberListRow(Member m, int? areaCom = null, Dictionary<string, int>? filtered = null) {
|
||||
MgNr = m.MgNr;
|
||||
Name1 = m.Name;
|
||||
AdminName1 = m.AdministrativeName1;
|
||||
@@ -133,7 +133,7 @@ namespace Elwig.Models.Dtos {
|
||||
.Distinct()
|
||||
.Concat(m.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).Except([EmailAddress])));
|
||||
Comment = m.Comment;
|
||||
AreaCommitment = areaCmt == 0 ? null : areaCmt;
|
||||
AreaCommitment = areaCom == 0 ? null : areaCom;
|
||||
AreaCommitmentsFiltered = filtered != null ? filtered.OrderBy(f => f.Key).Select(f => (f.Key, f.Value)).ToArray() : [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
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,9 +20,6 @@ namespace Elwig.Models.Entities {
|
||||
[Column("dest")]
|
||||
public string Dest { get; private set; } = null!;
|
||||
|
||||
[NotMapped]
|
||||
public string FullDest => $"{Ort.Name} ({Dest})";
|
||||
|
||||
[ForeignKey("Plz")]
|
||||
public virtual AT_Plz AtPlz { get; private set; } = null!;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Elwig.Models.Entities {
|
||||
[Table("area_commitment"), PrimaryKey("FbNr", "RevNr")]
|
||||
public class AreaCmt {
|
||||
public class AreaCom {
|
||||
[Column("fbnr")]
|
||||
public int FbNr { get; set; }
|
||||
|
||||
@@ -65,13 +65,13 @@ namespace Elwig.Models.Entities {
|
||||
}
|
||||
|
||||
[ForeignKey("FbNr")]
|
||||
public virtual AreaCmtContract Contract { get; private set; } = null!;
|
||||
public virtual AreaComContract Contract { get; private set; } = null!;
|
||||
|
||||
[ForeignKey("MgNr")]
|
||||
public virtual Member Member { get; private set; } = null!;
|
||||
|
||||
[ForeignKey("VtrgId")]
|
||||
public virtual AreaCmtType AreaCmtType { get; private set; } = null!;
|
||||
public virtual AreaComType AreaComType { get; private set; } = null!;
|
||||
|
||||
[ForeignKey("CultId")]
|
||||
public virtual WineCult? WineCult { get; private set; }
|
||||
@@ -7,7 +7,7 @@ using System.Linq;
|
||||
|
||||
namespace Elwig.Models.Entities {
|
||||
[Table("area_commitment_contract"), PrimaryKey("FbNr")]
|
||||
public class AreaCmtContract {
|
||||
public class AreaComContract {
|
||||
[Column("fbnr")]
|
||||
public int FbNr { get; set; }
|
||||
|
||||
@@ -58,11 +58,11 @@ namespace Elwig.Models.Entities {
|
||||
[ForeignKey("KgNr, RdNr")]
|
||||
public virtual WbRd? Rd { get; private set; }
|
||||
|
||||
[InverseProperty(nameof(AreaCmt.Contract))]
|
||||
public virtual ICollection<AreaCmt> Revisions { get; private set; } = null!;
|
||||
[InverseProperty(nameof(AreaCom.Contract))]
|
||||
public virtual ICollection<AreaCom> Revisions { get; private set; } = null!;
|
||||
|
||||
[NotMapped]
|
||||
public AreaCmt? Latest => Revisions.OrderBy(r => r.RevNr).LastOrDefault();
|
||||
public AreaCom? Latest => Revisions.OrderBy(r => r.RevNr).LastOrDefault();
|
||||
|
||||
[NotMapped]
|
||||
public int? YearFrom => Revisions.Any(r => r.YearFrom == null) ? null : Revisions.Min(r => r.YearFrom);
|
||||
@@ -5,7 +5,7 @@ using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
|
||||
|
||||
namespace Elwig.Models.Entities {
|
||||
[Table("area_commitment_type"), PrimaryKey("VtrgId"), Index("SortId", "AttrId", "Discriminator", IsUnique = true)]
|
||||
public class AreaCmtType {
|
||||
public class AreaComType {
|
||||
[Column("vtrgid")]
|
||||
public required string VtrgId { get; set; }
|
||||
|
||||
@@ -199,10 +199,10 @@ namespace Elwig.Models.Entities {
|
||||
[ForeignKey("ZwstId")]
|
||||
public virtual Branch? Branch { get; private set; }
|
||||
|
||||
[InverseProperty(nameof(AreaCmt.Member))]
|
||||
public virtual ICollection<AreaCmt> AreaCommitments { get; private set; } = null!;
|
||||
[InverseProperty(nameof(AreaCom.Member))]
|
||||
public virtual ICollection<AreaCom> AreaCommitments { get; private set; } = null!;
|
||||
|
||||
public IQueryable<AreaCmt> ActiveAreaCommitments(AppDbContext ctx, int? year = null) {
|
||||
public IQueryable<AreaCom> ActiveAreaCommitments(AppDbContext ctx, int? year = null) {
|
||||
return ctx.AreaCommitments.Where(c => c.MgNr == MgNr).Where(Utils.ActiveAreaCommitments(year ?? Utils.CurrentYear));
|
||||
}
|
||||
|
||||
|
||||
@@ -104,10 +104,10 @@ namespace Elwig.Models.Entities {
|
||||
|
||||
public string FormatReasonPhrase(int mgnr) {
|
||||
if (Reason == REASON_TRANSFER) {
|
||||
if (ToMgNr == mgnr) {
|
||||
return $"{ReasonPretty} von {FromMember?.FullAdministrativeName ?? "Vorgänger"}" + (Comment != null ? $", {Comment}" : "");
|
||||
} else if (FromMgNr == mgnr) {
|
||||
if (FromMgNr == mgnr) {
|
||||
return $"{ReasonPretty} an {ToMember?.FullAdministrativeName ?? "Nachfolger"}" + (Comment != null ? $", {Comment}" : "");
|
||||
} else if (ToMgNr == mgnr) {
|
||||
return $"{ReasonPretty} von {FromMember?.FullAdministrativeName ?? "Vorgänger"}" + (Comment != null ? $", {Comment}" : "");
|
||||
}
|
||||
}
|
||||
return ReasonPretty + (Comment != null ? $", {Comment}" : "");
|
||||
|
||||
@@ -92,13 +92,13 @@
|
||||
{"$ref": "#/definitions/curve_data"}
|
||||
]
|
||||
},
|
||||
"ctrd": {
|
||||
"geb": {
|
||||
"anyOf": [
|
||||
{"type": "number"},
|
||||
{"$ref": "#/definitions/curve_data"}
|
||||
]
|
||||
},
|
||||
"geb": {
|
||||
"contracted": {
|
||||
"anyOf": [
|
||||
{"type": "number"},
|
||||
{"$ref": "#/definitions/curve_data"}
|
||||
|
||||
@@ -14,7 +14,7 @@ PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_schema SET sql = REPLACE(REPLACE(REPLACE(sql, 'funktionär', 'officer '), 'buchführend', 'accounting '), 'volllieferant', 'full_delivery')
|
||||
WHERE type = 'table' AND name = 'member';
|
||||
|
||||
UPDATE sqlite_schema SET sql = REPLACE(sql, 'gebunden', 'contracted')
|
||||
UPDATE sqlite_schema SET sql = REPLACE(sql, 'gebunden ', 'contracted')
|
||||
WHERE type = 'table' AND name = 'delivery_part';
|
||||
|
||||
UPDATE sqlite_schema SET sql = REPLACE(sql, 'gebunden', 'contracted')
|
||||
@@ -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_email_address SET comment = NULL WHERE comment = '';
|
||||
|
||||
UPDATE member SET address = CONCAT('Untere Weißgerberstraße ', SUBSTR(address, 21)) WHERE address LIKE 'U. Weißgasse 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 SET address = 'Untere Weißgerberstraße' WHERE address = '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 = 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))
|
||||
|
||||
@@ -8,9 +8,9 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Elwig.Services {
|
||||
public static class AreaCmtService {
|
||||
public static class AreaComService {
|
||||
|
||||
public static async Task InitInputs(this AreaCmtAdminViewModel vm) {
|
||||
public static async Task InitInputs(this AreaComAdminViewModel vm) {
|
||||
using var ctx = new AppDbContext();
|
||||
vm.FbNr = await ctx.NextFbNr();
|
||||
vm.MgNr = vm.FilterMember.MgNr;
|
||||
@@ -18,11 +18,11 @@ namespace Elwig.Services {
|
||||
vm.WineCult = null;
|
||||
}
|
||||
|
||||
public static void ClearInputs(this AreaCmtAdminViewModel vm) {
|
||||
public static void ClearInputs(this AreaComAdminViewModel vm) {
|
||||
vm.Period = null;
|
||||
}
|
||||
|
||||
public static void FillInputs(this AreaCmtAdminViewModel vm, AreaCmtContract c) {
|
||||
public static void FillInputs(this AreaComAdminViewModel vm, AreaComContract c) {
|
||||
vm.FbNr = c.FbNr;
|
||||
vm.Period = c.YearTo == null ? $"ab {c.YearFrom}" : $"{c.YearFrom}\u2013{c.YearTo}";
|
||||
vm.Comment = c.Comment;
|
||||
@@ -30,23 +30,23 @@ namespace Elwig.Services {
|
||||
vm.Rd = ControlUtils.GetItemFromSourceWithPk(vm.RdSource, c.KgNr, c.RdNr) as WbRd;
|
||||
}
|
||||
|
||||
public static void FillInputs(this AreaCmtAdminViewModel vm, AreaCmt a) {
|
||||
public static void FillInputs(this AreaComAdminViewModel vm, AreaCom a) {
|
||||
vm.MgNr = a.MgNr;
|
||||
vm.YearFrom = a.YearFrom;
|
||||
vm.YearTo = a.YearTo;
|
||||
vm.AreaCmtType = ControlUtils.GetItemFromSourceWithPk(vm.AreaCmtTypeSource, a.VtrgId) as AreaCmtType;
|
||||
vm.AreaComType = ControlUtils.GetItemFromSourceWithPk(vm.AreaComTypeSource, a.VtrgId) as AreaComType;
|
||||
vm.WineCult = ControlUtils.GetItemFromSourceWithPk(vm.WineCultSource, a.CultId) as WineCult;
|
||||
vm.GstNr = a.GstNr;
|
||||
vm.Area = a.Area;
|
||||
}
|
||||
|
||||
public static async Task<(List<string>, IQueryable<AreaCmtContract>, IQueryable<AreaCmt>, List<string>)> GetFilters(this AreaCmtAdminViewModel vm, AppDbContext ctx) {
|
||||
public static async Task<(List<string>, IQueryable<AreaComContract>, IQueryable<AreaCom>, List<string>)> GetFilters(this AreaComAdminViewModel vm, AppDbContext ctx) {
|
||||
List<string> filterNames = [];
|
||||
IQueryable<AreaCmt> areaCmtQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
||||
IQueryable<AreaCom> areaComQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
||||
filterNames.Add(vm.FilterMember.AdministrativeName);
|
||||
|
||||
if (vm.FilterSeason is int season) {
|
||||
areaCmtQuery = Utils.ActiveAreaCommitments(areaCmtQuery, season);
|
||||
areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, season);
|
||||
filterNames.Add($"laufend {season}");
|
||||
}
|
||||
|
||||
@@ -96,37 +96,37 @@ namespace Elwig.Services {
|
||||
}
|
||||
}
|
||||
|
||||
if (filterVar.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => filterVar.Contains(a.AreaCmtType.WineVar.SortId));
|
||||
if (filterNotVar.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => !filterNotVar.Contains(a.AreaCmtType.WineVar.SortId));
|
||||
if (filterAttr.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => a.AreaCmtType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaCmtType.WineAttr.AttrId));
|
||||
if (filterNotAttr.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => a.AreaCmtType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaCmtType.WineAttr.AttrId));
|
||||
if (filterVar.Count > 0) areaComQuery = areaComQuery.Where(a => filterVar.Contains(a.AreaComType.WineVar.SortId));
|
||||
if (filterNotVar.Count > 0) areaComQuery = areaComQuery.Where(a => !filterNotVar.Contains(a.AreaComType.WineVar.SortId));
|
||||
if (filterAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
||||
if (filterNotAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
||||
}
|
||||
|
||||
IQueryable<AreaCmtContract> contracts = areaCmtQuery
|
||||
IQueryable<AreaComContract> contracts = areaComQuery
|
||||
.Select(c => c.Contract).Distinct()
|
||||
.OrderBy(c => c.FbNr);
|
||||
|
||||
return (filterNames, contracts, areaCmtQuery, filter);
|
||||
return (filterNames, contracts, areaComQuery, filter);
|
||||
}
|
||||
|
||||
public static async Task<(int FbNr, int RevNr)> UpdateAreaCommitment(this AreaCmtAdminViewModel vm, int? oldFbNr, int? revNr) {
|
||||
public static async Task<(int FbNr, int RevNr)> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr, int? revNr) {
|
||||
int newFbNr = vm.FbNr!.Value;
|
||||
|
||||
return await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var c = new AreaCmtContract {
|
||||
var c = new AreaComContract {
|
||||
FbNr = oldFbNr ?? newFbNr,
|
||||
Comment = string.IsNullOrWhiteSpace(vm.Comment) ? null : vm.Comment,
|
||||
KgNr = vm.Kg!.KgNr,
|
||||
RdNr = vm.Rd?.RdNr,
|
||||
};
|
||||
var a = new AreaCmt {
|
||||
var a = new AreaCom {
|
||||
FbNr = oldFbNr ?? newFbNr,
|
||||
RevNr = revNr ?? await ctx.NextRevNr(oldFbNr ?? newFbNr),
|
||||
MgNr = vm.MgNr!.Value,
|
||||
YearFrom = vm.YearFrom,
|
||||
YearTo = vm.YearTo,
|
||||
VtrgId = vm.AreaCmtType!.VtrgId,
|
||||
VtrgId = vm.AreaComType!.VtrgId,
|
||||
CultId = vm.WineCult?.CultId,
|
||||
GstNr = vm.GstNr?.Trim() ?? "-",
|
||||
Area = vm.Area!.Value,
|
||||
@@ -168,53 +168,53 @@ namespace Elwig.Services {
|
||||
grid.AddToolTipCell(max == null ? "" : $"{max:N0} kg", row, 4, bold: bold, alignRight: true);
|
||||
}
|
||||
|
||||
public static async Task<(string, (string?, string?, int, int?, int?)[])> GenerateToolTipData(IQueryable<AreaCmt> areaCmts, int maxKgPerHa) {
|
||||
public static async Task<(string, (string?, string?, int, int?, int?)[])> GenerateToolTipData(IQueryable<AreaCom> areaComs, int maxKgPerHa) {
|
||||
var grid = new List<(string?, string?, int, int?, int?)>();
|
||||
var text = "-";
|
||||
|
||||
var area = await areaCmts.SumAsync(p => p.Area);
|
||||
var area = await areaComs.SumAsync(p => p.Area);
|
||||
text = $"{area:N0} m²";
|
||||
grid.Add(("Geb. Fläche", null, area, null, null));
|
||||
|
||||
if (await areaCmts.AnyAsync()) {
|
||||
var attrGroups = await areaCmts
|
||||
.Where(c => c.AreaCmtType.WineAttr != null)
|
||||
.GroupBy(c => c.AreaCmtType.WineAttr!.Name)
|
||||
if (await areaComs.AnyAsync()) {
|
||||
var attrGroups = await areaComs
|
||||
.Where(c => c.AreaComType.WineAttr != null)
|
||||
.GroupBy(c => c.AreaComType.WineAttr!.Name)
|
||||
.Select(g => new {
|
||||
Attr = g.Key,
|
||||
Area = g.Sum(c => c.Area),
|
||||
Min = g.Sum(c => c.Area * (c.AreaCmtType.MinKgPerHa ?? 0) / 10_000),
|
||||
Max = g.Sum(c => c.Area * (c.AreaCmtType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||
Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000),
|
||||
Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||
})
|
||||
.OrderByDescending(g => g.Area)
|
||||
.ThenBy(g => g.Attr)
|
||||
.ToListAsync();
|
||||
var groups = await areaCmts
|
||||
.Where(c => c.AreaCmtType.WineAttr != null)
|
||||
var groups = await areaComs
|
||||
.Where(c => c.AreaComType.WineAttr != null)
|
||||
.GroupBy(c => new {
|
||||
Attr = c.AreaCmtType.WineAttr!.Name,
|
||||
c.AreaCmtType.SortId,
|
||||
Attr = c.AreaComType.WineAttr!.Name,
|
||||
c.AreaComType.SortId,
|
||||
})
|
||||
.Select(g => new {
|
||||
g.Key.Attr,
|
||||
g.Key.SortId,
|
||||
Area = g.Sum(c => c.Area),
|
||||
Min = g.Sum(c => c.Area * (c.AreaCmtType.MinKgPerHa ?? 0) / 10_000),
|
||||
Max = g.Sum(c => c.Area * (c.AreaCmtType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||
Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000),
|
||||
Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||
})
|
||||
.OrderByDescending(g => g.Area)
|
||||
.ThenBy(g => g.Attr)
|
||||
.ThenBy(g => g.SortId)
|
||||
.ToListAsync();
|
||||
|
||||
var noAttr = await areaCmts
|
||||
.Where(c => c.AreaCmtType.WineAttr == null || !c.AreaCmtType.WineAttr.IsStrict)
|
||||
.GroupBy(c => c.AreaCmtType.SortId)
|
||||
var noAttr = await areaComs
|
||||
.Where(c => c.AreaComType.WineAttr == null || !c.AreaComType.WineAttr.IsStrict)
|
||||
.GroupBy(c => c.AreaComType.SortId)
|
||||
.Select(g => new {
|
||||
SortId = g.Key,
|
||||
Area = g.Sum(c => c.Area),
|
||||
Min = g.Sum(c => c.Area * (c.AreaCmtType.MinKgPerHa ?? 0) / 10_000),
|
||||
Max = g.Sum(c => c.Area * (c.AreaCmtType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||
Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000),
|
||||
Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||
})
|
||||
.OrderByDescending(g => g.Area)
|
||||
.ThenBy(g => g.SortId)
|
||||
@@ -254,7 +254,7 @@ namespace Elwig.Services {
|
||||
return grid;
|
||||
}
|
||||
|
||||
public static async Task DeleteAreaCmt(int fbnr) {
|
||||
public static async Task DeleteAreaCom(int fbnr) {
|
||||
await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var l = (await ctx.AreaCommitmentContracts.FindAsync(fbnr))!;
|
||||
@@ -263,7 +263,7 @@ namespace Elwig.Services {
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task DeleteAreaCmtRevision(int fbnr, int revnr) {
|
||||
public static async Task DeleteAreaComRevision(int fbnr, int revnr) {
|
||||
await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var l = (await ctx.AreaCommitments.FindAsync(fbnr, revnr))!;
|
||||
@@ -1,7 +1,5 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Export;
|
||||
using Elwig.Models;
|
||||
using Elwig.Models.Dtos;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.ViewModels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -12,10 +10,6 @@ using System.Threading.Tasks;
|
||||
namespace Elwig.Services {
|
||||
public static class MemberBusinessSharesService {
|
||||
|
||||
public enum ExportSubject {
|
||||
Pending,
|
||||
};
|
||||
|
||||
public static async Task InitInputs(this MemberBusinessSharesViewModel vm) {
|
||||
using var ctx = new AppDbContext();
|
||||
vm.DateNoticeString = $"{DateTime.Today:dd.MM.yyyy}";
|
||||
@@ -103,19 +97,5 @@ namespace Elwig.Services {
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,7 @@ namespace Elwig.Services {
|
||||
var s = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||
if (s != null) maxKgPerHa = s.MaxKgPerHa;
|
||||
} catch { }
|
||||
var (text, gridData) = await AreaCmtService.GenerateToolTipData(c, maxKgPerHa);
|
||||
var (text, gridData) = await AreaComService.GenerateToolTipData(c, maxKgPerHa);
|
||||
|
||||
var deliveries = await ctx.Deliveries
|
||||
.Where(d => d.MgNr == m.MgNr)
|
||||
@@ -202,7 +202,7 @@ namespace Elwig.Services {
|
||||
return;
|
||||
var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []);
|
||||
var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []);
|
||||
var grid = AreaCmtService.GenerateToolTip(gridData);
|
||||
var grid = AreaComService.GenerateToolTip(gridData);
|
||||
vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}";
|
||||
vm.StatusDeliveriesLastSeason = textLast;
|
||||
vm.StatusDeliveriesLastSeasonToolTip = d1Grid;
|
||||
@@ -297,15 +297,15 @@ namespace Elwig.Services {
|
||||
var filterKgNr = new List<int>();
|
||||
var filterLfbisNr = new List<string>();
|
||||
var filterUstIdNr = new List<string>();
|
||||
var filterAreaCmt = new List<string>();
|
||||
var filterNotAreaCmt = new List<string>();
|
||||
var filterAreaCom = new List<string>();
|
||||
var filterNotAreaCom = new List<string>();
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var branches = await ctx.FetchBranches().ToListAsync();
|
||||
var mgnr = await ctx.FetchMembers(includeNotActive: true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg);
|
||||
var areaCmts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
||||
var areaComs = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
||||
|
||||
for (int i = 0; i < filter.Count; i++) {
|
||||
var e = filter[i];
|
||||
@@ -434,19 +434,19 @@ namespace Elwig.Services {
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add($"Tel.-Nr. {e}");
|
||||
} else if (e.Length >= 5 && e.Length <= 14 && "flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||
filterAreaCmt.AddRange(areaCmts.Keys);
|
||||
filterAreaCom.AddRange(areaComs.Keys);
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add($"Flächenbindung");
|
||||
} else if (e.Length >= 6 && e.Length <= 15 && "!flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||
filterNotAreaCmt.AddRange(areaCmts.Keys);
|
||||
filterNotAreaCom.AddRange(areaComs.Keys);
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add($"keine Flächenbindung");
|
||||
} else if (areaCmts.ContainsKey(e.ToUpper())) {
|
||||
filterAreaCmt.Add(e.ToUpper());
|
||||
} else if (areaComs.ContainsKey(e.ToUpper())) {
|
||||
filterAreaCom.Add(e.ToUpper());
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add($"Flächenbindung {e.ToUpper()}");
|
||||
} else if (e.Length >= 3 && e[0] == '!' && areaCmts.ContainsKey(e[1..].ToUpper())) {
|
||||
filterNotAreaCmt.Add(e[1..].ToUpper());
|
||||
} else if (e.Length >= 3 && e[0] == '!' && areaComs.ContainsKey(e[1..].ToUpper())) {
|
||||
filterNotAreaCom.Add(e[1..].ToUpper());
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add($"ohne Flächenbindung {e[1..].ToUpper()}");
|
||||
} else if (Validator.CheckLfbisNr(e)) {
|
||||
@@ -467,8 +467,8 @@ namespace Elwig.Services {
|
||||
if (filterMgNr.Count > 0) memberQuery = memberQuery.Where(m => filterMgNr.Contains(m.MgNr));
|
||||
if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr));
|
||||
if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId));
|
||||
if (filterAreaCmt.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).Any(c => filterAreaCmt.Contains(c.VtrgId)));
|
||||
if (filterNotAreaCmt.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).All(c => filterNotAreaCmt.Contains(c.VtrgId)));
|
||||
if (filterAreaCom.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).Any(c => filterAreaCom.Contains(c.VtrgId)));
|
||||
if (filterNotAreaCom.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).All(c => filterNotAreaCom.Contains(c.VtrgId)));
|
||||
if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr));
|
||||
if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr));
|
||||
}
|
||||
@@ -585,7 +585,7 @@ namespace Elwig.Services {
|
||||
.DistinctBy(h => h.HistNr)
|
||||
.OrderBy(h => h.DateNotice).ThenBy(h => h.HistNr)
|
||||
.ToList();
|
||||
var areaCmts = await query
|
||||
var areaComs = await query
|
||||
.SelectMany(m => m.AreaCommitments)
|
||||
.Select(c => c.Contract).Distinct()
|
||||
.Include(c => c.Revisions)
|
||||
@@ -593,11 +593,11 @@ namespace Elwig.Services {
|
||||
var wbKgs = members
|
||||
.Where(m => m.DefaultWbKg != null)
|
||||
.Select(m => m.DefaultWbKg!)
|
||||
.Union(areaCmts.Select(c => c.Kg))
|
||||
.Union(areaComs.Select(c => c.Kg))
|
||||
.Distinct()
|
||||
.OrderBy(k => k.KgNr)
|
||||
.ToList();
|
||||
await ElwigData.Export(filename, members, history, areaCmts, wbKgs, filterNames);
|
||||
await ElwigData.Export(filename, members, history, areaComs, wbKgs, filterNames);
|
||||
});
|
||||
}
|
||||
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
|
||||
@@ -700,12 +700,12 @@ namespace Elwig.Services {
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
if (vm.TransferPredecessorAreaCmts is int year && m.PredecessorMgNr is int predecessor) {
|
||||
var areaCmts = await ctx.AreaCommitments
|
||||
if (vm.TransferPredecessorAreaComs is int year && m.PredecessorMgNr is int predecessor) {
|
||||
var areaComs = await ctx.AreaCommitments
|
||||
.Where(c => c.MgNr == predecessor && (c.YearTo == null || c.YearTo >= year))
|
||||
.ToListAsync();
|
||||
|
||||
ctx.AddRange(await Task.WhenAll(areaCmts.Select(async (c, i) => new AreaCmt {
|
||||
ctx.AddRange(await Task.WhenAll(areaComs.Select(async (c, i) => new AreaCom {
|
||||
FbNr = c.FbNr,
|
||||
RevNr = await ctx.NextRevNr(c.FbNr),
|
||||
MgNr = m.MgNr,
|
||||
@@ -717,24 +717,24 @@ namespace Elwig.Services {
|
||||
YearTo = c.YearTo,
|
||||
})));
|
||||
|
||||
foreach (var ac in areaCmts)
|
||||
foreach (var ac in areaComs)
|
||||
ac.YearTo = year - 1;
|
||||
ctx.UpdateRange(areaCmts);
|
||||
ctx.UpdateRange(areaComs);
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
vm.TransferPredecessorAreaCmts = null;
|
||||
vm.TransferPredecessorAreaComs = null;
|
||||
|
||||
if (vm.CancelAreaCmts is int yearTo) {
|
||||
var areaCmts = await ctx.AreaCommitments
|
||||
if (vm.CancelAreaComs is int yearTo) {
|
||||
var areaComs = await ctx.AreaCommitments
|
||||
.Where(c => c.MgNr == m.MgNr && (c.YearTo == null || c.YearTo > yearTo))
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var ac in areaCmts)
|
||||
foreach (var ac in areaComs)
|
||||
ac.YearTo = yearTo;
|
||||
ctx.UpdateRange(areaCmts);
|
||||
ctx.UpdateRange(areaComs);
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
vm.CancelAreaCmts = null;
|
||||
vm.CancelAreaComs = null;
|
||||
|
||||
if (newMgNr != m.MgNr) {
|
||||
await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}");
|
||||
@@ -744,7 +744,7 @@ namespace Elwig.Services {
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaCmts) {
|
||||
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
|
||||
await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||
@@ -755,7 +755,7 @@ namespace Elwig.Services {
|
||||
if (deleteDeliveries) {
|
||||
await ctx.Deliveries.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||
}
|
||||
if (deleteAreaCmts) {
|
||||
if (deleteAreaComs) {
|
||||
await ctx.AreaCommitments.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||
}
|
||||
ctx.Remove(l);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -48,7 +47,7 @@ namespace Elwig.Services {
|
||||
(CategoriesOfProduct.Contains(TracesCategoryOfProduct.UNPROCESSED_PLANT_PRODUCTS_INCLUDING_SEEDS) || CategoriesOfProduct.Contains(TracesCategoryOfProduct.WINE));
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<int, (DateTime Timestamp, TracesCertificate[] Certificates)> _memberCerts = [];
|
||||
private static readonly Dictionary<int, (DateTime Timestamp, TracesCertificate[] Certificates)> _memberCerts = [];
|
||||
|
||||
public async static Task<TracesCertificate[]> GetTracesCertificates(Member m, bool? tryNameAndAddress = null) {
|
||||
if (_memberCerts.TryGetValue(m.MgNr, out var entry) && entry.Timestamp >= DateTime.Now.AddDays(-1))
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Elwig.Services {
|
||||
public static class SyncService {
|
||||
|
||||
public static readonly Expression<Func<Member, bool>> ChangedMembers = (m) => ((m.XTime == null && m.MTime > 1751328000) || m.MTime > m.XTime) && (m.ITime == null || m.MTime > m.ITime);
|
||||
public static readonly Expression<Func<AreaCmtContract, bool>> ChangedAreaCmtContracts = (c) => ((c.XTime == null && c.MTime > 1751328000) || c.MTime > c.XTime) && (c.ITime == null || c.MTime > c.ITime);
|
||||
public static readonly Expression<Func<AreaComContract, bool>> ChangedAreaComContracts = (c) => ((c.XTime == null && c.MTime > 1751328000) || c.MTime > c.XTime) && (c.ITime == null || c.MTime > c.ITime);
|
||||
public static readonly Expression<Func<Delivery, bool>> ChangedDeliveries = (d) => ((d.XTime == null && d.MTime > 1751328000) || d.MTime > d.XTime) && (d.ITime == null || d.MTime > d.ITime);
|
||||
|
||||
public static async Task Upload(string url, string username, string password, IQueryable<Member> query, IEnumerable<string> filterNames) {
|
||||
@@ -37,7 +37,7 @@ namespace Elwig.Services {
|
||||
.DistinctBy(h => h.HistNr)
|
||||
.OrderBy(h => h.DateNotice).ThenBy(h => h.HistNr)
|
||||
.ToList();
|
||||
var areaCmts = await query
|
||||
var areaComs = await query
|
||||
.SelectMany(m => m.AreaCommitments)
|
||||
.Select(c => c.Contract).Distinct()
|
||||
.OrderBy(c => c.FbNr)
|
||||
@@ -46,7 +46,7 @@ namespace Elwig.Services {
|
||||
var wbKgs = members
|
||||
.Where(m => m.DefaultWbKg != null)
|
||||
.Select(m => m.DefaultWbKg!)
|
||||
.Union(areaCmts.Select(c => c.Kg))
|
||||
.Union(areaComs.Select(c => c.Kg))
|
||||
.Distinct()
|
||||
.OrderBy(k => k.KgNr)
|
||||
.ToList();
|
||||
@@ -54,9 +54,9 @@ namespace Elwig.Services {
|
||||
InteractionService.ShowError("Mitglieder hochladen", "Es wurden keine Mitglieder zum Hochladen ausgewählt!");
|
||||
} else {
|
||||
var exportedAt = DateTime.Now;
|
||||
await ElwigData.Export(path, members, history, areaCmts, wbKgs, filterNames);
|
||||
await ElwigData.Export(path, members, history, areaComs, wbKgs, filterNames);
|
||||
await Utils.UploadExportData(path, url, username, password);
|
||||
await UpdateExportedAt(members, areaCmts, [], exportedAt);
|
||||
await UpdateExportedAt(members, areaComs, [], exportedAt);
|
||||
InteractionService.ShowInformation("Mitglieder hochgeladen", $"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!");
|
||||
}
|
||||
} catch (HttpRequestException exc) {
|
||||
@@ -106,7 +106,7 @@ namespace Elwig.Services {
|
||||
try {
|
||||
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
|
||||
List<Member> members;
|
||||
List<AreaCmtContract> areaCmts;
|
||||
List<AreaComContract> areaComs;
|
||||
List<Delivery> deliveries;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
members = await ctx.Members
|
||||
@@ -115,8 +115,8 @@ namespace Elwig.Services {
|
||||
.Include(m => m.EmailAddresses)
|
||||
.OrderBy(m => m.MgNr)
|
||||
.ToListAsync();
|
||||
areaCmts = await ctx.AreaCommitmentContracts
|
||||
.Where(ChangedAreaCmtContracts)
|
||||
areaComs = await ctx.AreaCommitmentContracts
|
||||
.Where(ChangedAreaComContracts)
|
||||
.Include(c => c.Revisions)
|
||||
.OrderBy(c => c.FbNr)
|
||||
.ToListAsync();
|
||||
@@ -129,7 +129,7 @@ namespace Elwig.Services {
|
||||
var wbKgs = members
|
||||
.Where(m => m.DefaultWbKg != null)
|
||||
.Select(m => m.DefaultWbKg!)
|
||||
.Union(areaCmts.Select(c => c.Kg))
|
||||
.Union(areaComs.Select(c => c.Kg))
|
||||
.Union(deliveries.SelectMany(d => d.Parts)
|
||||
.Where(p => p.Kg != null)
|
||||
.Select(p => p.Kg!))
|
||||
@@ -142,13 +142,13 @@ namespace Elwig.Services {
|
||||
var exportedAt = DateTime.Now;
|
||||
await (new ElwigData.ElwigExport {
|
||||
Members = (members, ["geändert seit letztem Export"]),
|
||||
AreaCmts = (areaCmts, ["geändert seit letztem Export"]),
|
||||
AreaComs = (areaComs, ["geändert seit letztem Export"]),
|
||||
Deliveries = (deliveries, ["geändert seit letzem Export"]),
|
||||
WbKgs = (wbKgs, ["von exportierten Mitgliedern, Flächenbindungen und Lieferungen"]),
|
||||
}).Export(path);
|
||||
await Utils.UploadExportData(path, url, username, password);
|
||||
await UpdateExportedAt(members, areaCmts, deliveries, exportedAt);
|
||||
InteractionService.ShowInformation("Mitglieder und Lieferungen hochladen", $"Hochladen von {members.Count:N0} Mitgliedern, {areaCmts.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!");
|
||||
await UpdateExportedAt(members, areaComs, deliveries, exportedAt);
|
||||
InteractionService.ShowInformation("Mitglieder und Lieferungen hochladen", $"Hochladen von {members.Count:N0} Mitgliedern, {areaComs.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!");
|
||||
}
|
||||
} catch (HttpRequestException exc) {
|
||||
InteractionService.ShowException("Mitglieder und Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
|
||||
@@ -236,7 +236,7 @@ namespace Elwig.Services {
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task UpdateExportedAt(IEnumerable<Member> member, IEnumerable<AreaCmtContract> contracts, IEnumerable<Delivery> deliveries, DateTime dateTime) {
|
||||
private static async Task UpdateExportedAt(IEnumerable<Member> member, IEnumerable<AreaComContract> contracts, IEnumerable<Delivery> deliveries, DateTime dateTime) {
|
||||
var timestamp = ((DateTimeOffset)dateTime.ToUniversalTime()).ToUnixTimeSeconds();
|
||||
var mgnrs = string.Join(",", member.Select(m => $"{m.MgNr}").Append("0"));
|
||||
var fbnrs = string.Join(",", contracts.Select(c => $"{c.FbNr}").Append("0"));
|
||||
@@ -259,7 +259,7 @@ namespace Elwig.Services {
|
||||
|
||||
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
||||
try {
|
||||
return await ctx.Members.Where(ChangedMembers).AnyAsync() || await ctx.AreaCommitmentContracts.Where(ChangedAreaCmtContracts).AnyAsync() || await ctx.Deliveries.Where(ChangedDeliveries).AnyAsync() || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
||||
return await ctx.Members.Where(ChangedMembers).AnyAsync() || await ctx.AreaCommitmentContracts.Where(ChangedAreaComContracts).AnyAsync() || await ctx.Deliveries.Where(ChangedDeliveries).AnyAsync() || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Elwig.ViewModels {
|
||||
public partial class AreaCmtAdminViewModel : ObservableObject {
|
||||
public partial class AreaComAdminViewModel : ObservableObject {
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; } = "Flächenbindungen - Elwig";
|
||||
@@ -54,9 +54,9 @@ namespace Elwig.ViewModels {
|
||||
public partial string? Period { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AreaCmtType? AreaCmtType { get; set; }
|
||||
public partial AreaComType? AreaComType { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial IEnumerable<AreaCmtType> AreaCmtTypeSource { get; set; } = [];
|
||||
public partial IEnumerable<AreaComType> AreaComTypeSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
public partial object? WineCultObj { get; set; }
|
||||
public WineCult? WineCult {
|
||||
@@ -117,7 +117,7 @@ namespace Elwig.ViewModels {
|
||||
public partial string? WeightString { get; set; }
|
||||
public int? Weight {
|
||||
get => int.TryParse(WeightString?.Replace(Utils.GroupSeparator, ""), out var w) ? w : null;
|
||||
set => WeightString = value > 0 ? $"{value:N0}" : null;
|
||||
set => WeightString = $"{value:N0}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
public partial string? TareString { get; set; } = "-";
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace Elwig.ViewModels {
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; } = "Mitglieder - Elwig";
|
||||
|
||||
public int? TransferPredecessorAreaCmts { get; set; } = null;
|
||||
public int? CancelAreaCmts { get; set; } = null;
|
||||
public int? TransferPredecessorAreaComs { get; set; } = null;
|
||||
public int? CancelAreaComs { get; set; } = null;
|
||||
|
||||
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
|
||||
|
||||
|
||||
@@ -608,8 +608,8 @@ namespace Elwig.Windows {
|
||||
InputLostFocus((TextBox)sender, Validator.CheckUpperCase);
|
||||
}
|
||||
|
||||
protected void AreaCmtTypeDetailsButton_Click(object sender, RoutedEventArgs? evt) {
|
||||
App.FocusBaseDataAreaCmtType();
|
||||
protected void AreaComTypeDetailsButton_Click(object sender, RoutedEventArgs? evt) {
|
||||
App.FocusBaseDataAreaComType();
|
||||
}
|
||||
|
||||
protected void AddressInput_TextChanged(object sender, TextChangedEventArgs? evt) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<local:AdministrationWindow
|
||||
x:Class="Elwig.Windows.AreaCmtAdminWindow"
|
||||
x:Class="Elwig.Windows.AreaComAdminWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -9,7 +9,7 @@
|
||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||
Title="{Binding Title}" Height="600" MinHeight="550" Width="1000" MinWidth="860">
|
||||
<Window.DataContext>
|
||||
<vm:AreaCmtAdminViewModel/>
|
||||
<vm:AreaComAdminViewModel/>
|
||||
</Window.DataContext>
|
||||
<Window.Resources>
|
||||
<Style TargetType="Label">
|
||||
@@ -110,10 +110,10 @@
|
||||
</DataGridTextColumn.CellStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="130"/>
|
||||
<DataGridTextColumn Header="Sorte" Binding="{Binding Latest.AreaCmtType.VtrgId}" Width="50">
|
||||
<DataGridTextColumn Header="Sorte" Binding="{Binding Latest.AreaComType.VtrgId}" Width="50">
|
||||
<DataGridTextColumn.CellStyle>
|
||||
<Style>
|
||||
<Setter Property="TextBlock.Foreground" Value="{Binding Latest.AreaCmtType.WineVar.Color}"/>
|
||||
<Setter Property="TextBlock.Foreground" Value="{Binding Latest.AreaComType.WineVar.Color}"/>
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.CellStyle>
|
||||
@@ -229,7 +229,7 @@
|
||||
<TextBlock Text="{Binding YearFrom}" Width="28" TextAlignment="Right" Margin="0,0,0,0"/>
|
||||
<TextBlock Text="–" TextAlignment="Center" Margin="0,0,0,0"/>
|
||||
<TextBlock Text="{Binding YearTo}" Width="28" TextAlignment="Left" Margin="0,0,0,0"/>
|
||||
<TextBlock Text="{Binding VtrgId}" Width="40" TextAlignment="Center" Foreground="{Binding AreaCmtType.WineVar.Color}"/>
|
||||
<TextBlock Text="{Binding VtrgId}" Width="40" TextAlignment="Center" Foreground="{Binding AreaComType.WineVar.Color}"/>
|
||||
<TextBlock Text="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/>
|
||||
<TextBlock Text="{Binding Member.AdministrativeName}"/>
|
||||
</StackPanel>
|
||||
@@ -268,11 +268,11 @@
|
||||
TextChanged="IntegerInput_TextChanged"/>
|
||||
|
||||
<Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0"/>
|
||||
<ComboBox x:Name="AreaCmtTypeInput" SelectedItem="{Binding AreaCmtType, Mode=TwoWay}" ItemsSource="{Binding AreaCmtTypeSource, Mode=TwoWay}"
|
||||
<ComboBox x:Name="AreaComTypeInput" SelectedItem="{Binding AreaComType, Mode=TwoWay}" ItemsSource="{Binding AreaComTypeSource, Mode=TwoWay}"
|
||||
ItemTemplate="{StaticResource AreaCommitmentTypeTemplate}" TextSearch.TextPath="DisplayName"
|
||||
HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1"/>
|
||||
<Button x:Name="AreaCmtTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
||||
Click="AreaCmtTypeDetailsButton_Click"
|
||||
<Button x:Name="AreaComTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
||||
Click="AreaComTypeDetailsButton_Click"
|
||||
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
|
||||
|
||||
<Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0"/>
|
||||
+38
-38
@@ -12,13 +12,13 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Elwig.Windows {
|
||||
public partial class AreaCmtAdminWindow : AdministrationWindow {
|
||||
public partial class AreaComAdminWindow : AdministrationWindow {
|
||||
|
||||
public AreaCmtAdminViewModel ViewModel => (AreaCmtAdminViewModel)DataContext;
|
||||
public AreaComAdminViewModel ViewModel => (AreaComAdminViewModel)DataContext;
|
||||
|
||||
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(AreaCmtAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
||||
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(AreaComAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
||||
|
||||
public AreaCmtAdminWindow(int mgnr) {
|
||||
public AreaComAdminWindow(int mgnr) {
|
||||
InitializeComponent();
|
||||
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
|
||||
using var ctx = new AppDbContext();
|
||||
@@ -30,7 +30,7 @@ namespace Elwig.Windows {
|
||||
];
|
||||
RequiredInputs = [
|
||||
FbNrInput, MgNrInput, MemberInput, YearFromInput, KgInput, RdInput,
|
||||
GstNrInput, AreaInput, AreaCmtTypeInput, WineCultivationInput
|
||||
GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput
|
||||
];
|
||||
|
||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||
@@ -50,13 +50,13 @@ namespace Elwig.Windows {
|
||||
var cursor = Mouse.OverrideCursor != null;
|
||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||
var query = (vm.SearchQuery, vm.FilterSeason);
|
||||
var (filterNames, filter, contracts, areaCmts, areaCmtCount, stat) = await Task.Run(async () => {
|
||||
var (filterNames, filter, contracts, areaComs, areaComCount, stat) = await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var (filterNames, contractQuery, areaCmtQuery, filter) = await vm.GetFilters(ctx);
|
||||
var (filterNames, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
||||
var contracts = await contractQuery
|
||||
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
||||
.ToListAsync();
|
||||
var areaCmts = await areaCmtQuery.ToListAsync();
|
||||
var areaComs = await areaComQuery.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && contracts.Count > 0) {
|
||||
var dict = contracts.AsParallel()
|
||||
@@ -68,11 +68,11 @@ namespace Elwig.Windows {
|
||||
.Select(a => a.Key)];
|
||||
}
|
||||
|
||||
var areaCmtCount = await areaCmtQuery.CountAsync();
|
||||
var areaComCount = await areaComQuery.CountAsync();
|
||||
var season = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||
var stat = await AreaCmtService.GenerateToolTipData(areaCmtQuery, season?.MaxKgPerHa ?? 10_000);
|
||||
var stat = await AreaComService.GenerateToolTipData(areaComQuery, season?.MaxKgPerHa ?? 10_000);
|
||||
|
||||
return (filterNames, filter, contracts, areaCmts, areaCmtCount, stat);
|
||||
return (filterNames, filter, contracts, areaComs, areaComCount, stat);
|
||||
});
|
||||
if (!cursor) Mouse.OverrideCursor = null;
|
||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason)) return;
|
||||
@@ -83,16 +83,16 @@ namespace Elwig.Windows {
|
||||
RefreshInputs();
|
||||
|
||||
if (filter.Count == 0) {
|
||||
ViewModel.StatusAreaCommitments = $"{areaCmtCount:N0}";
|
||||
ViewModel.StatusAreaCommitments = $"{areaComCount:N0}";
|
||||
var (text, gridData) = stat;
|
||||
ViewModel.StatusArea = text;
|
||||
ViewModel.StatusAreaToolTip = AreaCmtService.GenerateToolTip(gridData);
|
||||
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
|
||||
} else {
|
||||
ViewModel.StatusAreaCommitments = $"{contracts.Count:N0}";
|
||||
ViewModel.StatusArea = $"{areaCmts.Sum(a => a.Area):N0} m²";
|
||||
ViewModel.StatusArea = $"{areaComs.Sum(a => a.Area):N0} m²";
|
||||
ViewModel.StatusAreaToolTip = null;
|
||||
}
|
||||
var groups = areaCmts.GroupBy(a => $"{a.AreaCmtType.SortId}{a.AreaCmtType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
||||
var groups = areaComs.GroupBy(a => $"{a.AreaComType.SortId}{a.AreaComType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
||||
ViewModel.StatusContracts = $"{groups.Count:N0}";
|
||||
if (groups.Count > 0)
|
||||
ViewModel.StatusContracts += $" ({string.Join(", ", groups.Select(g => g.Key))})";
|
||||
@@ -100,7 +100,7 @@ namespace Elwig.Windows {
|
||||
|
||||
private async Task RefreshRevisions() {
|
||||
using var ctx = new AppDbContext();
|
||||
if (AreaCommitmentList.SelectedItem is AreaCmtContract c) {
|
||||
if (AreaCommitmentList.SelectedItem is AreaComContract c) {
|
||||
ControlUtils.RenewItemsSource(RevisionList, c.Revisions.OrderByDescending(p => p.RevNr).ToList(), RevisionList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||
} else {
|
||||
RevisionList.ItemsSource = null;
|
||||
@@ -109,11 +109,11 @@ namespace Elwig.Windows {
|
||||
|
||||
private void RefreshInputs(bool validate = false) {
|
||||
ClearInputStates();
|
||||
if (RevisionList.SelectedItem is AreaCmt a) {
|
||||
if (RevisionList.SelectedItem is AreaCom a) {
|
||||
EditAreaCommitmentButton.IsEnabled = true;
|
||||
DeleteAreaCommitmentButton.IsEnabled = true;
|
||||
FillInputs(a);
|
||||
} else if (AreaCommitmentList.SelectedItem is AreaCmtContract c) {
|
||||
} else if (AreaCommitmentList.SelectedItem is AreaComContract c) {
|
||||
EditAreaCommitmentButton.IsEnabled = true;
|
||||
DeleteAreaCommitmentButton.IsEnabled = true;
|
||||
FillInputs(c);
|
||||
@@ -128,14 +128,14 @@ namespace Elwig.Windows {
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
private void FillInputs(AreaCmtContract c) {
|
||||
private void FillInputs(AreaComContract c) {
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
ViewModel.FillInputs(c);
|
||||
FinishInputFilling();
|
||||
}
|
||||
|
||||
private void FillInputs(AreaCmt a) {
|
||||
private void FillInputs(AreaCom a) {
|
||||
FillInputs(a.Contract);
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
@@ -170,7 +170,7 @@ namespace Elwig.Windows {
|
||||
.Select(k => k.AtKg)
|
||||
.OrderBy(k => k.Name)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(AreaCmtTypeInput, await ctx.AreaCommitmentTypes
|
||||
ControlUtils.RenewItemsSource(AreaComTypeInput, await ctx.AreaCommitmentTypes
|
||||
.Include(c => c.WineVar)
|
||||
.Include(c => c.WineAttr)
|
||||
.OrderBy(v => v.VtrgId)
|
||||
@@ -228,10 +228,10 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
if (RevisionList.SelectedItem is not AreaCmt a)
|
||||
if (RevisionList.SelectedItem is not AreaCom a)
|
||||
return;
|
||||
|
||||
var d = new AreaCmtModifyDialog(a.YearFrom, a.YearTo, a.Area, true, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, true, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||
if (d.ShowDialog() != true)
|
||||
return;
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace Elwig.Windows {
|
||||
ViewModel.YearTo = yearTo;
|
||||
await ViewModel.UpdateAreaCommitment(a.FbNr, a.RevNr);
|
||||
} else {
|
||||
await AreaCmtService.DeleteAreaCmt(a.FbNr);
|
||||
await AreaComService.DeleteAreaCom(a.FbNr);
|
||||
}
|
||||
App.HintContextChange();
|
||||
} catch (Exception exc) {
|
||||
@@ -260,9 +260,9 @@ namespace Elwig.Windows {
|
||||
SaveButton.IsEnabled = false;
|
||||
|
||||
int? yearTo = null;
|
||||
if (InputHasChanged(AreaInput) || InputHasChanged(AreaCmtTypeInput) || InputHasChanged(MgNrInput)) {
|
||||
var a = (RevisionList.SelectedItem as AreaCmt)!;
|
||||
var d = new AreaCmtModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput) || InputHasChanged(MgNrInput)) {
|
||||
var a = (RevisionList.SelectedItem as AreaCom)!;
|
||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||
if (d.ShowDialog() != true) {
|
||||
SaveButton.IsEnabled = true;
|
||||
return;
|
||||
@@ -273,13 +273,13 @@ namespace Elwig.Windows {
|
||||
int fbnr, revnr;
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
try {
|
||||
AreaCmt? temp = null;
|
||||
AreaCom? temp = null;
|
||||
if (yearTo != null && (!ViewModel.YearTo.HasValue || yearTo < ViewModel.YearTo)) {
|
||||
temp = new AreaCmt {
|
||||
temp = new AreaCom {
|
||||
MgNr = ViewModel.MgNr!.Value,
|
||||
YearFrom = ViewModel.YearFrom,
|
||||
YearTo = ViewModel.YearTo,
|
||||
VtrgId = ViewModel.AreaCmtType!.VtrgId,
|
||||
VtrgId = ViewModel.AreaComType!.VtrgId,
|
||||
CultId = ViewModel.WineCult?.CultId,
|
||||
GstNr = ViewModel.GstNr?.Trim() ?? "-",
|
||||
Area = ViewModel.Area!.Value,
|
||||
@@ -287,11 +287,11 @@ namespace Elwig.Windows {
|
||||
RefreshInputs();
|
||||
ViewModel.YearTo = yearTo;
|
||||
}
|
||||
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCmtContract)?.FbNr, (RevisionList.SelectedItem as AreaCmt)?.RevNr);
|
||||
if (temp is AreaCmt t) {
|
||||
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaComContract)?.FbNr, (RevisionList.SelectedItem as AreaCom)?.RevNr);
|
||||
if (temp is AreaCom t) {
|
||||
t.YearFrom = yearTo + 1;
|
||||
ViewModel.FillInputs(t);
|
||||
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCmtContract)?.FbNr, null);
|
||||
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaComContract)?.FbNr, null);
|
||||
}
|
||||
App.HintContextChange();
|
||||
} catch (Exception exc) {
|
||||
@@ -415,7 +415,7 @@ namespace Elwig.Windows {
|
||||
|
||||
private void RevisionList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||
RefreshInputs();
|
||||
if (RevisionList.SelectedItem is AreaCmt c) {
|
||||
if (RevisionList.SelectedItem is AreaCom c) {
|
||||
EditAreaCommitmentButton.IsEnabled = true;
|
||||
} else {
|
||||
EditAreaCommitmentButton.IsEnabled = false;
|
||||
@@ -495,12 +495,12 @@ namespace Elwig.Windows {
|
||||
RdInput.SelectedIndex = s.Count();
|
||||
}
|
||||
|
||||
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaCmtContract?, ValidationResult> checker) {
|
||||
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaCmtContract)AreaCommitmentList.SelectedItem));
|
||||
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaComContract?, ValidationResult> checker) {
|
||||
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaComContract)AreaCommitmentList.SelectedItem));
|
||||
}
|
||||
|
||||
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaCmtContract?, ValidationResult> checker, string? msg = null) {
|
||||
InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaCmtContract)AreaCommitmentList.SelectedItem), msg);
|
||||
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaComContract?, ValidationResult> checker, string? msg = null) {
|
||||
InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaComContract)AreaCommitmentList.SelectedItem), msg);
|
||||
}
|
||||
|
||||
private void FbNrInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||
@@ -195,7 +195,7 @@
|
||||
<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"
|
||||
TextChanged="BranchPlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||
<ComboBox x:Name="BranchOrtInput" DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||
<ComboBox x:Name="BranchOrtInput" ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
||||
Margin="47,70,10,0" Grid.Column="1" Grid.ColumnSpan="3" Width="253" HorizontalAlignment="Left"
|
||||
SelectionChanged="Branch_Changed"/>
|
||||
|
||||
@@ -561,12 +561,12 @@
|
||||
</ComboBox>
|
||||
|
||||
<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"
|
||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox x:Name="ParameterAreaCmtGroup" Header="Berechnung Flächenbindungen (aktuelle Saison)" Margin="10,10,10,0" VerticalAlignment="Top">
|
||||
<GroupBox x:Name="ParameterAreaComGroup" Header="Berechnung Flächenbindungen (aktuelle Saison)" Margin="10,10,10,0" VerticalAlignment="Top">
|
||||
<Grid>
|
||||
<CheckBox x:Name="ParameterAllowAttrIntoLowerInput" Content="Erlauben Lieferungen auch auf (konfigurierte) "schlechtere" Flächenbindungen aufzuteilen"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,10,10,10"
|
||||
@@ -611,13 +611,6 @@
|
||||
<TabItem Header="Textelemente">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||
<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">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace Elwig.Windows {
|
||||
public partial class BaseDataWindow {
|
||||
|
||||
private Dictionary<string, string?>? _acts = null;
|
||||
private Dictionary<AreaCmtType, string>? _actIds = null;
|
||||
private ObservableCollection<AreaCmtType>? _actList = null;
|
||||
private Dictionary<AreaComType, string>? _actIds = null;
|
||||
private ObservableCollection<AreaComType>? _actList = null;
|
||||
private bool _actChanged = false;
|
||||
private bool _actUpdate = false;
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Elwig.Windows {
|
||||
private void AreaCommitmentTypeList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||
UpdateButtons();
|
||||
_actUpdate = true;
|
||||
if (AreaCommitmentTypeList.SelectedItem is AreaCmtType type) {
|
||||
if (AreaCommitmentTypeList.SelectedItem is AreaComType type) {
|
||||
AreaCommitmentTypeIdInput.Text = $"{type.SortId}{type.AttrId}";
|
||||
ControlUtils.SelectItemWithPk(AreaCommitmentTypeWineVariantInput, type.SortId);
|
||||
ControlUtils.SelectItemWithPk(AreaCommitmentTypeWineAttributeInput, type.AttrId);
|
||||
@@ -96,7 +96,7 @@ namespace Elwig.Windows {
|
||||
private void AreaCommitmentTypeAddButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (_actList == null) return;
|
||||
_actChanged = true;
|
||||
var item = new AreaCmtType { VtrgId = "", SortId = "" };
|
||||
var item = new AreaComType { VtrgId = "", SortId = "" };
|
||||
_actList.Add(item);
|
||||
AreaCommitmentTypeList.SelectedItem = item;
|
||||
UpdateButtons();
|
||||
@@ -114,7 +114,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void AreaCommitmentType_Changed(object? sender, RoutedEventArgs? evt) {
|
||||
if (_actUpdate || (!IsEditing && !IsCreating) || AreaCommitmentTypeList.SelectedItem is not AreaCmtType attr || _acts == null || _actIds == null) return;
|
||||
if (_actUpdate || (!IsEditing && !IsCreating) || AreaCommitmentTypeList.SelectedItem is not AreaComType attr || _acts == null || _actIds == null) return;
|
||||
_actChanged = true;
|
||||
|
||||
var v = AreaCommitmentTypeWineVariantInput.SelectedItem as WineVar;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Elwig.Windows {
|
||||
];
|
||||
WineAttributeFillLowerInput.Visibility = Visibility.Hidden;
|
||||
WineAttributeFillLowerLabel.Visibility = Visibility.Hidden;
|
||||
ParameterAreaCmtGroup.Header = ParameterAreaCmtGroup.Header.ToString()!.Split('(')[0] + $"({Utils.CurrentLastSeason})";
|
||||
ParameterAreaComGroup.Header = ParameterAreaComGroup.Header.ToString()!.Split('(')[0] + $"({Utils.CurrentLastSeason})";
|
||||
LockInputs();
|
||||
}
|
||||
|
||||
@@ -338,7 +338,6 @@ namespace Elwig.Windows {
|
||||
ClientEmailAddressInput.Text = p.EmailAddress;
|
||||
ClientWebsiteInput.Text = p.Website;
|
||||
|
||||
ModeMemberDataSheetShares.IsChecked = p.ModeMemberDataSheetShares > 0;
|
||||
TextElementDeliveryNote.Text = p.TextDeliveryNote;
|
||||
switch (p.ModeDeliveryNoteStats) {
|
||||
case 0: ModeDeliveryNoteNone.IsChecked = true; break;
|
||||
@@ -382,7 +381,6 @@ namespace Elwig.Windows {
|
||||
|
||||
p.ModeBusinessShares = ParameterBusinessShareModeInput.SelectedIndex;
|
||||
p.EnableMemberHistory = ParameterBusinessShareHistoryInput.IsChecked ?? false;
|
||||
p.ModeMemberDataSheetShares = ModeMemberDataSheetShares.IsChecked == true ? 1 : 0;
|
||||
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.TextDeliveryConfirmation = string.IsNullOrWhiteSpace(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text;
|
||||
|
||||
@@ -35,11 +35,11 @@ namespace Elwig.Windows {
|
||||
|
||||
private static readonly LegendItem
|
||||
UnContractedLegend = new() {
|
||||
LabelText = "Ungebunden", LineWidth = 1, LineColor = ColorUnContracted,
|
||||
LabelText = "UnContracted", LineWidth = 1, LineColor = ColorUnContracted,
|
||||
MarkerStyle = new(MarkerShape.FilledCircle, 5, ColorUnContracted)
|
||||
},
|
||||
ContractedLegend = new() {
|
||||
LabelText = "Gebunden", LineWidth = 1, LineColor = ColorContracted,
|
||||
LabelText = "Contracted", LineWidth = 1, LineColor = ColorContracted,
|
||||
MarkerStyle = new(MarkerShape.FilledCircle, 5, ColorContracted)
|
||||
},
|
||||
LdwLegend = new() {
|
||||
|
||||
@@ -629,7 +629,7 @@ namespace Elwig.Windows {
|
||||
var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare);
|
||||
if (correction == null) return;
|
||||
ViewModel.Weight += lastCorrection - correction;
|
||||
if (ViewModel.Weight != null && ViewModel.WeighingData is string s) {
|
||||
if (ViewModel.WeighingData is string s) {
|
||||
ViewModel.TargetTare = correction == 0 ? null : (ViewModel.ActualTare ?? 0) + correction;
|
||||
ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare;
|
||||
var obj = JsonNode.Parse(s)!.AsObject();
|
||||
@@ -1514,7 +1514,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
InputTextChanged((TextBox)sender, new ValidationResult(ViewModel.Weight > 0, null));
|
||||
InputTextChanged((TextBox)sender);
|
||||
}
|
||||
|
||||
private void TemperatureAcidInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<RadioButton GroupName="Recipients" x:Name="RecipientsActiveMembersInput" Content="aktive Mitglieder"
|
||||
Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
||||
<RadioButton GroupName="Recipients" x:Name="RecipientsAreaCmtMembersInput" Content="Mitglieder mit Flächenbindung"
|
||||
<RadioButton GroupName="Recipients" x:Name="RecipientsAreaComMembersInput" Content="Mitglieder mit Flächenbindung"
|
||||
Margin="10,30,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
|
||||
<RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryAncmtMembersInput" Content="Mitglieder mit Anmeldung"
|
||||
@@ -178,8 +178,8 @@
|
||||
Margin="180,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||
Checked="MemberInput_Checked"/>
|
||||
|
||||
<Label Content="Vtrg.:" x:Name="MemberAreaCmtLabel" Margin="10,280,0,10"/>
|
||||
<ctrl:CheckComboBox x:Name="MemberAreaCmtInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId"
|
||||
<Label Content="Vtrg.:" x:Name="MemberAreaComLabel" Margin="10,280,0,10"/>
|
||||
<ctrl:CheckComboBox x:Name="MemberAreaComInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId"
|
||||
IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten"
|
||||
Margin="50,280,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
|
||||
SelectionChanged="MemberInput_SelectionChanged"/>
|
||||
|
||||
@@ -181,13 +181,13 @@ namespace Elwig.Windows {
|
||||
MemberKgInput.SelectAll();
|
||||
MemberKgInput.SelectionChanged += MemberInput_SelectionChanged;
|
||||
}
|
||||
ControlUtils.RenewItemsSource(MemberAreaCmtInput, await ctx.AreaCommitmentTypes
|
||||
ControlUtils.RenewItemsSource(MemberAreaComInput, await ctx.AreaCommitmentTypes
|
||||
.OrderBy(a => a.VtrgId)
|
||||
.ToListAsync(), MemberInput_SelectionChanged);
|
||||
if (MemberAreaCmtInput.SelectedItems.Count == 0) {
|
||||
MemberAreaCmtInput.SelectionChanged -= MemberInput_SelectionChanged;
|
||||
MemberAreaCmtInput.SelectAll();
|
||||
MemberAreaCmtInput.SelectionChanged += MemberInput_SelectionChanged;
|
||||
if (MemberAreaComInput.SelectedItems.Count == 0) {
|
||||
MemberAreaComInput.SelectionChanged -= MemberInput_SelectionChanged;
|
||||
MemberAreaComInput.SelectAll();
|
||||
MemberAreaComInput.SelectionChanged += MemberInput_SelectionChanged;
|
||||
}
|
||||
ControlUtils.RenewItemsSource(MemberDeliveryAncmtInput, await ctx.DeliverySchedules
|
||||
.Where(s => s.Year == Year)
|
||||
@@ -412,8 +412,8 @@ namespace Elwig.Windows {
|
||||
MemberOfficerYesInput.Visibility = vis;
|
||||
MemberOfficerNoInput.Visibility = vis;
|
||||
MemberOfficerIndifferentInput.Visibility = vis;
|
||||
MemberAreaCmtInput.Visibility = RecipientsAreaCmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
MemberAreaCmtLabel.Visibility = RecipientsAreaCmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
MemberAreaComInput.Visibility = RecipientsAreaComMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
MemberAreaComLabel.Visibility = RecipientsAreaComMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
MemberDeliveryAncmtInput.Visibility = RecipientsDeliveryAncmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
MemberDeliveryAncmtLabel.Visibility = RecipientsDeliveryAncmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
MemberCustomInput.Visibility = RecipientsCustomInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
|
||||
@@ -465,8 +465,8 @@ namespace Elwig.Windows {
|
||||
query = query.Where(m => !m.IsOfficer);
|
||||
}
|
||||
|
||||
if (RecipientsAreaCmtMembersInput.IsChecked == true) {
|
||||
var vtrg = MemberAreaCmtInput.SelectedItems.Cast<AreaCmtType>().Select(a => a.VtrgId).ToList();
|
||||
if (RecipientsAreaComMembersInput.IsChecked == true) {
|
||||
var vtrg = MemberAreaComInput.SelectedItems.Cast<AreaComType>().Select(a => a.VtrgId).ToList();
|
||||
query = query.Where(m => m.IsActive && m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Year)).Any(c => vtrg.Contains(c.VtrgId)));
|
||||
} else if (RecipientsDeliveryAncmtMembersInput.IsChecked == true) {
|
||||
var dsnrs = MemberDeliveryAncmtInput.SelectedItems.Cast<DeliverySchedule>().Select(s => s.DsNr).ToList();
|
||||
|
||||
@@ -414,11 +414,11 @@ namespace Elwig.Windows {
|
||||
if (valid) {
|
||||
await Task.Run(async () => {
|
||||
var membersTotal = await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync();
|
||||
var areaCmts = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value);
|
||||
var membersCtrd = await areaCmts.Select(c => c.Member).Distinct().CountAsync();
|
||||
var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value);
|
||||
var membersCtrd = await areaComs.Select(c => c.Member).Distinct().CountAsync();
|
||||
var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight);
|
||||
var ctrdWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value);
|
||||
var area = await areaCmts.SumAsync(c => c.Area);
|
||||
var area = await areaComs.SumAsync(c => c.Area);
|
||||
await App.MainDispatcher.BeginInvoke(() => {
|
||||
if (year != SeasonInput.Value) return;
|
||||
SeasonStatMembersTotal.Text = $"{membersTotal:N0}";
|
||||
@@ -462,7 +462,7 @@ namespace Elwig.Windows {
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year);
|
||||
var tbl2 = await AreaCmtUnderDeliveryData.ForSeason(ctx.AreaCmtUnderDeliveryRows, year);
|
||||
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year);
|
||||
using var ods = new OdsFile(filename);
|
||||
if (App.Client.HasRedWhite) {
|
||||
await ods.AddTable(tbl1.Red);
|
||||
@@ -524,8 +524,8 @@ namespace Elwig.Windows {
|
||||
App.HintContextChange();
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
var tbl1 = await MemberAreaCmtTotalsData.ForSeason(ctx.MemberAreaCmtTotalsRows, year);
|
||||
var tbl2 = await MemberAreaCmtsData.ForSeason(ctx.MemberAreaCmtsRows, year);
|
||||
var tbl1 = await MemberAreaComTotalsData.ForSeason(ctx.MemberAreaComTotalsRows, year);
|
||||
var tbl2 = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year);
|
||||
using var ods = new OdsFile(filename);
|
||||
await ods.AddTable(tbl1);
|
||||
await ods.AddTable(tbl2);
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
Click="Menu_CreditNote_Email_Click"/>
|
||||
</MenuItem>
|
||||
<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"/>
|
||||
<MenuItem x:Name="Menu_List_ShowActive" Header="...mit Aktiven anzeigen (PDF)"
|
||||
Click="Menu_List_ShowActive_Click" InputGestureText="Strg+O"/>
|
||||
@@ -119,7 +119,7 @@
|
||||
<MenuItem x:Name="Menu_List_PrintActive" Header="...mit Aktiven drucken"
|
||||
Click="Menu_List_PrintActive_Click" InputGestureText="Strg+Shift+O"/>
|
||||
<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"/>
|
||||
<MenuItem x:Name="Menu_List_ShowFilters" Header="...aus Filtern anzeigen (PDF)"
|
||||
Click="Menu_List_ShowFilters_Click"/>
|
||||
@@ -128,7 +128,7 @@
|
||||
<MenuItem x:Name="Menu_List_PrintFilters" Header="...aus Filtern drucken"
|
||||
Click="Menu_List_PrintFilters_Click"/>
|
||||
<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"/>
|
||||
<MenuItem x:Name="Menu_List_ShowAll" Header="...mit allen anzeigen (PDF)"
|
||||
Click="Menu_List_ShowAll_Click"/>
|
||||
@@ -147,10 +147,6 @@
|
||||
IsCheckable="True" IsChecked="{Binding MemberListOrderByOrt, Mode=TwoWay}"
|
||||
Click="Menu_List_Order_Click"/>
|
||||
</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 x:Name="Menu_Export_ExportSelected" Header="...von ausgewähltem Mitglied speichern..." IsEnabled="False"
|
||||
Click="Menu_Export_ExportSelected_Click"/>
|
||||
@@ -382,7 +378,7 @@
|
||||
Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
||||
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||
<ComboBox x:Name="OrtInput" SelectedItem="{Binding Ort, Mode=TwoWay}" ItemsSource="{Binding OrtSource, Mode=TwoWay}"
|
||||
DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
||||
SelectionChanged="OrtInput_SelectionChanged"
|
||||
Margin="47,160,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
||||
</Grid>
|
||||
@@ -615,7 +611,7 @@
|
||||
Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
||||
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||
<ComboBox x:Name="BillingOrtInput" SelectedItem="{Binding BillingOrt, Mode=TwoWay}" ItemsSource="{Binding BillingOrtSource, Mode=TwoWay}"
|
||||
DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
||||
SelectionChanged="OrtInput_SelectionChanged"
|
||||
Margin="47,70,10,0" Grid.Column="1"/>
|
||||
</Grid>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Elwig.Dialogs;
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Export;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.Services;
|
||||
using Elwig.ViewModels;
|
||||
@@ -115,7 +114,6 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
if (!App.Client.EnableMemberHistory) {
|
||||
Menu_BusinessShares.Visibility = Visibility.Collapsed;
|
||||
BusinessSharesButton.Visibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
@@ -476,8 +474,8 @@ namespace Elwig.Windows {
|
||||
IsCreating = true;
|
||||
MemberList.IsEnabled = false;
|
||||
ViewModel.SelectedMember = null;
|
||||
ViewModel.TransferPredecessorAreaCmts = null;
|
||||
ViewModel.CancelAreaCmts = null;
|
||||
ViewModel.TransferPredecessorAreaComs = null;
|
||||
ViewModel.CancelAreaComs = null;
|
||||
HideNewEditDeleteButtons();
|
||||
ShowSaveResetCancelButtons();
|
||||
UnlockInputs();
|
||||
@@ -497,8 +495,8 @@ namespace Elwig.Windows {
|
||||
|
||||
IsEditing = true;
|
||||
MemberList.IsEnabled = false;
|
||||
ViewModel.TransferPredecessorAreaCmts = null;
|
||||
ViewModel.CancelAreaCmts = null;
|
||||
ViewModel.TransferPredecessorAreaComs = null;
|
||||
ViewModel.CancelAreaComs = null;
|
||||
|
||||
HideNewEditDeleteButtons();
|
||||
ShowSaveResetCancelButtons();
|
||||
@@ -519,17 +517,17 @@ namespace Elwig.Windows {
|
||||
if (ViewModel.SelectedMember is not Member m)
|
||||
return;
|
||||
|
||||
int areaCmts = 0, deliveries = 0, credits = 0;
|
||||
int areaComs = 0, deliveries = 0, credits = 0;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
areaCmts = await ctx.AreaCommitments.Where(c => c.MgNr == m.MgNr).CountAsync();
|
||||
areaComs = await ctx.AreaCommitments.Where(c => c.MgNr == m.MgNr).CountAsync();
|
||||
deliveries = await ctx.Deliveries.Where(d => d.MgNr == m.MgNr).CountAsync();
|
||||
credits = await ctx.Credits.Where(c => c.MgNr == m.MgNr).CountAsync();
|
||||
}
|
||||
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaCmts, deliveries, credits);
|
||||
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits);
|
||||
if (d.ShowDialog() == true) {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
try {
|
||||
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaCmts);
|
||||
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
|
||||
App.HintContextChange();
|
||||
} catch (Exception exc) {
|
||||
InteractionService.ShowDbException("Mitglied löschen", exc);
|
||||
@@ -582,8 +580,8 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
ViewModel.TransferPredecessorAreaCmts = null;
|
||||
ViewModel.CancelAreaCmts = null;
|
||||
ViewModel.TransferPredecessorAreaComs = null;
|
||||
ViewModel.CancelAreaComs = null;
|
||||
if (IsEditing) {
|
||||
RefreshInputs();
|
||||
} else if (IsCreating) {
|
||||
@@ -597,8 +595,8 @@ namespace Elwig.Windows {
|
||||
IsEditing = false;
|
||||
IsCreating = false;
|
||||
MemberList.IsEnabled = true;
|
||||
ViewModel.TransferPredecessorAreaCmts = null;
|
||||
ViewModel.CancelAreaCmts = null;
|
||||
ViewModel.TransferPredecessorAreaComs = null;
|
||||
ViewModel.CancelAreaComs = null;
|
||||
HideSaveResetCancelButtons();
|
||||
ShowNewEditDeleteButtons();
|
||||
RefreshInputs();
|
||||
@@ -612,7 +610,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void AreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
|
||||
App.FocusMemberAreaCmts(ViewModel.SelectedMember!.MgNr);
|
||||
App.FocusMemberAreaComs(ViewModel.SelectedMember!.MgNr);
|
||||
}
|
||||
|
||||
private void DeliveryButton_Click(object sender, RoutedEventArgs evt) {
|
||||
@@ -811,10 +809,6 @@ namespace Elwig.Windows {
|
||||
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) {
|
||||
if (!IsEditing && !IsCreating) {
|
||||
SearchInput.Focus();
|
||||
@@ -926,10 +920,10 @@ namespace Elwig.Windows {
|
||||
if (ViewModel.MgNr == mgnr)
|
||||
return;
|
||||
using var ctx = new AppDbContext();
|
||||
var areaCmts = await ctx.AreaCommitments
|
||||
var areaComs = await ctx.AreaCommitments
|
||||
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
|
||||
.ToListAsync();
|
||||
if (areaCmts.Count == 0)
|
||||
if (areaComs.Count == 0)
|
||||
return;
|
||||
|
||||
var oldMember = await ctx.FetchMembers(mgnr).SingleAsync();
|
||||
@@ -937,10 +931,10 @@ namespace Elwig.Windows {
|
||||
$"{ViewModel.Prefix}{(!string.IsNullOrWhiteSpace(ViewModel.Prefix) ? " " : "")}" +
|
||||
$"{ViewModel.GivenName}{(!string.IsNullOrWhiteSpace(ViewModel.GivenName) ? " " : "")}" +
|
||||
$"{ViewModel.Suffix}{(!string.IsNullOrWhiteSpace(ViewModel.Suffix) ? " " : "")}";
|
||||
var d = new AreaCmtTransferDialog(oldMember.AdministrativeName, newName, areaCmts.Count, areaCmts.Sum(c => c.Area));
|
||||
var d = new AreaComTransferDialog(oldMember.AdministrativeName, newName, areaComs.Count, areaComs.Sum(c => c.Area));
|
||||
if (d.ShowDialog() != true)
|
||||
return;
|
||||
ViewModel.TransferPredecessorAreaCmts = d.SuccessorSeason;
|
||||
ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason;
|
||||
if (IsEditing)
|
||||
SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save
|
||||
UpdateButtons();
|
||||
@@ -985,13 +979,13 @@ namespace Elwig.Windows {
|
||||
return;
|
||||
if ((IsEditing || IsCreating) && ViewModel.IsActive == false && ViewModel.MgNr is int mgnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
var areaCmts = await ctx.AreaCommitments
|
||||
var areaComs = await ctx.AreaCommitments
|
||||
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
|
||||
.ToListAsync();
|
||||
if (areaCmts.Count > 0) {
|
||||
var d = new AreaCmtTransferDialog(m.AdministrativeName, areaCmts.Count, areaCmts.Sum(c => c.Area));
|
||||
if (areaComs.Count > 0) {
|
||||
var d = new AreaComTransferDialog(m.AdministrativeName, areaComs.Count, areaComs.Sum(c => c.Area));
|
||||
if (d.ShowDialog() == true) {
|
||||
ViewModel.CancelAreaCmts = d.CancelSeason;
|
||||
ViewModel.CancelAreaComs = d.CancelSeason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,9 +99,9 @@ namespace Elwig.Windows {
|
||||
var allMembers = await ctx.Members.Where(m => m.DefaultKgNr == k.KgNr).CountAsync();
|
||||
StatusDefaultKgs.Text += $"{activeMembers:N0} ({allMembers:N0})";
|
||||
var year = Utils.CurrentNextSeason;
|
||||
var activeAreaCmts = await Utils.ActiveAreaCommitments(ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr), year).CountAsync();
|
||||
var allAreaCmts = await ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr).CountAsync();
|
||||
StatusAreaCommitments.Text += $"{activeAreaCmts:N0} ({allAreaCmts:N0})";
|
||||
var activeAreaComs = await Utils.ActiveAreaCommitments(ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr), year).CountAsync();
|
||||
var allAreaComs = await ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr).CountAsync();
|
||||
StatusAreaCommitments.Text += $"{activeAreaComs:N0} ({allAreaComs:N0})";
|
||||
var deliveryParts = await ctx.DeliveryParts.Where(p => p.KgNr == k.KgNr).CountAsync();
|
||||
var deliveries = await ctx.Deliveries.Where(d => d.Parts.Any(p => p.KgNr == k.KgNr)).CountAsync();
|
||||
StatusDeliveries.Text += $"{deliveries:N0} ({deliveryParts:N0})";
|
||||
|
||||
@@ -54,9 +54,9 @@ namespace Elwig.Windows {
|
||||
var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
|
||||
|
||||
var (tbl1, _, _) = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year);
|
||||
var tbl2 = await AreaCmtUnderDeliveryData.ForSeason(ctx.AreaCmtUnderDeliveryRows, Year);
|
||||
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, Year);
|
||||
var weight = tbl1.Rows.ToDictionary(r => r.MgNr, r => r.WeightTotal);
|
||||
var areaCmts = tbl2.Rows.ToDictionary(r => r.MgNr, r => r.VtrgIds.Zip(r.UnderDeliveries).ToDictionary(r => r.First, r => r.Second));
|
||||
var areaComs = tbl2.Rows.ToDictionary(r => r.MgNr, r => r.VtrgIds.Zip(r.UnderDeliveries).ToDictionary(r => r.First, r => r.Second));
|
||||
CustomPayments = await ctx.CustomPayments.Where(p => p.Year == Year).ToDictionaryAsync(p => p.MgNr, p => p);
|
||||
|
||||
var history = await ctx.MemberHistory
|
||||
@@ -93,7 +93,7 @@ namespace Elwig.Windows {
|
||||
(season.PenaltyPerShareAmount * Math.Floor(m.OverUnder / season.MinKgPerShare ?? 0m) ?? 0) +
|
||||
(m.Weight == 0 ? (-season.PenaltyNone ?? 0) + (-season.PenaltyPerShareNone * m.SharesActive ?? 0) : 0)
|
||||
: (decimal?)null,
|
||||
PenaltyAc = areaCmts.TryGetValue(m.MgNr, out var c) ? c.Select(r => {
|
||||
PenaltyAc = areaComs.TryGetValue(m.MgNr, out var c) ? c.Select(r => {
|
||||
var con = contracts[r.Key];
|
||||
return (r.Value.Kg * con.PenaltyPerKg ?? 0) + (r.Value.Kg < 0 ? con.PenaltyAmount ?? 0 : 0) + (r.Value.Percent == -100 ? con.PenaltyNone ?? 0 : 0);
|
||||
}).Sum() : (decimal?)null,
|
||||
|
||||
@@ -13,7 +13,7 @@ About
|
||||
**Product:** Elwig
|
||||
**Description:** Electronic Management for Vintners' Cooperatives
|
||||
**Type:** ERP system
|
||||
**Version:** 1.2.0.1 ([Changelog](./CHANGELOG.md))
|
||||
**Version:** 1.1.2.2 ([Changelog](./CHANGELOG.md))
|
||||
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||
**Website:** https://elwig.at/
|
||||
**Source code:** https://git.necronda.net/winzer/elwig
|
||||
@@ -33,7 +33,7 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||
**Produkt:** Elwig
|
||||
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
||||
**Typ:** Warenwirtschaftssystem (ERP-System)
|
||||
**Version:** 1.2.0.1 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||
**Version:** 1.1.2.2 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||
**Website:** https://elwig.at/
|
||||
**Quellcode:** https://git.necronda.net/winzer/elwig
|
||||
|
||||
@@ -298,7 +298,7 @@ namespace Tests.UnitTests.HelperTests {
|
||||
"73oe": 0.5,
|
||||
"17kmw": 0.6
|
||||
},
|
||||
"ctrd": 0.1
|
||||
"contracted": 0.1
|
||||
}, {
|
||||
"id": 2,
|
||||
"mode": "kmw",
|
||||
@@ -306,7 +306,7 @@ namespace Tests.UnitTests.HelperTests {
|
||||
"15kmw": 0.6,
|
||||
"17kmw": 0.7
|
||||
},
|
||||
"ctrd": {
|
||||
"contracted": {
|
||||
"73oe": 0.65,
|
||||
"17kmw": 0.80
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ namespace Tests.UnitTests.HelperTests {
|
||||
"id": 1,
|
||||
"mode": "oe",
|
||||
"data": {"15kmw": 0.54},
|
||||
"ctrd": 0.1
|
||||
"contracted": 0.1
|
||||
}, {
|
||||
"id": 2,
|
||||
"mode": "oe",
|
||||
"data": {"15kmw": 0.61},
|
||||
"ctrd": 0.1
|
||||
"contracted": 0.1
|
||||
}]
|
||||
}
|
||||
""";
|
||||
@@ -79,7 +79,7 @@ namespace Tests.UnitTests.HelperTests {
|
||||
""");
|
||||
}
|
||||
|
||||
private Task<Dictionary<string, AreaCmtBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr) {
|
||||
private Task<Dictionary<string, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
return ctx.GetMemberAreaCommitmentBuckets(year, mgnr, Connection);
|
||||
}
|
||||
@@ -122,11 +122,11 @@ namespace Tests.UnitTests.HelperTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_01_NoActiveAreaCmts() {
|
||||
public async Task Test_01_NoActiveAreaComs() {
|
||||
int mgnr = MgNr1, year = Year1;
|
||||
|
||||
var areaCmt = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||
Assert.That(areaCmt, Is.Empty);
|
||||
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||
Assert.That(areaCom, Is.Empty);
|
||||
var delivery = await GetMemberDeliveryBuckets(year, mgnr);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(delivery, Has.Count.EqualTo(3));
|
||||
@@ -163,13 +163,13 @@ namespace Tests.UnitTests.HelperTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_02_SimpleNotStrictAreaCmts() {
|
||||
public async Task Test_02_SimpleNotStrictAreaComs() {
|
||||
int mgnr = MgNr1, year = Year2;
|
||||
|
||||
var areaCmt = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(areaCmt, Has.Count.EqualTo(1));
|
||||
Assert.That(areaCmt["GV"], Is.EqualTo(new AreaCmtBucket(10_000, 5_000, 10_000)));
|
||||
Assert.That(areaCom, Has.Count.EqualTo(1));
|
||||
Assert.That(areaCom["GV"], Is.EqualTo(new AreaComBucket(10_000, 5_000, 10_000)));
|
||||
}
|
||||
var delivery = await GetMemberDeliveryBuckets(year, mgnr);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -209,13 +209,13 @@ namespace Tests.UnitTests.HelperTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_03_SimpleNotStrictAreaCmts_HonorContracted() {
|
||||
public async Task Test_03_SimpleNotStrictAreaComs_HonorContracted() {
|
||||
int mgnr = MgNr1, year = Year2;
|
||||
|
||||
var areaCmt = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(areaCmt, Has.Count.EqualTo(1));
|
||||
Assert.That(areaCmt["GV"], Is.EqualTo(new AreaCmtBucket(10_000, 5_000, 10_000)));
|
||||
Assert.That(areaCom, Has.Count.EqualTo(1));
|
||||
Assert.That(areaCom["GV"], Is.EqualTo(new AreaComBucket(10_000, 5_000, 10_000)));
|
||||
}
|
||||
var delivery = await GetMemberDeliveryBuckets(year, mgnr);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -255,56 +255,56 @@ namespace Tests.UnitTests.HelperTests {
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_04_ComplexNotStrictAreaCmts() {
|
||||
public Task Test_04_ComplexNotStrictAreaComs() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_05_ComplexNotStrictAreaCmts_HonorContracted() {
|
||||
public Task Test_05_ComplexNotStrictAreaComs_HonorContracted() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_06_StrictAreaCmts_NoFillLower_NotAllowed() {
|
||||
public Task Test_06_StrictAreaComs_NoFillLower_NotAllowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_07_StrictAreaCmts_NoFillLower_Allowed() {
|
||||
public Task Test_07_StrictAreaComs_NoFillLower_Allowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_08_StrictAreaCmts_NoFillLower_Allowed_AvoidUnderDeliveries() {
|
||||
public Task Test_08_StrictAreaComs_NoFillLower_Allowed_AvoidUnderDeliveries() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_09_StrictAreaCmts_FillLowerUntilObligation_NotAllowed() {
|
||||
public Task Test_09_StrictAreaComs_FillLowerUntilObligation_NotAllowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_10_StrictAreaCmts_FillLowerUntilObligation_Allowed() {
|
||||
public Task Test_10_StrictAreaComs_FillLowerUntilObligation_Allowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_11_StrictAreaCmts_FillLowerUntilObligation_Allowed_AvoidUnderDeliveries() {
|
||||
public Task Test_11_StrictAreaComs_FillLowerUntilObligation_Allowed_AvoidUnderDeliveries() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@@ -312,42 +312,42 @@ namespace Tests.UnitTests.HelperTests {
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_12_StrictAreaCmts_FillLowerUntilObligation_NotAllowed() {
|
||||
public Task Test_12_StrictAreaComs_FillLowerUntilObligation_NotAllowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_13_StrictAreaCmts_FillLowerUntilObligation_Allowed() {
|
||||
public Task Test_13_StrictAreaComs_FillLowerUntilObligation_Allowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_14_StrictAreaCmts_FillLowerUntilObligation_Allowed_AvoidUnderDeliveries() {
|
||||
public Task Test_14_StrictAreaComs_FillLowerUntilObligation_Allowed_AvoidUnderDeliveries() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_15_StrictAreaCmts_FillLowerUntilRight_NotAllowed() {
|
||||
public Task Test_15_StrictAreaComs_FillLowerUntilRight_NotAllowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_16_StrictAreaCmts_FillLowerUntilRight_Allowed() {
|
||||
public Task Test_16_StrictAreaComs_FillLowerUntilRight_Allowed() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public Task Test_17_StrictAreaCmts_FillLowerUntilRight_Allowed_AvoidUnderDeliveries() {
|
||||
public Task Test_17_StrictAreaComs_FillLowerUntilRight_Allowed_AvoidUnderDeliveries() {
|
||||
// TODO
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user