From a62fb9ab166d930bba3c40afcb3ebbf140d02772 Mon Sep 17 00:00:00 2001
From: Lorenz Stechauner <lorenz.stechauner@necronda.net>
Date: Mon, 31 Jul 2023 15:42:46 +0200
Subject: [PATCH] Saving delivery now works

---
 Elwig/Helpers/AppDbContext.cs             |   8 ++
 Elwig/Windows/AdministrationWindow.cs     |   1 +
 Elwig/Windows/DeliveryAdminWindow.xaml.cs | 147 +++++++++++++++++++++-
 Elwig/Windows/MemberAdminWindow.xaml.cs   |  12 +-
 4 files changed, 162 insertions(+), 6 deletions(-)

diff --git a/Elwig/Helpers/AppDbContext.cs b/Elwig/Helpers/AppDbContext.cs
index 8a31829..bd13968 100644
--- a/Elwig/Helpers/AppDbContext.cs
+++ b/Elwig/Helpers/AppDbContext.cs
@@ -122,6 +122,14 @@ namespace Elwig.Helpers {
             return c + 1;
         }
 
+        public async Task<int> NextDId(int year) {
+            return await Deliveries.Where(d => d.Year == year).Select(d => d.DId).MaxAsync() + 1;
+        }
+
+        public async Task<int> NextDPNr(int year, int did) {
+            return await DeliveryParts.Where(p => p.Year == year && p.DId == did).Select(d => d.DPNr).MaxAsync() + 1;
+        }
+
         public async Task<WineQualLevel> GetWineQualityLevel(double kmw) {
             return await WineQualityLevels
                 .Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw))
