diff --git a/ENI-2/ENI2/ENI2/DetailRootControl.xaml.cs b/ENI-2/ENI2/ENI2/DetailRootControl.xaml.cs
index 810e0757..82e49694 100644
--- a/ENI-2/ENI2/ENI2/DetailRootControl.xaml.cs
+++ b/ENI-2/ENI2/ENI2/DetailRootControl.xaml.cs
@@ -57,6 +57,39 @@ namespace ENI2
get { return this.buttonSave.Visibility == Visibility.Visible; } // schwach aber es wird's tun
}
+ public bool HasUnsentMessages
+ {
+ get
+ {
+ // Bedingung:
+ // wenn in einer Meldeklasse zwar Daten vorhanden sind, eingespielt durch Excel import oder
+ // Handeingabe, diese aber NICHT gesendet wurden.
+ foreach (Message aMessage in _messages)
+ {
+ if ((aMessage.InternalStatus == Message.BSMDStatus.UPDATED) ||
+ (aMessage.InternalStatus == Message.BSMDStatus.SAVED) ||
+ (aMessage.InternalStatus == Message.BSMDStatus.EXCEL))
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ public bool HasUnConfirmedMessages
+ {
+ get
+ {
+ foreach(Message aMessage in _messages)
+ {
+ if ((aMessage.InternalStatus == Message.BSMDStatus.SENT) ||
+ (aMessage.InternalStatus == Message.BSMDStatus.TOSEND))
+ return true;
+ }
+ return false;
+ }
+ }
+
#endregion
#region Construction
@@ -231,7 +264,6 @@ namespace ENI2
existingCore = DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).GetMessageCoreByVisitId(newCore.VisitId);
}
-
bool skipCopyTransit = false;
bool skipCopyVisit = false;
@@ -302,6 +334,20 @@ namespace ENI2
if (skipCopyTransit && (oldMessage.MessageNotificationClass == Message.NotificationClass.TRANSIT)) continue;
if (skipCopyVisit && (oldMessage.MessageNotificationClass == Message.NotificationClass.VISIT)) continue;
+ // 10.9.19: bestimmte Meldeklassen nicht kopieren. Muss getestet werden, ob hier
+ // stattdessen "Leer"-Messages erzeugt werden müssen
+ if (oldMessage.MessageNotificationClass == Message.NotificationClass.ATA) continue;
+ if (oldMessage.MessageNotificationClass == Message.NotificationClass.ATD) continue;
+ if (oldMessage.MessageNotificationClass == Message.NotificationClass.NOA_NOD) continue;
+
+ bool isAndienKlasse = ((oldMessage.MessageNotificationClass == Message.NotificationClass.AGNT) ||
+ (oldMessage.MessageNotificationClass == Message.NotificationClass.STAT) ||
+ (oldMessage.MessageNotificationClass == Message.NotificationClass.INFO) ||
+ (oldMessage.MessageNotificationClass == Message.NotificationClass.HAZA) ||
+ (oldMessage.MessageNotificationClass == Message.NotificationClass.HAZD));
+
+ if (!cdd.CopyAll && !isAndienKlasse) continue;
+
Message newMessage = oldMessage.Clone() as Message;
newMessage.MessageCore = newCore;
newMessage.MessageCoreId = newCore.Id;
@@ -366,9 +412,12 @@ namespace ENI2
{
if (message.IsDirty || message.IsNew)
{
- if ((message.Status == Message.MessageStatus.ACCEPTED) &&
+ if ((message.Status == Message.MessageStatus.ACCEPTED) &&
((message.InternalStatus == Message.BSMDStatus.CONFIRMED) || (message.InternalStatus == Message.BSMDStatus.VIOLATION)))
message.InternalStatus = Message.BSMDStatus.UPDATED;
+ else
+ message.InternalStatus = Message.BSMDStatus.SAVED;
+
string userName = "?";
if(App.UserId.HasValue && DBManager.Instance.GetReportingPartyDict().ContainsKey(App.UserId.Value))
{
@@ -377,24 +426,8 @@ namespace ENI2
message.ChangedBy = string.Format("{0} at {1}", userName, DateTime.Now);
DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(message);
- //if (message.MessageNotificationClass == Message.NotificationClass.CREW)
- //{
- // foreach(CREW crew in message.Elements)
- // {
- // if (crew.IsNew || crew.IsDirty) DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(crew);
- // }
- //}
- //else if (message.MessageNotificationClass == Message.NotificationClass.PAS)
- //{
- // foreach(PAS pas in message.Elements)
- // {
- // if(pas.IsNew || pas.IsDirty) DBManager.GetSingleCon(Properties.Settings.Default.ConnectionString).Save(pas);
- // }
- //}
- //else
- //{
- message.SaveElements();
- //}
+ message.SaveElements();
+
message.IsDirty = false;
if(message.MessageNotificationClass == Message.NotificationClass.ATA)
diff --git a/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml b/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml
index 0b029f3b..94e44c07 100644
--- a/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml
+++ b/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml
@@ -8,7 +8,7 @@
xmlns:p="clr-namespace:ENI2.Properties"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
- Title="{x:Static p:Resources.textCopyDeclaration}" Height="270" Width="440" WindowStyle="SingleBorderWindow" Background="AliceBlue" ResizeMode="NoResize" Icon="/ENI2;component/Resources/id_cards.ico">
+ Title="{x:Static p:Resources.textCopyDeclaration}" Height="326" Width="440" WindowStyle="SingleBorderWindow" Background="AliceBlue" ResizeMode="NoResize" Icon="/ENI2;component/Resources/id_cards.ico">
@@ -17,6 +17,8 @@
+
+
@@ -29,6 +31,7 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml.cs b/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml.cs
index 8fa564ff..345875ac 100644
--- a/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml.cs
+++ b/ENI-2/ENI2/ENI2/EditControls/CopyDeclarationDialog.xaml.cs
@@ -23,31 +23,7 @@ namespace ENI2.EditControls
{
InitializeComponent();
Loaded += CopyDeclarationDialog_Loaded;
- }
-
- private void CopyDeclarationDialog_Loaded(object sender, System.Windows.RoutedEventArgs e)
- {
- this.OKClicked += VisitIdDialog_OKClicked;
- List> comboDataSource = new List>()
- {
- new KeyValuePair( Message.NSWProvider.DBH, "DBH live" ),
- new KeyValuePair( Message.NSWProvider.DBH_TEST, "DBH Testsystem" ),
- new KeyValuePair( Message.NSWProvider.DUDR, "HIS-Nord live" ),
- new KeyValuePair( Message.NSWProvider.DUDR_TEST, "HIS-Nord Testsystem" )
- };
-
- this.comboBoxInitialHIS.ItemsSource = comboDataSource;
- this.comboBoxInitialHIS.SelectedIndex = 2;
-
- this.EnableOK(false);
- this.locodePoC.PropertyChanged += LocodePoC_PropertyChanged;
-
- if (!this.OldCore.IMO.IsNullOrEmpty()) this.doubleUpDownIMO.Value = Double.Parse(this.OldCore.IMO);
- if (!this.OldCore.ENI.IsNullOrEmpty()) this.doubleUpDownENI.Value = Double.Parse(this.OldCore.ENI);
- if (!this.OldCore.PoC.IsNullOrEmpty()) this.locodePoC.LocodeValue = this.OldCore.PoC;
- if (this.OldCore.ETA.HasValue) this.datePickerETA.SelectedDate = this.OldCore.ETA;
-
- }
+ }
#region Properties
@@ -57,6 +33,8 @@ namespace ENI2.EditControls
public bool IsOK { get { return this._isOK; } }
+ public bool CopyAll { get { return this.radioButtonCopyAll.IsChecked ?? false; } }
+
#endregion
#region completion logic
@@ -93,6 +71,30 @@ namespace ENI2.EditControls
#region event handler
+ private void CopyDeclarationDialog_Loaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ this.OKClicked += VisitIdDialog_OKClicked;
+ List> comboDataSource = new List>()
+ {
+ new KeyValuePair( Message.NSWProvider.DBH, "DBH live" ),
+ new KeyValuePair( Message.NSWProvider.DBH_TEST, "DBH Testsystem" ),
+ new KeyValuePair( Message.NSWProvider.DUDR, "HIS-Nord live" ),
+ new KeyValuePair( Message.NSWProvider.DUDR_TEST, "HIS-Nord Testsystem" )
+ };
+
+ this.comboBoxInitialHIS.ItemsSource = comboDataSource;
+ this.comboBoxInitialHIS.SelectedIndex = 2;
+
+ this.EnableOK(false);
+ this.locodePoC.PropertyChanged += LocodePoC_PropertyChanged;
+
+ if (!this.OldCore.IMO.IsNullOrEmpty()) this.doubleUpDownIMO.Value = Double.Parse(this.OldCore.IMO);
+ if (!this.OldCore.ENI.IsNullOrEmpty()) this.doubleUpDownENI.Value = Double.Parse(this.OldCore.ENI);
+ if (!this.OldCore.PoC.IsNullOrEmpty()) this.locodePoC.LocodeValue = this.OldCore.PoC;
+ if (this.OldCore.ETA.HasValue) this.datePickerETA.SelectedDate = this.OldCore.ETA;
+
+ }
+
private void LocodePoC_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.CheckComplete();
diff --git a/ENI-2/ENI2/ENI2/MainWindow.xaml.cs b/ENI-2/ENI2/ENI2/MainWindow.xaml.cs
index 65845a3c..949a2691 100644
--- a/ENI-2/ENI2/ENI2/MainWindow.xaml.cs
+++ b/ENI-2/ENI2/ENI2/MainWindow.xaml.cs
@@ -159,6 +159,21 @@ namespace ENI2
e.Cancel = true;
}
+ // Test for unsent messages
+ if (!e.Cancel && drc.HasUnsentMessages)
+ {
+ if (MessageBox.Show(Properties.Resources.textConfirmUnsentMessages, Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No)
+ e.Cancel = true;
+ }
+
+ // Test for unconfirmed messages
+ if(!e.Cancel && drc.HasUnConfirmedMessages)
+ {
+ if (MessageBox.Show(Properties.Resources.textConfirmUnconfirmedMessages, Properties.Resources.textConfirmation, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No)
+ e.Cancel = true;
+ }
+
+
if (!e.Cancel)
{
if (lockedCores.ContainsKey(tabItem))
diff --git a/ENI-2/ENI2/ENI2/Properties/Resources.Designer.cs b/ENI-2/ENI2/ENI2/Properties/Resources.Designer.cs
index d9046a93..073e9b78 100644
--- a/ENI-2/ENI2/ENI2/Properties/Resources.Designer.cs
+++ b/ENI-2/ENI2/ENI2/Properties/Resources.Designer.cs
@@ -1370,6 +1370,24 @@ namespace ENI2.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to Unconfirmed messages! Do you want to close anyway?.
+ ///
+ public static string textConfirmUnconfirmedMessages {
+ get {
+ return ResourceManager.GetString("textConfirmUnconfirmedMessages", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unsent messages! Do you want to close anyway?.
+ ///
+ public static string textConfirmUnsentMessages {
+ get {
+ return ResourceManager.GetString("textConfirmUnsentMessages", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Unsaved changes! Do you want to close anyway?.
///
diff --git a/ENI-2/ENI2/ENI2/Properties/Resources.resx b/ENI-2/ENI2/ENI2/Properties/Resources.resx
index 6eff215c..01e788e8 100644
--- a/ENI-2/ENI2/ENI2/Properties/Resources.resx
+++ b/ENI-2/ENI2/ENI2/Properties/Resources.resx
@@ -1525,6 +1525,12 @@
Unsaved changes! Do you want to close anyway?
+
+ Unsent messages! Do you want to close anyway?
+
+
+ Unconfirmed messages! Do you want to close anyway?
+
Some messages have unsaved changes. Send anyway?
diff --git a/Stundensheet.xlsx b/Stundensheet.xlsx
index 70b37197..fa1f6d05 100644
Binary files a/Stundensheet.xlsx and b/Stundensheet.xlsx differ
diff --git a/nsw/Source/bsmd.ExcelReadService/ExcelReadService.cs b/nsw/Source/bsmd.ExcelReadService/ExcelReadService.cs
index 82c17e0e..d1afd932 100644
--- a/nsw/Source/bsmd.ExcelReadService/ExcelReadService.cs
+++ b/nsw/Source/bsmd.ExcelReadService/ExcelReadService.cs
@@ -30,7 +30,7 @@ namespace bsmd.ExcelReadService
{
this.EventLog.Source = this.ServiceName;
this.EventLog.Log = "Application";
- this.Init(args);
+ this.Init();
this.EventLog.WriteEntry("NSW Excel Read Service started.", EventLogEntryType.Information);
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
@@ -40,7 +40,7 @@ namespace bsmd.ExcelReadService
this.DoOnce();
}
- private void Init(string[] args)
+ private void Init()
{
this._timer = new Timer
{
diff --git a/nsw/Source/bsmd.ExcelReadService/Util.cs b/nsw/Source/bsmd.ExcelReadService/Util.cs
index abc9b0c9..0868d7df 100644
--- a/nsw/Source/bsmd.ExcelReadService/Util.cs
+++ b/nsw/Source/bsmd.ExcelReadService/Util.cs
@@ -22,8 +22,6 @@ namespace bsmd.ExcelReadService
internal static bool ProcessSheet(ExcelReader reader, out string readMessage, out MessageCore messageCore)
{
- readMessage = "ok";
-
messageCore = Util.LookupMessageCore(reader, out readMessage);
if (messageCore == null) return false; // cannot work with this sheet or create one
@@ -138,6 +136,7 @@ namespace bsmd.ExcelReadService
foreach (Message message in messages)
{
message.CreatedBy = "EXCEL";
+ message.InternalStatus = Message.BSMDStatus.EXCEL;
DBManager.Instance.Save(message);
message.SaveElements();
}
@@ -2590,7 +2589,7 @@ namespace bsmd.ExcelReadService
// lookup using field values
MessageCore result = null;
DateTime? eta = null;
- string poc = null;
+ string poc;
string imo = null;
message = string.Empty;
bool isTransit = false;
@@ -2708,9 +2707,11 @@ namespace bsmd.ExcelReadService
imo = reader.ReadText("Visit.IMONumber");
reader.Conf.ConfirmText("Visit.IMONumber", imo, imo.IsNullOrEmpty() ? ExcelReader.ReadState.FAIL : ExcelReader.ReadState.OK);
+ if ((imo.Length > 0) && !bsmd.database.Util.IsIMOValid(imo))
+ reader.Conf.ConfirmText("Visit.IMONumber", imo, ExcelReader.ReadState.WARN);
// ETA
- if(poc != null)
+ if (poc != null)
eta = reader.ReadDateTime("NOA_NOD.ETADateToPortOfCall", "NOA_NOD.ETATimeToPortOfCall");
if ((imo != null) && (eta.HasValue) && (poc != null))
@@ -2795,6 +2796,11 @@ namespace bsmd.ExcelReadService
result.IMO = result.IMO.Substring(0, 7);
}
+ if((result.IMO.Length == 7) && !bsmd.database.Util.IsIMOValid(result.IMO))
+ {
+ _log.WarnFormat("IMO {0} possibly invalid (checksum number violation)", result.IMO);
+ }
+
if(visitTransitId != null)
{
if (bsmd.database.Util.IsTransitId(visitTransitId))
diff --git a/nsw/Source/bsmd.database/Message.cs b/nsw/Source/bsmd.database/Message.cs
index f4933479..9a646e22 100644
--- a/nsw/Source/bsmd.database/Message.cs
+++ b/nsw/Source/bsmd.database/Message.cs
@@ -157,7 +157,9 @@ namespace bsmd.database
SUSPENDED = 8,
IN_USE,
UPDATED,
- REPORT // nur für diese Meldeklasse einen PDF Report erzeugen (geht danach wieder auf PREPARE)
+ REPORT, // nur für diese Meldeklasse einen PDF Report erzeugen (geht danach wieder auf PREPARE)
+ SAVED, // veränderte Meldeklasse wird im ENI gespeichert
+ EXCEL // Meldeklasse wurde in Excel befüllt
}
///
diff --git a/nsw/Source/bsmd.database/Util.cs b/nsw/Source/bsmd.database/Util.cs
index b0aa2f6c..434c4fbf 100644
--- a/nsw/Source/bsmd.database/Util.cs
+++ b/nsw/Source/bsmd.database/Util.cs
@@ -227,6 +227,41 @@ namespace bsmd.database
return null;
}
+ public static bool IsIMOValid(string imoAsString)
+ {
+ if (imoAsString.IsNullOrEmpty()) return false;
+ string actualIMO = null;
+ if(imoAsString.Length == 10)
+ {
+ if (imoAsString.Substring(0, 3).Equals("imo", StringComparison.OrdinalIgnoreCase))
+ actualIMO = imoAsString.Substring(3);
+ }
+ if (imoAsString.Length == 7)
+ actualIMO = imoAsString;
+
+ if ((actualIMO != null) && Int32.TryParse(actualIMO, out int _))
+ {
+ /* The integrity of an IMO number can be verified using its check digit. This is done by multiplying
+ * each of the first six digits by a factor of 2 to 7 corresponding to their position from right
+ * to left. The rightmost digit of this sum is the check digit.
+ * For example, for IMO 9074729: (9×7) + (0×6) + (7×5) + (4×4) + (7×3) + (2×2) = 139
+ */
+
+ int sum = 0;
+ for (int i = 0, multiplier = 7; i < 6; i++, multiplier--)
+ {
+ sum += (Convert.ToInt32(actualIMO[i]) * multiplier);
+ }
+
+ int lastdigit = sum % 10; // letzte Stelle
+
+ if (Convert.ToInt32(actualIMO[6]) == lastdigit)
+ return true;
+ }
+
+ return false;
+ }
+
#region CoordinateTransformation
public static double NSWToDecimalDegrees(int nswCoordinate)
diff --git a/nsw/Source/misc/db.sqlite b/nsw/Source/misc/db.sqlite
index efdea21e..0693e66c 100644
Binary files a/nsw/Source/misc/db.sqlite and b/nsw/Source/misc/db.sqlite differ