// Copyright (c) 2025 - schick Informatik // Description: Display control of formsheet Tab 9. Pas data departure // using bsmd.database; using ClosedXML.Excel; using ENI2.EditControls; using ENI2.Locode; using ENI2.Util; using Microsoft.Win32; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; namespace ENI2.SheetDisplayControls { /// /// Interaction logic for PassengerDepartureControl.xaml /// public partial class PassengerDepartureControl : DetailBaseControl { #region Fields private Message _pasMessage; private Message _pasdMessage; #endregion #region Construction public PassengerDepartureControl() { InitializeComponent(); } #endregion #region public override public override void Initialize() { base.Initialize(); foreach (Message aMessage in this.Messages) { if (aMessage.MessageNotificationClass == Message.NotificationClass.PASA) { this._pasMessage = aMessage; this.ControlMessages.Add(aMessage); } if (aMessage.MessageNotificationClass == Message.NotificationClass.PASD) { this._pasdMessage = aMessage; this.ControlMessages.Add(aMessage); } } #region init PASD if (this._pasdMessage == null) { this._pasdMessage = this.Core.CreateMessage(Message.NotificationClass.PASD); this.Messages.Add(this._pasdMessage); } this.dataGridPassengerListDeparture.Initialize(); this.dataGridPassengerListDeparture.ItemsSource = this._pasdMessage.Elements; this.dataGridPassengerListDeparture.AddingNewItem += DataGridPassengerListDeparture_AddingNewItem; this.dataGridPassengerListDeparture.EditRequested += DataGridPassengerListDeparture_EditRequested; this.dataGridPassengerListDeparture.DeleteRequested += DataGridPassengerListDeparture_DeleteRequested; this.dataGridPassengerListDeparture.CreateRequested += DataGridPassengerListDeparture_CreateRequested; this.dataGridPassengerListDeparture.RefreshGrid += DataGridPassengerListDeparture_RefreshGrid; this.dataGridPassengerListDeparture.MultiEditRequested += DataGridPassengerListDeparture_MultiEditRequested; if (this._pasdMessage.Elements.Count > 0) { this.checkBoxPasNotificationSchengenDeparture.IsChecked = ((PASD)this._pasdMessage.Elements[0]).NotificationSchengen; this.checkBoxPasNotificationPAXDeparture.IsChecked = ((PASD)this._pasdMessage.Elements[0]).NotificationPAX; } this.textBlockNumPasEntriesDeparture.DataContext = this._pasdMessage; // extra menu copy to PASA { this.dataGridPassengerListDeparture.ContextMenu.Items.Add(new Separator()); MenuItem copyPASDItem = new MenuItem(); copyPASDItem.Header = Properties.Resources.textCopyToPASA; copyPASDItem.Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/Resources/documents.png")) }; copyPASDItem.Click += CopyPASDItem_Click; this.dataGridPassengerListDeparture.ContextMenu.Items.Add(copyPASDItem); } #endregion } public override void SetEnabled(bool enabled) { base.SetEnabled(enabled); this.passengerDepartureGroupBox.IsEnabled = enabled; } #endregion #region event handler private void CopyPASDItem_Click(object sender, RoutedEventArgs e) { if (this.dataGridPassengerListDeparture.SelectedItems != null) { foreach (PASD pasd in this.dataGridPassengerListDeparture.SelectedItems) { PAS pasa = new PAS(); pasa.MessageHeader = this._pasMessage; pasa.CopyFromPAS(pasd); pasa.IsDeparture = false; pasa.Identifier = DatabaseEntity.GetNewIdentifier(this._pasMessage.Elements); this._pasMessage.Elements.Add(pasa); this.SublistElementChanged(Message.NotificationClass.PASA); } } } private void checkBoxPasNotificationSchengenDeparture_Click(object sender, RoutedEventArgs e) { foreach (PASD pasd in _pasdMessage.Elements.Cast()) { pasd.NotificationSchengen = checkBoxPasNotificationSchengenDeparture.IsChecked; } this.SublistElementChanged(Message.NotificationClass.PASD); } private void checkBoxPasNotificationPAXDeparture_Click(object sender, RoutedEventArgs e) { foreach (PASD pasd in _pasdMessage.Elements.Cast()) { pasd.NotificationPAX = checkBoxPasNotificationPAXDeparture.IsChecked; } this.SublistElementChanged(Message.NotificationClass.PASD); } private void buttonImportExcelPassengerDeparture_Click(object sender, RoutedEventArgs e) { OpenFileDialog ofd = new OpenFileDialog { Filter = "Excel Files|*.xls;*.xlsx" }; if (ofd.ShowDialog() ?? false) { try { using (var workbook = new XLWorkbook(ofd.FileName)) { var worksheet = workbook.Worksheet(1); // Get first worksheet var rows = worksheet.RangeUsed().RowsUsed().Skip(1); // Skip header row if present List importPassenger = new List(); foreach (var row in rows) { if (row.RowNumber() > worksheet.RangeUsed().RowCount()) break; if (worksheet.RangeUsed().ColumnCount() < 17) { throw new InvalidDataException("Sheet must have 17 columns of data"); } PASD pas = new PASD(); if (row.Cell(1).IsEmpty() && row.Cell(2).IsEmpty()) continue; if (!row.Cell(1).IsEmpty()) pas.PassengerLastName = row.Cell(1).GetString().Clean(); if (pas.PassengerLastName?.Equals("Family Name") == true || string.IsNullOrWhiteSpace(pas.PassengerLastName)) continue; if (!row.Cell(2).IsEmpty()) pas.PassengerFirstName = row.Cell(2).GetString().Clean(); if (!row.Cell(3).IsEmpty()) pas.PassengerGender = GlobalStructures.ParseGender(row.Cell(3).GetString()); if (!row.Cell(4).IsEmpty()) pas.PassengerPortOfEmbarkation = row.Cell(4).GetString().Clean(); if (LocodeDB.PortNameFromLocode(pas.PassengerPortOfEmbarkation) == null) pas.PassengerPortOfEmbarkation = null; if (!row.Cell(5).IsEmpty()) pas.PassengerPortOfDisembarkation = row.Cell(5).GetString().Clean(); if (LocodeDB.PortNameFromLocode(pas.PassengerPortOfDisembarkation) == null) pas.PassengerPortOfDisembarkation = null; if (!row.Cell(6).IsEmpty()) pas.PassengerInTransit = GlobalStructures.ReadBoolean(row.Cell(6).GetString()); if (!row.Cell(7).IsEmpty()) pas.PassengerNationality = row.Cell(7).GetString().Substring(0, 2).ToUpper(); if (!row.Cell(8).IsEmpty()) pas.PassengerPlaceOfBirth = row.Cell(8).GetString().Clean(); if (!row.Cell(9).IsEmpty()) pas.PassengerCountryOfBirth = row.Cell(9).GetString().Substring(0, 2).ToUpper(); if (!row.Cell(10).IsEmpty()) pas.PassengerDateOfBirth = row.Cell(10).GetDateTime(); if (!row.Cell(11).IsEmpty()) pas.PassengerIdentityDocumentType = GlobalStructures.ReadIdentityDocumentType(row.Cell(11).GetString()); if (!row.Cell(12).IsEmpty()) pas.PassengerIdentityDocumentId = row.Cell(12).GetString().Clean(); if (!row.Cell(13).IsEmpty()) pas.PassengerIdentityDocumentIssuingState = row.Cell(13).GetString().Substring(0, 2).ToUpper(); if (!row.Cell(14).IsEmpty()) pas.PassengerIdentityDocumentExpiryDate = row.Cell(14).GetDateTime(); if (!row.Cell(15).IsEmpty()) pas.PassengerVisaNumber = row.Cell(15).GetString().Clean(); if (!row.Cell(16).IsEmpty()) pas.EmergencyCare = row.Cell(16).GetString().Clean(); if (!row.Cell(17).IsEmpty()) pas.EmergencyContactNumber = row.Cell(17).GetString().Clean(); pas.MessageHeader = this._pasdMessage; pas.IsDirty = true; pas.Identifier = PASD.GetNewIdentifier(this._pasdMessage.Elements); this._pasdMessage.Elements.Add(pas); importPassenger.Add(pas); } if (importPassenger.Count > 0) { this.dataGridPassengerListDeparture.Items.Refresh(); this.SublistElementChanged(Message.NotificationClass.PASD); MessageBox.Show(String.Format(Properties.Resources.textPassengerImported, importPassenger.Count), Properties.Resources.textCaptionInformation, MessageBoxButton.OK, MessageBoxImage.Information); } } } catch (Exception ex) { MessageBox.Show("Error reading Excel: " + ex.Message, Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Error); } } } private async void buttonDeleteAllPasD_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(Properties.Resources.textConfimDeleteAllEntries, Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { foreach (PASD pasd in this._pasdMessage.Elements.Cast()) { await DBManagerAsync.DeleteAsync(pasd); } this._pasdMessage.Elements.Clear(); this.dataGridPassengerListDeparture.Items.Refresh(); this.SublistElementChanged(Message.NotificationClass.PASD); } } #endregion #region passenger grid departure private void DataGridPassengerListDeparture_CreateRequested() { EditPASDialog epd = new EditPASDialog { PAS = new PASD() }; epd.PAS.IsDeparture = true; epd.PAS.Identifier = PASD.GetNewIdentifier(_pasdMessage.Elements); epd.PAS.MessageHeader = this._pasdMessage; epd.AddClicked += () => { epd.CopyValuesToEntity(); if (!this._pasdMessage.Elements.Contains(epd.PAS)) { this._pasdMessage.Elements.Add(epd.PAS); this.CheckPASD(); } this.dataGridPassengerListDeparture.Items.Refresh(); epd.PAS = new PASD { IsDeparture = true, MessageHeader = this._pasdMessage, Identifier = PASD.GetNewIdentifier(_pasdMessage.Elements) }; this.SublistElementChanged(Message.NotificationClass.PASD); }; if (epd.ShowDialog() ?? false) { if (!this._pasdMessage.Elements.Contains(epd.PAS)) { _pasdMessage.Elements.Add(epd.PAS); this.CheckPASD(); } this.dataGridPassengerListDeparture.Items.Refresh(); this.SublistElementChanged(Message.NotificationClass.PASD); } } private void DataGridPassengerListDeparture_DeleteRequested(DatabaseEntity obj) { if (obj is PASD pasd) { // are you sure dialog is in base class _pasdMessage.Elements.Remove(pasd); DBManager.Instance.Delete(pasd); } } private void DataGridPassengerListDeparture_RefreshGrid() { DatabaseEntity.ResetIdentifiers(_pasdMessage.Elements); this.SublistElementChanged(Message.NotificationClass.PASD); this.dataGridPassengerListDeparture.Items.Refresh(); } private void DataGridPassengerListDeparture_EditRequested(DatabaseEntity obj) { EditPASDialog epd = new EditPASDialog { PAS = obj as PASD }; epd.AddClicked += () => { epd.CopyValuesToEntity(); if (!_pasMessage.Elements.Contains(epd.PAS)) { _pasMessage.Elements.Add(epd.PAS); this.CheckPASD(); } this.dataGridPassengerListDeparture.Items.Refresh(); epd.PAS = new PASD { IsDeparture = true, Identifier = PASD.GetNewIdentifier(_pasdMessage.Elements), MessageHeader = _pasdMessage }; this.SublistElementChanged(Message.NotificationClass.PASD); }; if (epd.ShowDialog() ?? false) { if (!_pasdMessage.Elements.Contains(epd.PAS)) { _pasdMessage.Elements.Add(epd.PAS); this.CheckPASD(); } epd.PAS.IsDirty = true; this.dataGridPassengerListDeparture.Items.Refresh(); this.SublistElementChanged(Message.NotificationClass.PASD); } } private void DataGridPassengerListDeparture_AddingNewItem(object sender, AddingNewItemEventArgs e) { this.DataGridPassengerListDeparture_CreateRequested(); } private void DataGridPassengerListDeparture_MultiEditRequested(List databaseEntities) { List pasList = new List(); foreach (PAS apas in databaseEntities.Cast()) pasList.Add(apas); // write common values of all PAS entities to template entity PAS pas = PAS.CreateCommon(pasList); EditPASDialog dialog = new EditPASDialog(); dialog.PAS = pas; dialog.AddVisible = false; if (dialog.ShowDialog() ?? false) { // write back changed values from pas to all entities and mark them as changed PAS.WriteTemplateToList(pas, pasList); this.SublistElementChanged(Message.NotificationClass.PASD); this.dataGridPassengerListDeparture.Items.Refresh(); } } #endregion #region private methods private void CheckPASD() { if (this._pasdMessage.Elements.Count == 0) return; PASD firstPAS = this._pasdMessage.Elements[0] as PASD; if (this._pasdMessage.Elements.Count == 1) { firstPAS.NotificationSchengen = true; this.checkBoxPasNotificationSchengenDeparture.IsChecked = true; } else { for (int i = 1; i < this._pasdMessage.Elements.Count; i++) { ((PASD)this._pasdMessage.Elements[i]).NotificationSchengen = firstPAS.NotificationSchengen; } } } #endregion } }