Requesting ID now works

This commit is contained in:
Daniel Schick 2023-02-13 17:19:40 +01:00
parent ed1f11c936
commit 2257a78326
8 changed files with 190 additions and 40 deletions

View File

@ -17,6 +17,8 @@ using bsmd.database;
using ExcelDataReader;
using System.Collections.ObjectModel;
using ENI2.Excel;
using ENI2.Locode;
using ENI2.Util;
namespace ENI2.Controls
{
@ -24,12 +26,13 @@ namespace ENI2.Controls
/// Interaction logic for MaerskListControl.xaml
/// </summary>
public partial class MaerskListControl : UserControl
{
{
#region Fields
private readonly ObservableCollection<MaerskData> maerskDataList = new ObservableCollection<MaerskData>();
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
@ -41,8 +44,47 @@ namespace ENI2.Controls
Loaded += POList_Loaded;
this.dateTimePickerFrom.Value = DateTime.Today.AddDays(-14);
this.dateTimePickerTo.Value = DateTime.Today.AddDays(14);
this._dbWatchDog = new DatabaseEntityWatchdog();
this._dbWatchDog.DatabaseEntityChanged += _dbWatchDog_DatabaseEntityChanged;
this._dbWatchDog.VisitTransitIdUpdated += _dbWatchDog_VisitTransitIdUpdated;
}
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);
this.Dispatcher.Invoke(() =>
{
this.dataGridPOCores.Items.Refresh();
});
}
}
}
}
private void _dbWatchDog_DatabaseEntityChanged(DatabaseEntity entity)
{
if (entity is MessageCore core)
System.Diagnostics.Trace.WriteLine($"Core state changed to {core.BSMDStatusInternal}");
}
#endregion
#region Properties
/// <summary>
/// Locode of the port that is concerned by this import list. Is to be set in the surrounding container:
/// </summary>
public string PortLocode { get; set; }
#endregion
#region control event handler
@ -302,18 +344,21 @@ namespace ENI2.Controls
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.MessageCore);
await DBManagerAsync.Save(md);
}
}
busyControl.BusyState = Util.UIHelper.BusyStateEnum.NEUTRAL;
}
private void buttonRequestIds_Click(object sender, RoutedEventArgs e)
private async void buttonRequestIds_Click(object sender, RoutedEventArgs e)
{
// find all entries from now until 3 days into the future and track parallel requests
List<MaerskData> requestList = new List<MaerskData>();
@ -330,13 +375,34 @@ namespace ENI2.Controls
else
{
// Todo:
foreach (MaerskData md in requestList)
{
// 1) create MessageCore and message classes
md.MessageCore = new MessageCore();
md.MessageCore.InitialHIS = Message.NSWProvider.DBH;
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);
// 1) create MessageCore and message classes
// Meldeklassen für neuen Anlauf erzeugen
// TODO: pre-set certain fields taken from Maersk data
await bsmd.database.Util.CreateMessagesForCoreAsync(md.MessageCore, null);
// 2) request dbh Id
// watchdog registrieren
this._dbWatchDog.Register(md.MessageCore);
// 2) request dbh Id
// 3) register watchdog for request completion
// 3) register watchdog for request completion
}
}
this.dataGridPOCores.Items.Refresh();
}

View File

@ -1,17 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls;
namespace ENI2.Controls
{
@ -23,6 +10,8 @@ namespace ENI2.Controls
public MaerskOverviewControl()
{
InitializeComponent();
this.brvListControl.PortLocode = "DEBRV";
this.wvnListControl.PortLocode = "DEWVN";
}
}
}

View File