diff --git a/Elwig/Windows/AdministrationWindow.cs b/Elwig/Windows/AdministrationWindow.cs
index 55b33f8..f929687 100644
--- a/Elwig/Windows/AdministrationWindow.cs
+++ b/Elwig/Windows/AdministrationWindow.cs
@@ -222,6 +222,7 @@ namespace Elwig.Windows {
             !IsValid ||
             TextBoxInputs.Any(InputHasChanged) ||
             ComboBoxInputs.Any(InputHasChanged) ||
+            CheckComboBoxInputs.Any(InputHasChanged) ||
             CheckBoxInputs.Any(InputHasChanged) ||
             RadioButtonInputs.Any(InputHasChanged);
 
diff --git a/Elwig/Windows/DeliveryAdminWindow.xaml.cs b/Elwig/Windows/DeliveryAdminWindow.xaml.cs
index a3f4e3b..119707b 100644
--- a/Elwig/Windows/DeliveryAdminWindow.xaml.cs
+++ b/Elwig/Windows/DeliveryAdminWindow.xaml.cs
@@ -1,6 +1,7 @@
 using Elwig.Helpers;
 using Elwig.Models;
 using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -226,6 +227,130 @@ namespace Elwig.Windows {
             FillOriginalValues();
         }
 
+        private async Task<DeliveryPart> UpdateDeliveryPart(Delivery? d, DeliveryPart? p) {
+            int year, did, dpnr;
+            bool deliveryNew = d == null;
+            if (d == null) {
+                d = Context.CreateProxy<Delivery>();
+                year = Utils.CurrentNextSeason;
+                did = await Context.NextDId(year);
+            } else {
+                year = d.Year;
+                did = d.DId;
+            }
+            if (p == null) {
+                p = Context.CreateProxy<DeliveryPart>();
+                dpnr = await Context.NextDPNr(year, did);
+            } else {
+                dpnr = p.DPNr;
+            }
+            d.Year = year;
+            d.DId = did;
+            p.Year = year;
+            p.DId = did;
+            p.DPNr = dpnr;
+
+            d.DateString = string.Join("-", DateInput.Text.Split(".").Reverse());
+            if (IsCreating || InputHasChanged(DateInput)) {
+                d.LNr = await Context.NextLNr(d.Date);
+            }
+            if (IsCreating) {
+                d.TimeString = DateTime.Now.ToString("HH:mm:SS");
+            } else if (InputHasChanged(TimeInput)) {
+                d.TimeString = TimeInput.Text + ":00";
+            }
+            d.ZwstId = (BranchInput.SelectedItem as Branch)?.ZwstId;
+            d.LsNr = LsNrInput.Text;
+            d.MgNr = int.Parse(MgNrInput.Text);
+            d.Comment = (CommentInput.Text == "") ? null : CommentInput.Text;
+
+            p.SortId = (WineVarietyInput.SelectedItem as WineVar)?.SortId;
+            p.Weight = int.Parse(WeightInput.Text);
+            p.Kmw = double.Parse(GradationKmwInput.Text);
+            p.QualId = (WineQualityLevelInput.SelectedItem as WineQualLevel)?.QualId;
+            p.HkId = (WineOriginInput.SelectedItem as WineOrigin)?.HkId;
+            p.KgNr = (WineKgInput.SelectedItem as AT_Kg)?.KgNr;
+            p.RdNr = (WineRdInput.SelectedItem as WbRd)?.RdNr;
+
+            p.IsGerebelt = GerebeltGewogenInput.IsChecked ?? false;
+            p.ManualWeighing = ManualWeighingInput.IsChecked ?? false;
+            p.IsHandPicked = HandPickedInput.IsChecked;
+            p.IsLesewagen = LesewagenInput.IsChecked;
+            p.Temperature = (TemperatureInput.Text == "") ? null : double.Parse(TemperatureInput.Text);
+            p.Acid = (TemperatureInput.Text == "") ? null : double.Parse(AcidInput.Text);
+            p.Comment = (PartCommentInput.Text == "") ? null : PartCommentInput.Text;
+
+            // TODO weighing/scale id
+            // p.ScaleId
+            // p.WeighingId
+
+            EntityEntry<Delivery>? dEntry = null;
+            EntityEntry<DeliveryPart>? pEntry = null;
+            try {
+                if (IsEditing) {
+                    dEntry = Context.Update(d);
+                    pEntry = Context.Update(p);
+                } else if (IsCreating) {
+                    if (deliveryNew) {
+                        dEntry = await Context.AddAsync(d);
+                    } else {
+                        dEntry = Context.Update(d);
+                    }
+                    pEntry = await Context.AddAsync(p);
+                }
+
+                foreach (var a in AttributesInput.ItemsSource.Cast<WineAttr>()) {
+                    var attr = p.PartAttributes.Where(pa => pa.AttrId == a.AttrId).FirstOrDefault();
+                    if (AttributesInput.SelectedItems.Contains(a)) {
+                        DeliveryPartAttr dpa = attr ?? Context.CreateProxy<DeliveryPartAttr>();
+                        dpa.Year = year;
+                        dpa.DId = did;
+                        dpa.DPNr = dpnr;
+                        dpa.AttrId = a.AttrId;
+                        if (attr == null) {
+                            await Context.AddAsync(dpa);
+                        } else {
+                            Context.Update(dpa);
+                        }
+                    } else {
+                        if (attr != null) {
+                            Context.Remove(attr);
+                        }
+                    }
+                }
+
+                foreach (var m in ModifiersInput.ItemsSource.Cast<Modifier>()) {
+                    var mod = p.PartModifiers.Where(pa => pa.ModId == m.ModId).FirstOrDefault();
+                    if (ModifiersInput.SelectedItems.Contains(m)) {
+                        DeliveryPartModifier dpm = mod ?? Context.CreateProxy<DeliveryPartModifier>();
+                        dpm.Year = year;
+                        dpm.DId = did;
+                        dpm.DPNr = dpnr;
+                        dpm.ModId = m.ModId;
+                        if (mod == null) {
+                            await Context.AddAsync(dpm);
+                        } else {
+                            Context.Update(dpm);
+                        }
+                    } else {
+                        if (mod != null) {
+                            Context.Remove(mod);
+                        }
+                    }
+                }
+
+                await Context.SaveChangesAsync();
+            } catch (Exception exc) {
+                if (dEntry != null) await dEntry.ReloadAsync();
+                if (pEntry != null) await pEntry.ReloadAsync();
+                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, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+
+            return p;
+        }
+
         private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
             TextFilter = SearchInput.Text.ToLower().Split(" ").ToList().FindAll(e => e.Length > 0);
             await RefreshDeliveryListQuery(true);
@@ -349,8 +474,26 @@ namespace Elwig.Windows {
             // TODO delete delivery
         }
 
-        private void SaveButton_Click(object sender, RoutedEventArgs evt) {
-            // TODO save delivery (part)
+        private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
+            DeliveryPart p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
+
+            IsEditing = false;
+            IsCreating = false;
+            DeliveryList.IsEnabled = true;
+            DeliveryPartList.IsEnabled = true;
+
+            HideSaveResetCancelButtons();
+            ShowNewEditDeleteButtons();
+            LockInputs();
+            UnlockSearchInputs();
+            FillOriginalValues();
+            await RefreshDeliveryList();
+            RefreshDeliveryParts();
+            RefreshInputs();
+
+            AbwertenButton.IsEnabled = true;
+            ExtractDeliveryPartButton.IsEnabled = true;
+            DeleteDeliveryPartButton.IsEnabled = true;
         }
 
         private void ResetButton_Click(object sender, RoutedEventArgs evt) {
diff --git a/Elwig/Windows/MemberAdminWindow.xaml.cs b/Elwig/Windows/MemberAdminWindow.xaml.cs
index 90b68fe..742d070 100644
--- a/Elwig/Windows/MemberAdminWindow.xaml.cs
+++ b/Elwig/Windows/MemberAdminWindow.xaml.cs
@@ -137,7 +137,7 @@ namespace Elwig.Windows {
             inputs.Item3.Text = comment;
         }
 
-        private (string, string, string?)? GetPhonenrInput(int nr) {
+        private (string, string, string?)? GetPhoneNrInput(int nr) {
             var inputs = PhoneNrInputs[nr];
             var number = inputs.Item2.Text;
             if (string.IsNullOrEmpty(number))
@@ -206,7 +206,7 @@ namespace Elwig.Windows {
         }
 
         private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
-            Member m = await UpdateMember(IsEditing ? (Member)MemberList.SelectedItem : Context.CreateProxy<Member>());
+            Member m = await UpdateMember(MemberList.SelectedItem as Member);
             IsEditing = false;
             IsCreating = false;
             MemberList.IsEnabled = true;
@@ -215,7 +215,9 @@ namespace Elwig.Windows {
             LockInputs();
             UpdatePhoneNrInputVisibility();
             UnlockSearchInputs();
+            FillOriginalValues();
             await RefreshMemberList();
+            RefreshInputs();
             SearchInput.Text = "";
             MemberList.SelectedItem = m;
         }
@@ -326,7 +328,9 @@ namespace Elwig.Windows {
             }
         }
 
-        private async Task<Member> UpdateMember(Member m) {
+        private async Task<Member> UpdateMember(Member? m) {
+            m ??= Context.CreateProxy<Member>();
+
             int newMgNr = int.Parse(MgNrInput.Text);
             m.PredecessorMgNr = (PredecessorMgNrInput.Text == "") ? null : int.Parse(PredecessorMgNrInput.Text);
             m.Prefix = (PrefixInput.Text == "") ? null : PrefixInput.Text;
@@ -389,7 +393,7 @@ namespace Elwig.Windows {
                 }
 
                 for (int i = 0, j = 0; i < PhoneNrInputs.Length; i++) {
-                    var input = GetPhonenrInput(i);
+                    var input = GetPhoneNrInput(i);
                     var phoneNr = m.TelephoneNumbers.FirstOrDefault(p => p.Nr - 1 == i);
                     if (input == null) {
                         if (phoneNr != null) {