[#48] Billing: Add custom modifiers for members
All checks were successful
Test / Run tests (push) Successful in 2m21s
All checks were successful
Test / Run tests (push) Successful in 2m21s
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Billing;
|
||||
using Elwig.Models.Dtos;
|
||||
using Elwig.Models.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -17,6 +18,8 @@ namespace Elwig.Windows {
|
||||
public readonly int Year;
|
||||
public readonly bool SeasonLocked;
|
||||
|
||||
public Dictionary<int, PaymentCustom>? CustomPayments;
|
||||
|
||||
public PaymentAdjustmentWindow(int year) {
|
||||
InitializeComponent();
|
||||
Year = year;
|
||||
@ -26,6 +29,10 @@ namespace Elwig.Windows {
|
||||
Title = $"Auszahlung anpassen - Lese {Year} - Elwig";
|
||||
AutoAdjustBsButton.IsEnabled = !SeasonLocked;
|
||||
UnAdjustBsButton.IsEnabled = !SeasonLocked;
|
||||
SaveCustomButton.IsEnabled = !SeasonLocked;
|
||||
RemoveCustomButton.IsEnabled = !SeasonLocked;
|
||||
CustomAmountInput.IsEnabled = !SeasonLocked;
|
||||
CustomCommentInput.IsEnabled = !SeasonLocked;
|
||||
|
||||
AllowanceKgInput.Text = $"{App.Client.AutoAdjustBs.AllowanceKg}";
|
||||
AllowanceBsInput.Text = $"{App.Client.AutoAdjustBs.AllowanceBs}";
|
||||
@ -54,6 +61,7 @@ namespace Elwig.Windows {
|
||||
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, Year);
|
||||
var weight = tbl1.Rows.ToDictionary(r => r.MgNr, r => r.Weight);
|
||||
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
|
||||
.Where(h => h.DateString.CompareTo($"{Year}-01-01") >= 0 && h.DateString.CompareTo($"{Year}-12-31") <= 0 && h.Type == "auto" && h.BusinessShares > 0)
|
||||
@ -95,6 +103,7 @@ namespace Elwig.Windows {
|
||||
}).Sum() : (decimal?)null,
|
||||
m.Adjust,
|
||||
m.AdjustAmount,
|
||||
Custom = CustomPayments!.GetValueOrDefault(m.MgNr, null)?.Amount,
|
||||
})
|
||||
.Select(m => new {
|
||||
m.MgNr, m.FamilyName, m.GivenName,
|
||||
@ -103,22 +112,23 @@ namespace Elwig.Windows {
|
||||
PenaltyAc = m.PenaltyAc == null ? (decimal?)null : Math.Round((decimal)m.PenaltyAc, 2),
|
||||
m.Adjust,
|
||||
AdjustAmount = m.AdjustAmount == null ? (decimal?)null : Math.Round((decimal)m.AdjustAmount, 2),
|
||||
m.Custom
|
||||
})
|
||||
.Select(m => new {
|
||||
m.MgNr, m.FamilyName, m.GivenName,
|
||||
m.BusinessShares, m.Weight, m.OverUnder,
|
||||
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount,
|
||||
Total = (m.PenaltyBs ?? 0) + (m.PenaltyAc ?? 0) + (m.AdjustAmount ?? 0),
|
||||
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.Custom,
|
||||
Total = (m.PenaltyBs ?? 0) + (m.PenaltyAc ?? 0) + (m.AdjustAmount ?? 0) + (m.Custom ?? 0),
|
||||
})
|
||||
.Select(m => new {
|
||||
m.MgNr, m.FamilyName, m.GivenName,
|
||||
m.BusinessShares, m.Weight, m.OverUnder,
|
||||
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount,
|
||||
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.Custom,
|
||||
m.Total,
|
||||
Background = m.Weight == 0 ? Brushes.Orange : m.Weight / 2 < -m.Total ? Brushes.Red : Brushes.White,
|
||||
Foreground = m.Total == 0 ? Brushes.Gray : Brushes.Black,
|
||||
})
|
||||
.Where(m => m.OverUnder != null || m.Adjust != null || m.PenaltyBs != null || m.PenaltyAc != null)
|
||||
.Where(m => m.OverUnder != null || m.Adjust != null || m.PenaltyBs != null || m.PenaltyAc != null || m.Custom != null)
|
||||
.OrderByDescending(m => m.OverUnder ?? 0)
|
||||
.ThenBy(m => m.FamilyName)
|
||||
.ThenBy(m => m.GivenName)
|
||||
@ -131,8 +141,16 @@ namespace Elwig.Windows {
|
||||
PenaltyBusinessShares.Text = $"{list.Count(r => r.PenaltyBs != null && r.PenaltyBs != 0)} Mg. / {list.Sum(r => r.PenaltyBs):N2} {sym}";
|
||||
PenaltyAreaCommitments.Text = $"{list.Count(r => r.PenaltyAc != null && r.PenaltyAc != 0)} Mg. / {list.Sum(r => r.PenaltyAc):N2} {sym}";
|
||||
AutoBusinessShareAdjustment.Text = $"{list.Count(r => r.Adjust > 0)} Mg. / {list.Sum(r => r.Adjust)} GA / {list.Sum(r => r.AdjustAmount):N2} {sym}";
|
||||
CustomModifiers.Text = $"{list.Count(r => r.Custom != null)} Mg. / {list.Sum(r => r.Custom):N2} {sym}";
|
||||
TotalModifiers.Text = $"{list.Count(r => r.Total != 0)} Mg. / {list.Sum(r => r.Total):N2} {sym}";
|
||||
NonDeliveries.Text = $"{list.Count(r => r.Weight == 0):N0}";
|
||||
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.OrderBy(m => m.FamilyName)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
CustomAmountInput.Unit = sym;
|
||||
}
|
||||
|
||||
private async void AutoAdjustBsButton_Click(object sender, RoutedEventArgs evt) {
|
||||
@ -191,5 +209,82 @@ namespace Elwig.Windows {
|
||||
private void PercentInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
Validator.CheckDecimal((TextBox)sender, false, 3, 2);
|
||||
}
|
||||
|
||||
private void MemberList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
||||
if (MemberList.SelectedItem != null) {
|
||||
var i = MemberList.SelectedItem;
|
||||
var t = i.GetType();
|
||||
MgNrInput.Text = t.GetProperty("MgNr")?.GetValue(i)?.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void MgNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
var res = Validator.CheckMgNr((TextBox)sender, true);
|
||||
ControlUtils.SelectItemWithPk(MemberInput, res.IsValid ? int.Parse(MgNrInput.Text) : null);
|
||||
}
|
||||
|
||||
private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
||||
var res = Validator.CheckMgNr((TextBox)sender, true);
|
||||
ControlUtils.SelectItemWithPk(MemberInput, res.IsValid ? int.Parse(MgNrInput.Text) : null);
|
||||
}
|
||||
|
||||
private void MemberInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
||||
if (MemberInput.SelectedItem is Member m) {
|
||||
MgNrInput.Text = m.MgNr.ToString();
|
||||
MemberList.SelectedItem = MemberList.ItemsSource.Cast<object>().FirstOrDefault(i => {
|
||||
var t = i.GetType();
|
||||
return (int?)t.GetProperty("MgNr")?.GetValue(i) == m.MgNr;
|
||||
});
|
||||
if (MemberList.SelectedItem != null)
|
||||
MemberList.ScrollIntoView(MemberList.SelectedItem);
|
||||
|
||||
if (CustomPayments?.TryGetValue(m.MgNr, out var p) == true) {
|
||||
CustomAmountInput.Text = $"{p.Amount:N2}";
|
||||
CustomCommentInput.Text = p.Comment ?? "";
|
||||
} else {
|
||||
CustomAmountInput.Text = "";
|
||||
CustomCommentInput.Text = "";
|
||||
}
|
||||
} else {
|
||||
CustomAmountInput.Text = "";
|
||||
CustomCommentInput.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (MemberInput.SelectedItem is not Member m) return;
|
||||
App.FocusMember(m.MgNr);
|
||||
}
|
||||
|
||||
private void CustomAmountInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
Validator.CheckDecimal((TextBox)sender, false, 4, 2, true);
|
||||
}
|
||||
|
||||
private async void CustomButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (MemberInput.SelectedItem is not Member m) return;
|
||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
if (CustomPayments?.TryGetValue(m.MgNr, out var p) == true) {
|
||||
ctx.Remove(p);
|
||||
}
|
||||
if (sender == SaveCustomButton && decimal.TryParse(CustomAmountInput.Text, out var num)) {
|
||||
var text = CustomCommentInput.Text.Trim();
|
||||
ctx.Add(new PaymentCustom {
|
||||
MgNr = m.MgNr,
|
||||
Year = Year,
|
||||
Amount = num,
|
||||
Comment = text == "" ? null : text,
|
||||
});
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
} catch (Exception exc) {
|
||||
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
|
||||
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
|
||||
MessageBox.Show(str, "Benutzerdefinierten Zu-/Abschlag speichern", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
await App.HintContextChange();
|
||||
Mouse.OverrideCursor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user