@ -787,7 +787,6 @@ namespace ENI2.DetailViewControls
if (sfd.ShowDialog() ?? false)
{
Util.UIHelper.SetBusyState();
ExcelManager em = new ExcelManager();
try
@ -800,7 +799,7 @@ namespace ENI2.DetailViewControls
{
MessageBox.Show(ex.Message, "Export failed", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
#endregion

View File

@ -47,7 +47,7 @@ namespace ENI2.EditControls
if(this.locodePoC.LocodeValue == "ZZNOK")
{
this.Core.IsTransit = true;
this.Core.IsTransit = true;
this.Core.ETAKielCanal = this.datePickerETA.SelectedDate;
}
@ -78,7 +78,7 @@ namespace ENI2.EditControls
private void doubleUpDownIMO_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
bool hasValue = (doubleUpDownIMO.Value.HasValue && doubleUpDownIMO.Value > 0);
bool hasValue = doubleUpDownIMO.Value.HasValue && doubleUpDownIMO.Value > 0;
doubleUpDownENI.IsReadOnly = hasValue;
this.CheckComplete();
@ -88,7 +88,7 @@ namespace ENI2.EditControls
private void doubleUpDownENI_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
bool hasValue = (doubleUpDownENI.Value.HasValue && doubleUpDownENI.Value > 0);
bool hasValue = doubleUpDownENI.Value.HasValue && doubleUpDownENI.Value > 0;
doubleUpDownIMO.IsReadOnly = hasValue;
this.CheckComplete();
}

View File

@ -405,7 +405,7 @@ namespace ENI2
if (!closedDialog.Core.IsDK)
{
// deutsche Häfen fordern eine Visit-Id an, für DK erfolgt hier nur die Anlage eines Datensatzes
closedDialog.Core.BSMDStatusInternal = MessageCore.BSMDStatus.TOSEND;
closedDialog.Core.BSMDStatusInternal = MessageCore.BSMDStatus.TOSEND;
}
if (closedDialog.Core.PoC.Equals("ZZNOK"))

View File

@ -98,7 +98,7 @@ namespace ENI2.Util
if (this._watchedEntities.ContainsKey(entity)) // hier wird mit Id verglichen (IEquatable<T> impl.)
this._watchedEntities.Remove(entity);
if (this._watchedEntities.Count == 0)
this.bgTimer.Stop();
this.bgTimer.Stop();
}
}

View File

@ -25,7 +25,7 @@ namespace bsmd.database
#region Construction
public MaerskData()
{
this.tablename = "[dbo].[MaerskData]";
this.tablename = "[dbo].[XtraData]";
}
#endregion
@ -135,12 +135,14 @@ namespace bsmd.database
public async Task<List<MaerskData>> LoadListAsync(SqlDataReader reader)
{
List<MaerskData> result = new List<MaerskData>();
while (await reader.ReadAsync())
if (reader != null)
{
result.Add(ReadRowFromReader(reader));
while (await reader.ReadAsync())
{
result.Add(ReadRowFromReader(reader));
}
reader.Close();
}
reader.Close();
return result;
}

View File

