diff --git a/ENI2/Controls/EasyPeasyControl.xaml b/ENI2/Controls/EasyPeasyControl.xaml index 1cec118d..02b09fca 100644 --- a/ENI2/Controls/EasyPeasyControl.xaml +++ b/ENI2/Controls/EasyPeasyControl.xaml @@ -51,7 +51,7 @@ (yyyy-MM-ddTHH:mm:ss)" TextAlignment="Right" VerticalAlignment="Center" Margin="0,0,4,0"/> - + @@ -77,7 +77,7 @@ + PreviewKeyDown="DataGrid_PreviewKeyDown" Focusable="True" MinHeight="80" IsTabStop="True" MaxHeight="320"> diff --git a/ENI2/Controls/EasyPeasyControl.xaml.cs b/ENI2/Controls/EasyPeasyControl.xaml.cs index bc5406a4..bfc62ea2 100644 --- a/ENI2/Controls/EasyPeasyControl.xaml.cs +++ b/ENI2/Controls/EasyPeasyControl.xaml.cs @@ -7,12 +7,15 @@ using ENI2.Util; using Microsoft.Win32; using System; using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; +using System.Windows.Data; using System.Windows.Input; using System.Windows.Media.Imaging; using System.Xml; @@ -28,6 +31,8 @@ namespace ENI2.Controls private ProofRequest _vm; + #region Construction + public EasyPeasyControl() { InitializeComponent(); @@ -46,7 +51,23 @@ namespace ENI2.Controls deleteItem.Click += DeleteItem_Click; this.dataGridGoodsItems.ContextMenu.Items.Add(deleteItem); - } + // Add separator and paste option + this.dataGridGoodsItems.ContextMenu.Items.Add(new Separator()); + + MenuItem pasteItem = new MenuItem(); + pasteItem.Header = "Paste"; + pasteItem.Click += (s, e) => HandlePasteOperation(); + this.dataGridGoodsItems.ContextMenu.Items.Add(pasteItem); + + // Add command bindings for proper keyboard handling + this.dataGridGoodsItems.CommandBindings.Add(new CommandBinding( + ApplicationCommands.Paste, + (s, e) => HandlePasteOperation(), + (s, e) => e.CanExecute = Clipboard.ContainsText())); + + } + + #endregion public void SaveState() { @@ -87,11 +108,17 @@ namespace ENI2.Controls private void buttonClear_Click(object sender, RoutedEventArgs e) { + CleanupAutoCalculation(); + this._vm = EasyPeasyState.CreateDefault(); if (_vm.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF?.GoodsItemsForT2LT2LF == null) _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF = new ObservableCollection(); - + + _vm.ProofInformationT2LT2LF.DeclarationDate = DateTime.Now; // reset to today + _vm.ProofInformationT2LT2LF.RequestedValidityOfTheProof.NumberOfDays = 90; // default 90 days + this.DataContext = this._vm; + SetupAutoCalculation(); } private void buttonExport_Click(object sender, RoutedEventArgs e) @@ -145,6 +172,7 @@ namespace ENI2.Controls { using (var fs = File.OpenRead(ofd.FileName)) { + CleanupAutoCalculation(); var ser = new XmlSerializer(typeof(ProofRequest)); _vm = (ProofRequest)ser.Deserialize(fs); // after loading/creating _vm @@ -152,8 +180,11 @@ namespace ENI2.Controls _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF = new ObservableCollection(); _vm.ProofInformationT2LT2LF.DeclarationDate = DateTime.Now; // reset to today + if(_vm.ProofInformationT2LT2LF.RequestedValidityOfTheProof.NumberOfDays == 9) + _vm.ProofInformationT2LT2LF.RequestedValidityOfTheProof.NumberOfDays = 90; // default 90 days this.DataContext = _vm; + SetupAutoCalculation(); } } } @@ -175,10 +206,14 @@ namespace ENI2.Controls }; _vm.ProofInformationT2LT2LF.DeclarationDate = DateTime.Now; // reset to today this.DataContext = _vm; + + SetupAutoCalculation(); } private void UserControl_Unloaded(object sender, RoutedEventArgs e) { + CleanupAutoCalculation(); + try { EasyPeasyState.Save(_vm); @@ -188,8 +223,95 @@ namespace ENI2.Controls #endregion + #region auto calculation total gross mass + + private void SetupAutoCalculation() + { + if (_vm?.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF?.GoodsItemsForT2LT2LF != null) + { + // Subscribe to collection changes (add/remove items) + _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF.CollectionChanged += GoodsItems_CollectionChanged; + + // Subscribe to DataGrid cell changes + dataGridGoodsItems.CellEditEnding += DataGridGoodsItems_CellEditEnding; + + // Calculate initial total + CalculateTotalGrossMass(); + } + } + + private void CleanupAutoCalculation() + { + if (_vm?.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF?.GoodsItemsForT2LT2LF != null) + { + // Unsubscribe from collection changes + _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF.CollectionChanged -= GoodsItems_CollectionChanged; + dataGridGoodsItems.CellEditEnding -= DataGridGoodsItems_CellEditEnding; + } + } + + private void DataGridGoodsItems_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) + { + // Check if the edited column is GrossMass + if (e.Column.Header.ToString() == "Gross") + { + // Delay calculation to allow the binding to update + Dispatcher.BeginInvoke(new Action(() => { + CalculateTotalGrossMass(); + }), System.Windows.Threading.DispatcherPriority.Background); + } + } + + private void GoodsItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + // Recalculate total after any collection change + CalculateTotalGrossMass(); + } + + private void CalculateTotalGrossMass() + { + if (_vm?.ProofInformationT2LT2LF?.GoodsShipmentForT2LT2LF?.GoodsItemsForT2LT2LF != null) + { + var total = _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF + .Sum(item => item.GoodsMeasure?.GrossMass ?? 0m); + + _vm.ProofInformationT2LT2LF.TotalGrossMassKg = total; + + // Force UI update by refreshing the binding + var binding = BindingOperations.GetBindingExpression( + FindTotalGrossMassTextBox(), TextBox.TextProperty); + binding?.UpdateTarget(); + } + } + + // Simple property changed notification helper + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + private TextBox FindTotalGrossMassTextBox() + { + // Find the TextBox that displays TotalGrossMassKg + return this.FindName("textBoxTotalGrossMass") as TextBox ?? + this.GetTemplateChild("textBoxTotalGrossMass") as TextBox; + } + + #endregion + #region cut & paste logic + private void HandlePasteOperation() + { + if (Clipboard.ContainsText()) + { + var text = Clipboard.GetText(); + if (!TryPaste_EspHsPkgsGross(text)) + PasteGoodsItems(text); + } + } + private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) @@ -228,7 +350,7 @@ namespace ENI2.Controls if (cells.Length > 4 && decimal.TryParse(cells[4], out var net)) item.GoodsMeasure.NetMass = net; if (cells.Length > 5 && int.TryParse(cells[5], out var pkgs)) item.Packaging.NumberOfPackages = pkgs; if (cells.Length > 6) item.Packaging.TypeOfPackages = cells[6].Trim(); - if (cells.Length > 7) item.Packaging.ShippingMarks = cells[7].Trim(); + if (cells.Length > 7) item.Packaging.ShippingMarks = cells[7].Trim(); _vm.ProofInformationT2LT2LF.GoodsShipmentForT2LT2LF.GoodsItemsForT2LT2LF.Add(item); } @@ -333,7 +455,7 @@ namespace ENI2.Controls item.DescriptionOfGoods = "Brand New Vehicles"; // per spec item.Packaging.TypeOfPackages = "UN"; // per spec - item.Packaging.ShippingMarks = "-"; // per spec + item.Packaging.ShippingMarks = "-"; // per spec list.Add(item); anyAdded = true; diff --git a/ENI2/DetailRootControl.xaml.cs b/ENI2/DetailRootControl.xaml.cs index bf2eb99b..8ead1cd2 100644 --- a/ENI2/DetailRootControl.xaml.cs +++ b/ENI2/DetailRootControl.xaml.cs @@ -527,9 +527,14 @@ namespace ENI2 { if ((message.Status == Message.MessageStatus.ACCEPTED) && ((message.InternalStatus == Message.BSMDStatus.CONFIRMED) || (message.InternalStatus == Message.BSMDStatus.VIOLATION))) + { message.InternalStatus = Message.BSMDStatus.UPDATED; + message.Status = null; // reset send status + } else + { message.InternalStatus = Message.BSMDStatus.SAVED; + } string userName = "?"; if(App.UserId.HasValue && DBManager.Instance.GetReportingPartyDict().ContainsKey(App.UserId.Value))