diff --git a/ENI2/App.xaml.cs b/ENI2/App.xaml.cs
index f8cc4b82..c64a3b6e 100644
--- a/ENI2/App.xaml.cs
+++ b/ENI2/App.xaml.cs
@@ -60,7 +60,10 @@ namespace ENI2
ResetSplashCreated.WaitOne();
- base.OnStartup(e);
+ base.OnStartup(e);
+
+ // set connectnion string to async loader
+ DBManagerAsync.ConnectionString = ENI2.Properties.Settings.Default.ConnectionString;
// initialize static / localized lookups from sqlite database
diff --git a/ENI2/Controls/BusyControl.xaml b/ENI2/Controls/BusyControl.xaml
new file mode 100644
index 00000000..83b0c937
--- /dev/null
+++ b/ENI2/Controls/BusyControl.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/ENI2/Controls/BusyControl.xaml.cs b/ENI2/Controls/BusyControl.xaml.cs
new file mode 100644
index 00000000..e840a1fc
--- /dev/null
+++ b/ENI2/Controls/BusyControl.xaml.cs
@@ -0,0 +1,44 @@
+// Copyright (c) 2023- schick Informatik
+//
+// Description: Idea to have a simple control that shows if the application is busy or not using a simple icon
+// that will be set according to a state
+//
+
+using ENI2.Util;
+using System.Windows.Controls;
+
+namespace ENI2.Controls
+{
+ ///
+ /// Interaction logic for BusyControl.xaml
+ ///
+ public partial class BusyControl : UserControl
+ {
+ UIHelper.BusyStateEnum _busyState = UIHelper.BusyStateEnum.NEUTRAL;
+
+ public BusyControl()
+ {
+ InitializeComponent();
+ }
+
+ public UIHelper.BusyStateEnum BusyState
+ {
+ set
+ {
+ _busyState = value;
+ //Dispatcher.Invoke(() =>
+ //{
+ switch (_busyState)
+ {
+ case UIHelper.BusyStateEnum.NEUTRAL: imageBall.Source = Properties.Resources.bullet_ball_grey.CreateBitmapSource(); break;
+ case UIHelper.BusyStateEnum.BUSY: imageBall.Source = Properties.Resources.bullet_ball_yellow.CreateBitmapSource(); break;
+ case UIHelper.BusyStateEnum.FAIL: imageBall.Source = Properties.Resources.bullet_ball_red.CreateBitmapSource(); break;
+ case UIHelper.BusyStateEnum.SUCCESS: imageBall.Source = Properties.Resources.bullet_ball_green.CreateBitmapSource(); break;
+ }
+ //});
+ }
+
+ get => _busyState;
+ }
+ }
+}
diff --git a/ENI2/Controls/MaerskListControl.xaml b/ENI2/Controls/MaerskListControl.xaml
new file mode 100644
index 00000000..c45a235f
--- /dev/null
+++ b/ENI2/Controls/MaerskListControl.xaml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ENI2/Controls/MaerskListControl.xaml.cs b/ENI2/Controls/MaerskListControl.xaml.cs
new file mode 100644
index 00000000..b7410ee6
--- /dev/null
+++ b/ENI2/Controls/MaerskListControl.xaml.cs
@@ -0,0 +1,613 @@
+// Copyright (c) 2017 / 2023 schick Informatik
+// Description: Request dbh ids for Maersk data lists
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+using Microsoft.Win32;
+
+using bsmd.database;
+using ExcelDataReader;
+using System.Collections.ObjectModel;
+using ENI2.Excel;
+using ENI2.Locode;
+using ENI2.Util;
+using System.Diagnostics;
+using System.Linq;
+
+namespace ENI2.Controls
+{
+ ///
+ /// Interaction logic for MaerskListControl.xaml
+ ///
+ public partial class MaerskListControl : UserControl
+ {
+
+ #region Fields
+
+ private readonly ObservableCollection maerskDataList = new ObservableCollection();
+ private const uint MAX_EMPTY_ROWS_ON_IMPORT = 3; // import breaks if more than this count of empty rows have been read
+ private readonly DatabaseEntityWatchdog _dbWatchDog;
+
+ #endregion
+
+ #region Construction
+
+ public MaerskListControl()
+ {
+ InitializeComponent();
+ Loaded += POList_Loaded;
+ this.dateTimePickerFrom.SelectedDate = DateTime.Today.AddDays(-14);
+ this.dateTimePickerTo.SelectedDate = DateTime.Today.AddDays(14);
+ this._dbWatchDog = new DatabaseEntityWatchdog();
+ this._dbWatchDog.DatabaseEntityChanged += _dbWatchDog_DatabaseEntityChanged;
+ this._dbWatchDog.VisitTransitIdUpdated += _dbWatchDog_VisitTransitIdUpdated;
+ }
+
+ #endregion
+
+ #region Events
+
+ public delegate void DateChanged(DateTime date);
+
+ public event DateChanged FromDateChanged;
+
+ public event DateChanged ToDateChanged;
+
+ #endregion
+
+ #region DB Watchdog
+
+ private async void _dbWatchDog_VisitTransitIdUpdated(DatabaseEntity entity)
+ {
+ if (entity is MessageCore core)
+ {
+ foreach (MaerskData md in this.maerskDataList)
+ {
+ if ((md.MessageCore != null) && (md.MessageCore.Id == core.Id))
+ {
+ md.MessageCore = core;
+ md.Status = MaerskData.MDStatus.ID;
+ md.ColM = core.VisitId;
+ await DBManagerAsync.Save(md);
+ _dbWatchDog.UnRegister(core);
+ this.Dispatcher.Invoke(() =>
+ {
+ this.dataGridPOCores.Items.Refresh();
+ if(_dbWatchDog.Idle)
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
+ });
+ }
+ }
+ }
+ }
+
+ private void _dbWatchDog_DatabaseEntityChanged(DatabaseEntity entity)
+ {
+ if (entity is MessageCore core)
+ System.Diagnostics.Trace.WriteLine($"Core state changed to {core.BSMDStatusInternal}");
+ }
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Locode of the port that is concerned by this import list. Is to be set in the surrounding container:
+ ///
+ public string PortLocode { get; set; }
+
+ ///
+ /// synchronize selection props
+ ///
+ public DateTime? FromDate {
+ get { return this.dateTimePickerFrom.SelectedDate; }
+ set { this.dateTimePickerFrom.SelectedDate = value; }
+ }
+
+ ///
+ /// synchronize selection props
+ ///
+ public DateTime? ToDate
+ {
+ get { return this.dateTimePickerTo.SelectedDate; }
+ set { this.dateTimePickerTo.SelectedDate = value; }
+ }
+
+ #endregion
+
+ #region events
+
+ public event MessageCore.MessageCoreSelectedHandler MessageCoreSelected;
+
+ #endregion
+
+ #region control event handler
+
+ private void POList_Loaded(object sender, RoutedEventArgs e)
+ {
+ dataGridPOCores.ItemsSource = maerskDataList;
+ }
+
+ private async void dataGridPOCores_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
+ {
+
+ if (e.EditAction == DataGridEditAction.Commit)
+ {
+ if (e.Column == gridColumnRemark)
+ {
+ MaerskData maerskData = this.maerskDataList[e.Row.GetIndex()];
+
+ var el = e.EditingElement as System.Windows.Controls.TextBox;
+ if (el.Text.Length > 100)
+ {
+ el.Text = el.Text.Trim().Substring(0, 100);
+ }
+ maerskData.Remark = el.Text;
+
+ if (maerskData.MessageCore != null)
+ await DBManagerAsync.Save(maerskData);
+ }
+ /*
+ if(e.Column == gridColumnGroup)
+ {
+ var el = e.EditingElement as ComboBox;
+ DictionaryEntry selectedItem = (DictionaryEntry) el.SelectedItem;
+ MessageCore.CoreFlags coreFlag = (MessageCore.CoreFlags) Enum.Parse(typeof(MessageCore.CoreFlags), selectedItem.Value.ToString());
+ MessageCore editedCore = this.filteredResult[e.Row.GetIndex()];
+ // clear all first
+ editedCore.SetFlag(false, MessageCore.CoreFlags.MAERSK_BHV);
+ editedCore.SetFlag(false, MessageCore.CoreFlags.SEAGO_BHV);
+ editedCore.SetFlag(false, MessageCore.CoreFlags.SEAGO_WHV);
+ editedCore.SetFlag(false, MessageCore.CoreFlags.HOEGH);
+ if (coreFlag != MessageCore.CoreFlags.NONE)
+ {
+ editedCore.SetFlag(true, coreFlag);
+ }
+ // buttonSaveChanges.IsEnabled = true;
+ editedCore.IsDirty = true;
+ }
+ if(e.Column == gridColumnATA)
+ {
+ var el = e.EditingElement as System.Windows.Controls.TextBox;
+ if(DateTime.TryParse(el.Text, out DateTime localATA))
+ {
+ MessageCore editedCore = this.filteredResult[e.Row.GetIndex()];
+ editedCore.ATA = DateTime.SpecifyKind(localATA, DateTimeKind.Local).ToUniversalTime();
+ // buttonSaveChanges.IsEnabled = true;
+ editedCore.IsDirty = true;
+ }
+ else
+ {
+ el.Text = string.Empty;
+ e.Cancel = true;
+ }
+ }
+ */
+ }
+
+ }
+
+ #endregion
+
+ #region private methods
+
+ ///
+ /// "Status" of a Maersk Data element is a momentary evaluation that is relevant for display purposes only
+ /// It is not saved
+ ///
+ private void UpdateStatus(MaerskData md)
+ {
+ // here we set the following: NO_ID, NO_ID_AND_DUE, ID, NO_ETA and DONE
+ // the other status are set during active processing
+ if(md.ETA.HasValue)
+ {
+ if((md.ETA.Value - DateTime.Now).TotalSeconds > 0) // future
+ {
+ if(!md.ColM.IsNullOrEmpty() || ((md.MessageCore != null) && (!md.MessageCore.VisitId.IsNullOrEmpty())))
+ {
+ md.Status = MaerskData.MDStatus.ID;
+ }
+ else
+ {
+ if(md.ETA.Value.IsNextXDays(4))
+ {
+ md.Status = MaerskData.MDStatus.NO_ID_AND_DUE;
+ }
+ else
+ {
+ md.Status = MaerskData.MDStatus.NO_ID;
+ }
+ }
+
+ }
+ else // past
+ {
+ md.Status = MaerskData.MDStatus.DONE;
+ }
+ }
+ else
+ {
+ // no ETA means done
+ md.Status = MaerskData.MDStatus.NO_ETA;
+ }
+ }
+
+
+ private async void PerformSearch()
+ {
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
+ Dictionary filterDict = new Dictionary();
+
+ // Die Suche findet in dem eingestellten Intervall statt
+ uint from = this.dateTimePickerFrom.SelectedDate.Value.ToUniversalTime().ToUnixTimeStamp();
+ DateTime toDate = this.dateTimePickerTo.SelectedDate.Value.ToUniversalTime().Add(new TimeSpan(23, 59, 59));
+ uint to = toDate.ToUnixTimeStamp();
+ filterDict.Add(MessageCore.SearchFilterType.FILTER_ETA, string.Format("{0}:{1}", from.ToString() ?? "", to.ToString() ?? ""));
+ // eingeschränkt auf flags
+ filterDict.Add(MessageCore.SearchFilterType.FILTER_FLAG_EQ, "0");
+
+ // suche auslösen
+ List searchResult = DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).GetMessageCoresWithFilters(filterDict);
+
+ // alle anderen Häfen weg
+ searchResult.RemoveAll(item => (item.PoC == null) || (!item.PoC.Equals(PortLocode)));
+
+ // alles entfernen was keine Maersk Xtra-Data hat (=noch nicht schon einmal importiert wurde)
+ foreach(MessageCore core in searchResult)
+ {
+ MaerskData md = await DBManagerAsync.LoadMaerskDataForCoreAsync(core.Id.Value);
+ if(md != null)
+ {
+ md.MessageCore = core;
+ md.MessageCoreId = core.Id.Value;
+ this.UpdateStatus(md);
+ if(!maerskDataList.Contains(md)) // DatabaseEntity implements IEquatable
+ this.maerskDataList.Add(md);
+ }
+ }
+ this.TimeFilterItemSource();
+ // this.SortItemSource();
+ this.dataGridPOCores.SelectedItem = null;
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
+ }
+
+ private string ReadFieldAsString(IExcelDataReader reader, int fieldNum)
+ {
+ if (fieldNum >= reader.FieldCount) return null;
+ if (reader.GetFieldType(fieldNum) == typeof(string))
+ return reader.GetString(fieldNum).Clean();
+ if (reader.GetFieldType(fieldNum) == typeof(DateTime))
+ return reader.GetDateTime(fieldNum).ToString();
+ if (reader.GetFieldType(fieldNum) == typeof(int))
+ return reader.GetInt32(fieldNum).ToString();
+ if (reader.GetFieldType(fieldNum) == typeof(double))
+ return ((int) reader.GetDouble(fieldNum)).ToString();
+ Type theType = reader.GetFieldType(fieldNum);
+ return null;
+ }
+
+ private void TimeFilterItemSource()
+ {
+ List removeList = new List();
+ foreach (MaerskData md in this.maerskDataList)
+ {
+ if (md.ETA.HasValue)
+ {
+ if (this.dateTimePickerFrom.SelectedDate.HasValue && (md.ETA.Value < this.dateTimePickerFrom.SelectedDate.Value))
+ removeList.Add(md);
+
+ if (this.dateTimePickerTo.SelectedDate.HasValue) {
+
+ DateTime toDate = this.dateTimePickerTo.SelectedDate.Value.ToUniversalTime().Add(new TimeSpan(23, 59, 59));
+ if(md.ETA.Value > toDate)
+ removeList.Add(md);
+ }
+ }
+ }
+
+ foreach (MaerskData md in removeList)
+ this.maerskDataList.Remove(md);
+ }
+
+ private void SortItemSource()
+ {
+ ObservableCollection temp;
+ temp = new ObservableCollection(this.maerskDataList.OrderBy(p => p.ColA));
+ this.maerskDataList.Clear();
+ foreach (MaerskData md in temp)
+ this.maerskDataList.Add(md);
+ }
+
+ #endregion
+
+ #region button event handler
+
+ private void buttonLoad_Click(object sender, RoutedEventArgs e)
+ {
+ Util.UIHelper.SetBusyState();
+ this.PerformSearch();
+ }
+
+ private async void buttonImport_Click(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog ofd = new OpenFileDialog
+ {
+ Filter = "Excel Files|*.xls;*.xlsx"
+ };
+ if (ofd.ShowDialog() ?? false)
+ {
+ FileStream stream;
+ try
+ {
+ stream = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ using (IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream))
+ {
+ List importData = new List();
+ uint emptyRowCnt = 0;
+ bool isFirstRow = true;
+
+ try
+ {
+ while (reader.Read())
+ {
+
+ if (isFirstRow)
+ {
+ isFirstRow = false; // this must be a header row, skip
+ continue;
+ }
+
+ if (reader.FieldCount < 13)
+ {
+ throw new InvalidDataException("Sheet must have 13 columns of data");
+ }
+
+ MaerskData md = new MaerskData();
+ if (!reader.IsDBNull(0))
+ {
+ if (reader.GetFieldType(0) == typeof(DateTime))
+ {
+ md.ETA = reader.GetDateTime(0);
+ md.ColA = md.ETA.ToString();
+ }
+ else
+ {
+ md.ColA = reader.GetString(0);
+ if (DateTime.TryParse(md.ColA, out DateTime aDateTime))
+ md.ETA = aDateTime;
+ }
+ }
+ if (!reader.IsDBNull(1)) md.ColB = ReadFieldAsString(reader, 1);
+ if (!reader.IsDBNull(2)) md.ColC = ReadFieldAsString(reader, 2);
+ if (!reader.IsDBNull(3)) md.ColD = ReadFieldAsString(reader, 3);
+ if (!reader.IsDBNull(4)) md.ColE = ReadFieldAsString(reader, 4);
+ if (!reader.IsDBNull(5)) md.ColF = ReadFieldAsString(reader, 5);
+ if (!reader.IsDBNull(6)) md.ColG = ReadFieldAsString(reader, 6);
+ if (!reader.IsDBNull(7)) md.ColH = ReadFieldAsString(reader, 7);
+ if (!reader.IsDBNull(8)) md.ColI = ReadFieldAsString(reader, 8);
+ if (md.ColI != null)
+ {
+ if ((md.ColI.Contains("bremerhaven", StringComparison.OrdinalIgnoreCase) && this.PortLocode.Equals("DEWVN")) ||
+ (md.ColI.Contains("eurogate", StringComparison.OrdinalIgnoreCase) && this.PortLocode.Equals("DEBRV")))
+ throw new InvalidOperationException($"{md.ColI} found in import to {PortLocode}, this is probably an error. Aborting import");
+ }
+ if (!reader.IsDBNull(9)) md.ColJ = ReadFieldAsString(reader, 9);
+ if (md.ColJ == null) continue;
+ if (!(md.ColJ.Equals("msk", StringComparison.OrdinalIgnoreCase) || md.ColJ.Equals("sgl", StringComparison.OrdinalIgnoreCase))) continue; // skip operator we are not interested in
+ if (!reader.IsDBNull(10)) md.ColK = ReadFieldAsString(reader, 10);
+ if (!reader.IsDBNull(11)) md.ColL = ReadFieldAsString(reader, 11);
+ if (!reader.IsDBNull(12)) md.ColM = ReadFieldAsString(reader, 12);
+ if (!reader.IsDBNull(13)) md.Remark = ReadFieldAsString(reader, 13);
+
+ if (!md.ColF.IsNullOrEmpty()) // only add this if IMO is set
+ importData.Add(md);
+ else
+ emptyRowCnt++;
+ if (emptyRowCnt > MAX_EMPTY_ROWS_ON_IMPORT) break;
+ if (isFirstRow) isFirstRow = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error reading Excel: " + ex.Message, Properties.Resources.textCaptionError, MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+
+ if (importData.Count > 0)
+ {
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
+
+ foreach (MaerskData md in importData)
+ {
+ if (this.maerskDataList.Contains(md))
+ {
+ // update record with imported record
+ MaerskData foundData = this.maerskDataList.First((m) => (m.ColF != null) ? m.ColF.Equals(md.ColF) : (md.ColF == null) &&
+ (m.ColG != null) ? m.ColG.Equals(md.ColG) : (md.ColG == null) &&
+ (m.ColH != null) ? m.ColH.Equals(md.ColH) : (md.ColH == null));
+
+ if(foundData.ETA.HasValue && ((foundData.ETA.Value - DateTime.Now).TotalSeconds > 0) && foundData.Update(md))
+ foundData.Status = MaerskData.MDStatus.UPDATED;
+ }
+ else
+ {
+ if (!md.ColM.IsNullOrEmpty())
+ {
+ md.MessageCore = await DBManagerAsync.LoadCoreByVisitIdAsync(md.ColM);
+ }
+ this.UpdateStatus(md);
+ maerskDataList.Add(md);
+ }
+ }
+ this.TimeFilterItemSource();
+ // this.SortItemSource();
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
+ }
+
+ this.dataGridPOCores.Items.Refresh();
+ }
+
+ stream.Close();
+ }
+ }
+
+ private void buttonExport_Click(object sender, RoutedEventArgs e)
+ {
+ // Export of the current collection
+ string predefFilename = string.Format("{0}_{1}.xlsx", this.PortLocode, DateTime.Today.ToString("yyyyMMdd"));
+ SaveFileDialog sfd = new SaveFileDialog()
+ {
+ Filter = "Excel Files|*.xlsx;*.xls",
+ FileName = predefFilename
+ };
+ if(sfd.ShowDialog() ?? false)
+ {
+ Util.UIHelper.SetBusyState();
+ ExcelManager em = new ExcelManager();
+ try
+ {
+ List exportList = new List(this.maerskDataList);
+ em.ExportMaersk(exportList, sfd.FileName);
+ Process.Start(sfd.FileName);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Export failed", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ }
+
+ /*
+
+ private async void buttonSave_Click(object sender, RoutedEventArgs e)
+ {
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
+
+ // save the current list to DB (only if the entries have matching cores!)
+ foreach(MaerskData md in this.maerskDataList)
+ {
+ if(md.MessageCore != null)
+ {
+ await DBManagerAsync.Save(md);
+ }
+ }
+
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
+ }
+
+ */
+
+ private async void buttonRequestIds_Click(object sender, RoutedEventArgs e)
+ {
+ // find all entries from now until 4 days into the future and track parallel requests
+ List requestList = new List();
+ if (sender == this.buttonRequestIds)
+ {
+ foreach (MaerskData md in this.dataGridPOCores.SelectedItems)
+ {
+ if (md.MessageCore?.VisitId.IsNullOrEmpty() == false) continue; // already requested
+ if (md.ColM?.IsNullOrEmpty() == false) continue; // already something there
+ requestList.Add(md);
+ }
+ }
+ if(sender == this.buttonRequestPlus3)
+ {
+ foreach(MaerskData md in this.maerskDataList)
+ {
+ if(((md.MessageCore == null) && md.ColM.IsNullOrEmpty()) ||
+ ((md.MessageCore != null) && md.MessageCore.VisitId.IsNullOrEmpty()))
+ {
+ if (md.ETA.HasValue && md.ETA.Value.IsNextXDays(4))
+ requestList.Add(md);
+ }
+ }
+ }
+
+ if(requestList.Count == 0)
+ {
+ MessageBox.Show("No valid rows selected", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
+ }
+ else
+ {
+ busyControl.BusyState = Util.UIHelper.BusyStateEnum.BUSY;
+
+ foreach (MaerskData md in requestList)
+ {
+ md.Status = MaerskData.MDStatus.REQUESTING_ID;
+
+ // create MessageCore and message classes
+ md.MessageCore = new MessageCore();
+ md.MessageCore.InitialHIS = Message.NSWProvider.DBH_MAERSK;
+ md.MessageCore.IMO = md.ColF;
+ md.MessageCore.ETA = md.ETA;
+ md.MessageCore.IsTransit = false;
+ md.MessageCore.PoC = this.PortLocode;
+ md.MessageCore.Portname = LocodeDB.PortNameFromLocode(md.MessageCore.PoC);
+ md.MessageCore.BSMDStatusInternal = MessageCore.BSMDStatus.TOSEND;
+ md.MessageCore.Incoming = true;
+ md.MessageCore.DefaultReportingPartyId = App.UserId.Value;
+ await DBManagerAsync.Save(md.MessageCore);
+ md.MessageCoreId = md.MessageCore.Id.Value;
+ await DBManagerAsync.Save(md);
+
+ // Meldeklassen für neuen Anlauf erzeugen
+ // TODO: pre-set certain fields taken from Maersk data
+ await bsmd.database.Util.CreateMessagesForCoreAsync(md.MessageCore, null);
+
+ // watchdog registrieren
+ this._dbWatchDog.Register(md.MessageCore);
+ }
+ }
+ this.dataGridPOCores.Items.Refresh();
+ }
+
+ #endregion
+
+ #region grid event handler
+
+ private void dataGridPOCores_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (sender != null)
+ {
+ DataGrid grid = sender as DataGrid;
+ if (grid?.SelectedItems?.Count == 1)
+ {
+ MaerskData md = grid.SelectedItem as MaerskData;
+ if(md.MessageCore != null) {
+ Util.UIHelper.SetBusyState();
+ this.MessageCoreSelected?.Invoke(md.MessageCore);
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ #region DateTime picker event handler
+
+ private void dateTimePickerFrom_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+ {
+
+ if (sender == dateTimePickerFrom)
+ this.FromDateChanged?.Invoke(dateTimePickerFrom.SelectedDate.Value);
+
+ if (sender == dateTimePickerTo)
+ this.ToDateChanged?.Invoke(dateTimePickerTo.SelectedDate.Value);
+
+ }
+
+ #endregion
+
+ }
+}
diff --git a/ENI2/Controls/MaerskOverviewControl.xaml b/ENI2/Controls/MaerskOverviewControl.xaml
new file mode 100644
index 00000000..f6d27262
--- /dev/null
+++ b/ENI2/Controls/MaerskOverviewControl.xaml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ENI2/Controls/MaerskOverviewControl.xaml.cs b/ENI2/Controls/MaerskOverviewControl.xaml.cs
new file mode 100644
index 00000000..45ee4d9e
--- /dev/null
+++ b/ENI2/Controls/MaerskOverviewControl.xaml.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using System.Windows.Controls;
+
+namespace ENI2.Controls
+{
+ ///
+ /// Interaction logic for MaerskOverviewControl.xaml
+ ///
+ public partial class MaerskOverviewControl : UserControl
+ {
+ public MaerskOverviewControl()
+ {
+ InitializeComponent();
+ this.brvListControl.PortLocode = "DEBRV";
+ this.wvnListControl.PortLocode = "DEWVN";
+
+ this.brvListControl.FromDateChanged += BrvListControl_FromDateChanged;
+ this.brvListControl.ToDateChanged += BrvListControl_ToDateChanged;
+ this.wvnListControl.FromDateChanged += WvnListControl_FromDateChanged;
+ this.wvnListControl.ToDateChanged += WvnListControl_ToDateChanged;
+ }
+
+ private void WvnListControl_ToDateChanged(System.DateTime date)
+ {
+ this.brvListControl.ToDate = date;
+ }
+
+ private void WvnListControl_FromDateChanged(System.DateTime date)
+ {
+ this.brvListControl.FromDate = date;
+ }
+
+ private void BrvListControl_ToDateChanged(System.DateTime date)
+ {
+ this.wvnListControl.ToDate = date;
+ }
+
+ private void BrvListControl_FromDateChanged(System.DateTime date)
+ {
+ this.wvnListControl.FromDate = date;
+ }
+
+ public List ListControls
+ {
+ get
+ {
+ return new List() { this.brvListControl, this.wvnListControl };
+ }
+ }
+ }
+}
diff --git a/ENI2/Controls/POListControl.xaml b/ENI2/Controls/POListControl.xaml
deleted file mode 100644
index cafbeb49..00000000
--- a/ENI2/Controls/POListControl.xaml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ENI2/Controls/POListControl.xaml.cs b/ENI2/Controls/POListControl.xaml.cs
deleted file mode 100644
index 0985b92f..00000000
--- a/ENI2/Controls/POListControl.xaml.cs
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2017 schick Informatik
-// Description: PO Nummer Übersicht. Ergänzung Nummern. Excel Export
-//
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Windows;
-using System.Windows.Controls;
-using Microsoft.Win32;
-
-using Microsoft.Office.Interop.Excel;
-using System.Runtime.InteropServices;
-
-using bsmd.database;
-
-namespace ENI2.Controls
-{
- ///
- /// Interaction logic for POListControl.xaml
- ///
- public partial class POListControl : UserControl
- {
-
- #region Fields
-
- private readonly string[] _comboBoxEntries =
- {
- "All",
- "Maersk BRV/WHV",
- "SeaGo BHV",
- "SeaGo WHV"
- };
-
- private List searchResult = new List();
- private readonly List filteredResult = new List();
-
- #endregion
-
- #region Construction
-
- public POListControl()
- {
- InitializeComponent();
- Loaded += POList_Loaded;
- }
-
- #endregion
-
- #region control event handler
-
- private void POList_Loaded(object sender, RoutedEventArgs e)
- {
- this.comboBoxFilterType.ItemsSource = this._comboBoxEntries;
- this.doubleUpDownCalendarWeek.Value = bsmd.database.Util.GetIso8601WeekOfYear(DateTime.Now);
- this.dataGridPOCores.ItemsSource = this.filteredResult;
- }
-
- private void buttonExcelExport_Click(object sender, RoutedEventArgs e)
- {
- if (this.filteredResult.Count == 0) return;
-
- OpenFileDialog ofd = new OpenFileDialog
- {
- Filter = "Excel Files|*.xls;*.xlsx"
- };
- if (ofd.ShowDialog() ?? false)
- {
- try
- {
- Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
- excelApp.DisplayAlerts = false;
- Workbook workBook = excelApp.Workbooks.Open(ofd.FileName);
- Worksheet workSheet = workBook.Worksheets[1];
-
- int rowIndex = 3;
- foreach(MessageCore core in this.filteredResult)
- {
- workSheet.Cells[rowIndex, 7].Value = core.Shipname;
- workSheet.Cells[rowIndex, 10].Value = core.PoC.Substring(2);
- if(core.POATA.HasValue)
- workSheet.Cells[rowIndex, 11].Value = core.POATA.Value.ToShortDateString();
- workSheet.Cells[rowIndex, 13].Value = core.PONumber;
- rowIndex++;
- }
-
- workBook.Save();
- workBook.Close();
- Marshal.ReleaseComObject(workBook);
- excelApp.Quit();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
- return;
- }
- }
- }
-
- private void buttonSaveChanges_Click(object sender, RoutedEventArgs e)
- {
- foreach(MessageCore messageCore in this.filteredResult)
- {
- if (messageCore.IsDirty)
- {
- DBManager.Instance.Save(messageCore);
- messageCore.IsDirty = false;
- // load ATA for this Core
- /* DAS ATA WIRD JETZT NICHT MEHR IN DIE MELDEKLASSE GESPEICHERT
- Message ataMessage = DBManager.Instance.GetMessage(messageCore, Message.NotificationClass.ATA);
- if(ataMessage?.Elements.Count == 1)
- {
- if(messageCore.ATA != ((ATA)ataMessage.Elements[0]).ATAPortOfCall)
- {
- ((ATA)ataMessage.Elements[0]).ATAPortOfCall = messageCore.ATA;
- DBManager.Instance.Save(ataMessage.Elements[0]);
- }
- }
- */
- }
- }
- this.buttonSaveChanges.IsEnabled = false;
- }
-
- private void doubleUpDownCalendarWeek_ValueChanged(object sender, RoutedPropertyChangedEventArgs