@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using log4net;
using System.Globalization;
using System.Threading.Tasks;
namespace bsmd.database
{
@ -110,16 +111,16 @@ namespace bsmd.database
}
public static bool IsVisitId(string val)
{
{
if (val.IsNullOrEmpty()) return false;
return regexVisit.IsMatch(val);
}
public static bool IsTransitId(string val)
{
{
if (val.IsNullOrEmpty()) return false;
return regexTransit.IsMatch(val);
}
}
/// <summary>
/// Hilfsfunktion für "manuelle" Anlage eines Schiffsanlaufs. Die Objekte sind bereits gespeichert.
@ -137,8 +138,8 @@ namespace bsmd.database
{
_log.WarnFormat("Core {0} [{1}] has more than one message class for {2}", core.Id, core.DisplayId, aMessage.MessageNotificationClassDisplay);
}
messageDict[aMessage.MessageNotificationClass] = aMessage;
}
messageDict[aMessage.MessageNotificationClass] = aMessage;
}
}
bool isDE, isDK;
@ -148,7 +149,7 @@ namespace bsmd.database
isDK = core.PoC.StartsWith("DK");
foreach (Message.NotificationClass notificationClass in Enum.GetValues(typeof(Message.NotificationClass)))
{
{
if(isDE)
{
if (notificationClass == Message.NotificationClass.STO) continue;
@ -207,12 +208,105 @@ namespace bsmd.database
DBManager.Instance.Save(classElement);
message.Elements.Add(classElement);
}
}
}
}
}
return result;
}
/// <summary>
/// Hilfsfunktion für "manuelle" Anlage eines Schiffsanlaufs. Die Objekte sind bereits gespeichert.
/// Es werden nur noch nicht vorhandene Meldeklassen erzeugt (Async version)
/// </summary>
public static async Task<List<Message>> CreateMessagesForCoreAsync(MessageCore core, List<Message> existingMessages, ReportingParty user = null)
{
List<Message> result = new List<Message>();
Dictionary<Message.NotificationClass, Message> messageDict = new Dictionary<Message.NotificationClass, Message>();
if (!existingMessages.IsNullOrEmpty())
{
foreach (Message aMessage in existingMessages)
{
if (messageDict.ContainsKey(aMessage.MessageNotificationClass))
{
_log.WarnFormat("Core {0} [{1}] has more than one message class for {2}", core.Id, core.DisplayId, aMessage.MessageNotificationClassDisplay);
}
messageDict[aMessage.MessageNotificationClass] = aMessage;
}
}
bool isDE, isDK;
if (core?.PoC != null)
{
isDE = core.PoC.Equals("ZZNOK") || core.PoC.StartsWith("DE");
isDK = core.PoC.StartsWith("DK");
foreach (Message.NotificationClass notificationClass in Enum.GetValues(typeof(Message.NotificationClass)))
{
if (isDE)
{
if (notificationClass == Message.NotificationClass.STO) continue;
}
if (isDK)
{
// gibt es hier etwas, das nicht gebraucht wird? (siehe Mail von Christin, 29.5.17
if ((notificationClass == Message.NotificationClass.MDH) ||
(notificationClass == Message.NotificationClass.BKRA) ||
(notificationClass == Message.NotificationClass.BKRD) ||
(notificationClass == Message.NotificationClass.TOWA) ||
(notificationClass == Message.NotificationClass.TOWD)) continue;
}
if (core.IsTransit && (notificationClass == Message.NotificationClass.VISIT)) continue;
if (!core.IsTransit && (notificationClass == Message.NotificationClass.TRANSIT)) continue;
Message message;
if (!messageDict.ContainsKey(notificationClass))
{
message = new Message();
if (user != null)
message.CreatedBy = string.Format("ENI-2: {0}", user.Logon);
message.MessageCore = core;
message.MessageCoreId = core.Id;
message.MessageNotificationClass = notificationClass;
await DBManagerAsync.Save(message);
result.Add(message);
}
else
{
message = messageDict[notificationClass];
}
// abgesehen von "Listen" für die Nachrichtenklassen auch untergeordnete Elemente erzeugen, falls nicht vorhanden!
DatabaseEntity classElement;
if (!Message.IsListClass(notificationClass) && (message.Elements.Count == 0))
{
classElement = DBManager.CreateMessage(notificationClass);
// CH: 6.10.17: Für die manuelle Eingabe (wird leider nicht ganz auszuschließen sein) wäre es hilfreich, wenn alle Checkboxen nicht leer sind, sondern False beinhalten.
if (notificationClass == Message.NotificationClass.MDH)
{
((MDH)classElement).SetBoolsToFalse();
}
if (notificationClass == Message.NotificationClass.BPOL)
{
// Vorbelegung, Spezialwunsch aus BRV 5.2.18
((BPOL)classElement).CruiseShip = false;
((BPOL)classElement).StowawaysOnBoard = false;
}
if (classElement != null) // null für Visit/Transit
{
classElement.MessageHeader = message;
await DBManagerAsync.Save(classElement);
message.Elements.Add(classElement);
}
}
}
}
return result;
}
public static int? GetNumericIdentifier(ISublistElement element)
{
if (element != null)