Files
elwig/Elwig/Windows/PaymentVariantsWindow.xaml.cs

352 lines
15 KiB
C#

using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Models.Dtos;
using Elwig.Models.Entities;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Elwig.Helpers.Billing;
using Elwig.Helpers.Export;
using Microsoft.Win32;
using System.Text.Json;
namespace Elwig.Windows {
public partial class PaymentVariantsWindow : ContextWindow {
public readonly int Year;
private bool DataValid, DataChanged, NameChanged, CommentChanged, TransferDateValid, TransferDateChanged;
private static readonly JsonSerializerOptions JsonOpt = new() { WriteIndented = true };
public PaymentVariantsWindow(int year) {
InitializeComponent();
Year = year;
Title = $"Auszahlungsvarianten - Lese {Year} - Elwig";
if (!App.Config.Debug) {
DataInput.Visibility = Visibility.Hidden;
}
}
protected override async Task OnRenewContext() {
ControlUtils.RenewItemsSource(PaymentVariantList, await Context.PaymentVariants.Where(v => v.Year == Year).OrderBy(v => v.AvNr).ToListAsync(), v => (v as PaymentVar)?.AvNr);
Update();
}
private void Update() {
if (PaymentVariantList.SelectedItem is PaymentVar v) {
var locked = !v.TestVariant;
DeleteButton.IsEnabled = !locked;
CalculateButton.IsEnabled = !locked;
CommitButton.IsEnabled = !locked;
CommitButton.Visibility = !locked ? Visibility.Visible : Visibility.Hidden;
RevertButton.IsEnabled = locked;
RevertButton.Visibility = locked ? Visibility.Visible : Visibility.Hidden;
CopyButton.IsEnabled = true;
EditButton.Content = locked ? "Ansehen" : "Bearbeiten";
ShowButton.IsEnabled = true;
PrintButton.IsEnabled = true;
ExportButton.IsEnabled = locked;
NameInput.Text = v.Name;
CommentInput.Text = v.Comment;
DateInput.Text = $"{v.Date:dd.MM.yyyy}";
TransferDateInput.Text = $"{v.TransferDate:dd.MM.yyyy}";
if (App.Config.Debug) {
try {
var json = BillingData.ParseJson(v.Data);
DataInput.Text = JsonSerializer.Serialize(json, JsonOpt);
} catch {
DataInput.Text = v.Data;
}
}
} else {
EditButton.Content = "Bearbeiten";
CopyButton.IsEnabled = false;
CalculateButton.IsEnabled = false;
CommitButton.IsEnabled = false;
CommitButton.Visibility = Visibility.Visible;
RevertButton.IsEnabled = false;
RevertButton.Visibility = Visibility.Hidden;
DeleteButton.IsEnabled = false;
ShowButton.IsEnabled = false;
PrintButton.IsEnabled = false;
ExportButton.IsEnabled = false;
NameInput.Text = "";
CommentInput.Text = "";
DateInput.Text = "";
TransferDateInput.Text = "";
DataInput.Text = "";
}
UpdateSums();
UpdateSaveButton();
}
private void UpdateSaveButton() {
SaveButton.IsEnabled = PaymentVariantList.SelectedItem != null &&
((DataChanged && DataValid) || NameChanged || CommentChanged ||
(TransferDateChanged && TransferDateValid));
}
private void UpdateSums() {
if (PaymentVariantList.SelectedItem is PaymentVar v) {
var sym = v.Season.Currency.Symbol;
ModifierSum.Text = $"{v.DeliveryPartPayments.Sum(p => p.Amount - p.NetAmount):N2} {sym}";
TotalSum.Text = $"{v.MemberPayments.Sum(p => p.Amount):N2} {sym}";
if (v.Credits.Count == 0) {
VatSum.Text = $"- {sym}";
DeductionSum.Text = $"- {sym}";
PaymentSum.Text = $"- {sym}";
} else {
VatSum.Text = $"{v.Credits.Sum(c => c.VatAmount):N2} {sym}";
DeductionSum.Text = $"{-v.Credits.Sum(c => c.Modifiers ?? 0):N2} {sym}";
PaymentSum.Text = $"{v.Credits.Sum(c => c.Amount):N2} {sym}";
}
} else {
ModifierSum.Text = "-";
TotalSum.Text = "-";
VatSum.Text = "-";
DeductionSum.Text = "-";
PaymentSum.Text = "-";
}
}
private void PaymentVariantList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
Update();
}
private void AddButton_Click(object sender, RoutedEventArgs evt) {
}
private void CopyButton_Click(object sender, RoutedEventArgs evt) {
}
private void DeleteButton_Click(object sender, RoutedEventArgs evt) {
}
private async void CalculateButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedValue is not PaymentVar v)
return;
CalculateButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
try {
var b = new BillingVariant(v.Year, v.AvNr);
await b.Calculate();
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Berechnungsfehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
await App.HintContextChange();
Mouse.OverrideCursor = null;
CalculateButton.IsEnabled = true;
}
private void EditButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v)
return;
App.FocusChartWindow(v.Year, v.AvNr);
}
private async void ShowButton_Click(object sender, RoutedEventArgs evt) {
await Generate(1);
}
private async void PrintButton_Click(object sender, RoutedEventArgs evt) {
await Generate(2);
}
private async void CommitButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedValue is not PaymentVar v)
return;
CommitButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
var b = new BillingVariant(v.Year, v.AvNr);
await b.Commit();
Mouse.OverrideCursor = null;
RevertButton.IsEnabled = true;
await App.HintContextChange();
}
private async void RevertButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedValue is not PaymentVar v)
return;
var res = MessageBox.Show(
"Sollen wirklich alle festgesetzten Traubengutschriften der ausgewählten Auszahlungsvariante unwiderruflich gelöscht werden?\n\n" +
"Dies ist im Allgemeinen nie empfohlen. Handelt es sich um die aktuellste Auszahlungsvariante könnte das eine Ausnahme sein.",
"Traubengutschriften löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (res != MessageBoxResult.Yes)
return;
RevertButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
var b = new BillingVariant(v.Year, v.AvNr);
await b.Revert();
Mouse.OverrideCursor = null;
CommitButton.IsEnabled = true;
await App.HintContextChange();
}
private async void ExportButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedValue is not PaymentVar v) {
return;
} else if (v.TransferDate == null) {
MessageBox.Show("Überweisungsdatum muss gesetzt sein!", "Exportieren nicht möglich", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
var d = new SaveFileDialog() {
FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}",
DefaultExt = Ebics.FileExtension,
Filter = "EBICS-Datei (*.xml)|*.xml",
Title = $"Überweisungsdaten speichern unter - Elwig",
};
if (d.ShowDialog() == true) {
ExportButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
using var e = new Ebics(v, d.FileName);
await e.ExportAsync(Transaction.FromPaymentVariant(v));
Mouse.OverrideCursor = null;
ExportButton.IsEnabled = true;
}
}
private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) return;
try {
v.Name = NameInput.Text;
v.Comment = (CommentInput.Text != "") ? CommentInput.Text : null;
v.TransferDateString = (TransferDateInput.Text != "") ? string.Join("-", TransferDateInput.Text.Split(".").Reverse()) : null;
if (App.Config.Debug) v.Data = JsonSerializer.Serialize(BillingData.ParseJson(DataInput.Text));
Context.Update(v);
await Context.SaveChangesAsync();
await App.HintContextChange();
} catch (Exception exc) {
await HintContextChange();
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, "Auszahlungsvariante aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void NameInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(NameInput);
return;
}
if (NameInput.Text != v.Name) {
ControlUtils.SetInputChanged(NameInput);
NameChanged = true;
} else {
ControlUtils.ClearInputState(NameInput);
NameChanged = false;
}
UpdateSaveButton();
}
private void CommentInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(CommentInput);
return;
}
if (CommentInput.Text != (v.Comment ?? "")) {
ControlUtils.SetInputChanged(CommentInput);
CommentChanged = true;
} else {
ControlUtils.ClearInputState(CommentInput);
CommentChanged = false;
}
UpdateSaveButton();
}
private void TransferDateInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(TransferDateInput);
return;
}
var res = Validator.CheckDate(TransferDateInput, false);
if (!res.IsValid) {
ControlUtils.SetInputInvalid(TransferDateInput);
TransferDateValid = false;
} else if (TransferDateInput.Text != $"{v.TransferDate:dd.MM.yyyy}") {
ControlUtils.SetInputChanged(TransferDateInput);
TransferDateValid = true;
TransferDateChanged = true;
} else {
ControlUtils.ClearInputState(TransferDateInput);
TransferDateValid = true;
TransferDateChanged = false;
}
UpdateSaveButton();
}
private void DataInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(DataInput);
return;
}
try {
var json = BillingData.ParseJson(DataInput.Text);
var origJson = v.Data;
try {
origJson = JsonSerializer.Serialize(BillingData.ParseJson(v.Data));
} catch { }
DataValid = true;
if (JsonSerializer.Serialize(json) != origJson) {
ControlUtils.SetInputChanged(DataInput);
DataChanged = true;
} else {
ControlUtils.ClearInputState(DataInput);
DataChanged = false;
}
} catch {
ControlUtils.SetInputInvalid(DataInput);
DataValid = false;
}
UpdateSaveButton();
}
private async Task Generate(int mode) {
if (PaymentVariantList.SelectedItem is not PaymentVar v)
return;
Mouse.OverrideCursor = Cursors.AppStarting;
var members = Context.Members.FromSqlRaw($"""
SELECT m.*
FROM member m
INNER JOIN delivery d ON d.mgnr = m.mgnr
WHERE d.year = {Year}
GROUP BY m.mgnr
""");
members = members.OrderBy(m => m.MgNr);
IEnumerable<Member> list = await members.ToListAsync();
var data = await CreditNoteData.ForPaymentVariant(Context.CreditNoteRows, Context.Seasons, v.Year, v.AvNr);
var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
await Context.GetMemberAreaCommitmentBuckets(Year, 0);
using var doc = Document.Merge(list.Select(m =>
new CreditNote(Context, payments[m.MgNr], data[m.MgNr], Context.GetMemberUnderDelivery(Year, m.MgNr).GetAwaiter().GetResult())
));
await doc.Generate(new Progress<double>(v => {
ProgressBar.Value = v;
}));
Mouse.OverrideCursor = null;
if (mode < 2) {
doc.Show();
return;
}
if (App.Config.Debug) {
doc.Show();
} else {
await doc.Print();
}
}
}
}