using bsmd.database; using ENI2.Excel; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; namespace ENI2.Controls { /// /// Interaction logic for WASExemptionsControl.xaml /// public partial class WASExemptionsControl : UserControl { private DataGridColumn _editColumn; private object _editOriginalValue; public WASExemptionsControl() { InitializeComponent(); this.dataGridWASExemptions.ItemsSource = WASExemption.Exemptions; var view = CollectionViewSource.GetDefaultView(WASExemption.Exemptions); view.SortDescriptions.Add(new SortDescription(nameof(WASExemption.ShipName), ListSortDirection.Ascending)); _ = WASExemption.EnsureLoadedAsync(); this.dataGridWASExemptions.ContextMenu = new ContextMenu(); MenuItem addItem = new MenuItem { Header = Properties.Resources.textAdd, Icon = new System.Windows.Controls.Image { Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/Resources/add.png")) } }; addItem.Click += AddItem_Click; this.dataGridWASExemptions.ContextMenu.Items.Add(addItem); MenuItem delItem = new MenuItem { Header = Properties.Resources.textDelete, Icon = new System.Windows.Controls.Image { Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/Resources/delete.png")) } }; delItem.Click += DelItem_Click; this.dataGridWASExemptions.ContextMenu.Items.Add(delItem); } private void buttonSave_Click(object sender, RoutedEventArgs e) { _ = SaveExemptionsAsync(); } private void buttonImport_Click(object sender, RoutedEventArgs e) { var imported = ExcelLocalImportHelper.ImportWASExemptions(); int skipped = 0; foreach (var exemption in imported) { if (IsDuplicateIMOAndPort(exemption, exemption.IMO, exemption.Port)) { skipped++; continue; } WASExemption.Exemptions.Add(exemption); } if (skipped > 0) { MessageBox.Show($"{skipped} duplicate rows were skipped (same IMO and Port).", Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Warning); } } private void buttonAdd_Click(object sender, RoutedEventArgs e) { AddNewExemption(); } private async void buttonDeleteExpired_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show("Delete all expired exemptions?", Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) != MessageBoxResult.Yes) return; DateTime today = DateTime.Today; var toRemove = new List(); foreach (var exemption in WASExemption.Exemptions) { if (exemption.ValidUntil.Date < today) { int result = await DBManagerAsync.DeleteAsync(exemption); if (result == 1 || exemption.IsNew) { toRemove.Add(exemption); } } } foreach (var exemption in toRemove) { WASExemption.Exemptions.Remove(exemption); } } private void dataGridWASExemptions_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { if (e.Row?.Item is WASExemption exemption) { if (e.Column == columnIMO || e.Column == columnPort) { string newValue = (e.EditingElement as TextBox)?.Text?.Trim(); string imo = e.Column == columnIMO ? newValue : exemption.IMO?.Trim(); string port = e.Column == columnPort ? newValue : exemption.Port?.Trim(); if (!imo.IsNullOrEmpty() && !port.IsNullOrEmpty()) { if (IsDuplicateIMOAndPort(exemption, imo, port)) { MessageBox.Show("Duplicate entry detected. IMO can only appear once per Port.", Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Warning); if (e.EditingElement is TextBox tb) { tb.Text = _editOriginalValue as string ?? ""; } e.Cancel = true; return; } } } exemption.IsDirty = true; } } private void dataGridWASExemptions_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { _editColumn = e.Column; if (e.Row?.Item is WASExemption exemption) { if (e.Column == columnIMO) _editOriginalValue = exemption.IMO; else if (e.Column == columnPort) _editOriginalValue = exemption.Port; else _editOriginalValue = null; } } private void dataGridWASExemptions_MouseDoubleClick(object sender, MouseButtonEventArgs e) { } private void AddItem_Click(object sender, RoutedEventArgs e) { AddNewExemption(); } private async void DelItem_Click(object sender, RoutedEventArgs e) { if (this.dataGridWASExemptions.SelectedItems.Count > 0) { if (MessageBox.Show("Are you sure to delete the selected values?", Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { var selectedItems = new List(); foreach (WASExemption was in this.dataGridWASExemptions.SelectedItems) selectedItems.Add(was); foreach (WASExemption was in selectedItems) { int result = await DBManagerAsync.DeleteAsync(was); if (result == 1 || was.IsNew) { WASExemption.Exemptions.Remove(was); } } } } } private void AddNewExemption() { var exemption = new WASExemption { ValidUntil = DateTime.Today, IsDirty = true }; WASExemption.Exemptions.Add(exemption); this.dataGridWASExemptions.SelectedItem = exemption; this.dataGridWASExemptions.ScrollIntoView(exemption); } private async Task SaveExemptionsAsync() { int totalSaves = 0; var invalids = new List(); foreach (var exemption in WASExemption.Exemptions) { if (exemption.IsNew || exemption.IsDirty) { if (!IsValid(exemption)) { invalids.Add(exemption); continue; } totalSaves += await DBManagerAsync.SaveAsync(exemption); } } if (invalids.Count > 0) { MessageBox.Show( "Some rows are missing required fields (IMO, Port, ValidUntil) and were not saved.", Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Warning); } if (totalSaves > 0) { MessageBox.Show($"{totalSaves} WAS exemptions saved", "Success", MessageBoxButton.OK, MessageBoxImage.Information); } } private static bool IsValid(WASExemption exemption) { if (exemption == null) return false; if (exemption.IMO.IsNullOrEmpty()) return false; if (exemption.Port.IsNullOrEmpty()) return false; if (exemption.ValidUntil == default(DateTime)) return false; return true; } private bool IsDuplicateIMOAndPort(WASExemption current, string imo, string port) { if (imo.IsNullOrEmpty() || port.IsNullOrEmpty()) return false; string imoKey = imo.Trim(); string portKey = port.Trim(); return WASExemption.Exemptions.Any(x => !ReferenceEquals(x, current) && !x.IMO.IsNullOrEmpty() && !x.Port.IsNullOrEmpty() && string.Equals(x.IMO.Trim(), imoKey, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Port.Trim(), portKey, StringComparison.OrdinalIgnoreCase)); } } }