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 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(v => { ProgressBar.Value = v; })); Mouse.OverrideCursor = null; if (mode < 2) { doc.Show(); return; } if (App.Config.Debug) { doc.Show(); } else { await doc.Print(); } } } }