diff --git a/Stundensheet.xlsx b/Stundensheet.xlsx index 226f0584..74e3b04a 100644 Binary files a/Stundensheet.xlsx and b/Stundensheet.xlsx differ diff --git a/nsw/Source/SendNSWMessageService/NSWSendService.cs b/nsw/Source/SendNSWMessageService/NSWSendService.cs index 6832d697..5c138aaf 100644 --- a/nsw/Source/SendNSWMessageService/NSWSendService.cs +++ b/nsw/Source/SendNSWMessageService/NSWSendService.cs @@ -35,8 +35,14 @@ namespace SendNSWMessageService this.EventLog.Source = this.ServiceName; this.EventLog.Log = "Application"; this.Init(args); - this.EventLog.WriteEntry("NSW Send Service started.", EventLogEntryType.Information); - _log.Info("NSW Send Service started"); + + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + string version = fvi.FileVersion; + + this.EventLog.WriteEntry("NSW Send Service started", EventLogEntryType.Information); + _log.InfoFormat("NSW Send Service started. v.{0}", version); + this.DoOnce(); } @@ -128,11 +134,47 @@ namespace SendNSWMessageService (message.MessageNotificationClass == Message.NotificationClass.TIEFD) || (message.MessageNotificationClass == Message.NotificationClass.NAME) || (message.MessageNotificationClass == Message.NotificationClass.INFO) || - (message.MessageNotificationClass == Message.NotificationClass.POBD)) + (message.MessageNotificationClass == Message.NotificationClass.POBD) || + (message.MessageNotificationClass == Message.NotificationClass.ATA) || + (message.MessageNotificationClass == Message.NotificationClass.ATD) || + (message.MessageNotificationClass == Message.NotificationClass.LADG) || + (message.MessageNotificationClass == Message.NotificationClass.SERV) || + (message.MessageNotificationClass == Message.NotificationClass.WAS) || + (message.MessageNotificationClass == Message.NotificationClass.TOWD)) continue; } + // Visit/Transit Meldeklassen werden nicht erneut übertragen + if ((message.MessageNotificationClass == Message.NotificationClass.VISIT) || + (message.MessageNotificationClass == Message.NotificationClass.TRANSIT)) + continue; + // Wenn kein Gefahrgut gemeldet ist soll die Meldeklasse gar nicht gesendet werden + if((message.MessageNotificationClass == Message.NotificationClass.HAZA) || + (message.MessageNotificationClass == Message.NotificationClass.HAZD)) + { + if (message.Elements.Count > 0) + { + HAZ haz = message.Elements[0] as HAZ; + if (haz != null) + { + if (haz.NoDPGOnBoardOnArrival ?? false) continue; + } + } + } + + // ATD wird nur gesendet, wenn weniger als 60 Minuten in der Zukunft + if(message.MessageNotificationClass == Message.NotificationClass.ATD) + { + if (message.Elements.Count > 0) + { + bsmd.database.ATD atd = message.Elements[0] as bsmd.database.ATD; + if (!atd.ATDPortOfCall.HasValue) continue; + if ((atd.ATDPortOfCall.Value - DateTime.UtcNow).TotalMinutes > 60) continue; + } + } + + if (message.InternalStatus != Message.BSMDStatus.CONFIRMED) //(message.InternalStatus == Message.BSMDStatus.PREPARE) || //(message.InternalStatus == Message.BSMDStatus.TOSEND)) diff --git a/nsw/Source/bsmd.ReportGenerator/ReportService.cs b/nsw/Source/bsmd.ReportGenerator/ReportService.cs index 84f44deb..90834295 100644 --- a/nsw/Source/bsmd.ReportGenerator/ReportService.cs +++ b/nsw/Source/bsmd.ReportGenerator/ReportService.cs @@ -33,7 +33,10 @@ namespace bsmd.ReportGenerator this.EventLog.Log = "Application"; this.Init(args); this.EventLog.WriteEntry("Report Service started.", EventLogEntryType.Information); - _log.Info("Report Service started."); + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + string version = fvi.FileVersion; + _log.InfoFormat("Report Service started. v.{0}", version); this.DoOnce(); } diff --git a/nsw/Source/bsmd.dakosy.ResponseService/SFTPService.cs b/nsw/Source/bsmd.dakosy.ResponseService/SFTPService.cs index 838df08f..14d76a30 100644 --- a/nsw/Source/bsmd.dakosy.ResponseService/SFTPService.cs +++ b/nsw/Source/bsmd.dakosy.ResponseService/SFTPService.cs @@ -38,6 +38,10 @@ namespace bsmd.dakosy.ResponseService this.EventLog.Log = "Application"; this.Init(args); this.EventLog.WriteEntry("NSW SFTP Response Service started.", EventLogEntryType.Information); + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + string version = fvi.FileVersion; + _log.InfoFormat("Dakosy SFTP Response Service started. v.{0}", version); this._timer_Elapsed(null, null); } diff --git a/nsw/Source/bsmd.database/PortOfCallLast30Days.cs b/nsw/Source/bsmd.database/PortOfCallLast30Days.cs index 939a961d..32e55845 100644 --- a/nsw/Source/bsmd.database/PortOfCallLast30Days.cs +++ b/nsw/Source/bsmd.database/PortOfCallLast30Days.cs @@ -145,9 +145,12 @@ namespace bsmd.database if((this.PortOfCallLast30DaysCrewMembersJoined ?? false) && (this.CrewJoinedShip.Count == 0)) RuleEngine.CreateViolation(ValidationCode.V767, "Joined crew members", null); - foreach (PortOfCallLast30DaysCrewJoinedShip poc30Crew in this.CrewJoinedShip) + if (this.PortOfCallLast30DaysCrewMembersJoined ?? false) { - RuleEngine.ValidateProperties(poc30Crew, errors); + foreach (PortOfCallLast30DaysCrewJoinedShip poc30Crew in this.CrewJoinedShip) + { + RuleEngine.ValidateProperties(poc30Crew, errors); + } } } diff --git a/nsw/Source/bsmd.database/Properties/AssemblyProductInfo.cs b/nsw/Source/bsmd.database/Properties/AssemblyProductInfo.cs index 4bcc7b1c..d684ec1b 100644 --- a/nsw/Source/bsmd.database/Properties/AssemblyProductInfo.cs +++ b/nsw/Source/bsmd.database/Properties/AssemblyProductInfo.cs @@ -2,6 +2,6 @@ [assembly: AssemblyCompany("Informatikbüro Daniel Schick")] [assembly: AssemblyProduct("BSMD NSW interface")] -[assembly: AssemblyInformationalVersion("2.4.1")] +[assembly: AssemblyInformationalVersion("2.4.3")] [assembly: AssemblyCopyright("Copyright © 2014-2015 Informatikbüro Daniel Schick. All rights reserved.")] [assembly: AssemblyTrademark("")] \ No newline at end of file diff --git a/nsw/Source/bsmd.database/Properties/AssemblyProjectInfo.cs b/nsw/Source/bsmd.database/Properties/AssemblyProjectInfo.cs index 844680c7..1ce61e7d 100644 --- a/nsw/Source/bsmd.database/Properties/AssemblyProjectInfo.cs +++ b/nsw/Source/bsmd.database/Properties/AssemblyProjectInfo.cs @@ -4,6 +4,6 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.4.1.*")] +[assembly: AssemblyVersion("2.4.3.*")] // wenn das nicht auskommentiert wird erhalten wir eine Warnung // [assembly: AssemblyFileVersion("1.0.0.*")] diff --git a/nsw/Source/bsmd.dbh/Request.cs b/nsw/Source/bsmd.dbh/Request.cs index b3e20734..2b8cb6b3 100644 --- a/nsw/Source/bsmd.dbh/Request.cs +++ b/nsw/Source/bsmd.dbh/Request.cs @@ -564,6 +564,7 @@ namespace bsmd.dbh rootInfo.SpecialRequirementsOfShipAtBerth = info.SpecialRequirementsOfShipAtBerth; if(info.SpecialRequirementsOfShipAtBerth.IsNullOrEmpty()) { + _log.Info("dbh INFO send: SpecialRequirementsOfShipAtBerth is empty."); // Name des Agenten eintragen } rootInfo.ConstructionCharacteristicsOfShip = info.ConstructionCharacteristicsOfShip; @@ -760,16 +761,19 @@ namespace bsmd.dbh rootWAS.ItemsElementName[0] = ItemsChoiceType3.ConfirmationOfCorrectness; rootWAS.Items[0] = was.ConfirmationOfCorrectness ?? false ? RootWASConfirmationOfCorrectness.Y : RootWASConfirmationOfCorrectness.N; + rootWAS.ItemsElementName[1] = ItemsChoiceType3.LastWasteDisposalDate; if (was.LastWasteDisposalDate.HasValue) rootWAS.Items[1] = was.LastWasteDisposalDate.Value; + rootWAS.ItemsElementName[2] = ItemsChoiceType3.LastWasteDisposalPort; - rootWAS.Items[2] = was.LastWasteDisposalPort; - - rootWAS.ItemsElementName[2] = ItemsChoiceType3.WasteDisposalServiceProviderName; + rootWAS.Items[2] = was.LastWasteDisposalPort; + + rootWAS.ItemsElementName[3] = ItemsChoiceType3.WasteDisposalDelivery; if (was.WasteDisposalDelivery.HasValue) rootWAS.Items[3] = (RootWASWasteDisposalDelivery)was.WasteDisposalDelivery.Value; + rootWAS.ItemsElementName[4] = ItemsChoiceType3.WasteDisposalServiceProviderName; if (was.WasteDisposalServiceProvider.Count > 0) { @@ -799,7 +803,7 @@ namespace bsmd.dbh { rww.WasteDescription = was.Waste[j-5].WasteDescription; if (was.Waste[j - 5].WasteType.HasValue) - rww.WasteType = (RootWASWasteWasteType)was.Waste[j - 5].WasteType.Value; + rww.WasteType = (RootWASWasteWasteType) (was.Waste[j - 5].WasteType.Value - 1); // im generierten Code ist das 0-basiert if (was.Waste[j - 5].WasteDisposalAmount_MTQ.HasValue) rww.WasteDisposalAmount_MTQ = (float)was.Waste[j - 5].WasteDisposalAmount_MTQ.Value; rww.WasteDetails = new RootWASWasteWasteDetails(); @@ -1391,7 +1395,10 @@ namespace bsmd.dbh } catch (Exception ex) { - _log.ErrorFormat("exception on message send: {0}", ex.Message); + _log.ErrorFormat("Exception on dbh message send: {0}", ex.Message); + if (ex.InnerException != null) + _log.ErrorFormat("Inner exception: {0}", ex.InnerException.Message); + returnval = false; } diff --git a/nsw/Source/bsmd.herberg.FormService/FormService.cs b/nsw/Source/bsmd.herberg.FormService/FormService.cs index f27f5920..74def239 100644 --- a/nsw/Source/bsmd.herberg.FormService/FormService.cs +++ b/nsw/Source/bsmd.herberg.FormService/FormService.cs @@ -35,7 +35,10 @@ namespace bsmd.herberg.FormService this.EventLog.Log = "Application"; this.Init(args); this.EventLog.WriteEntry("FormService started.", EventLogEntryType.Information); - this._log.Info("Starting EU-NOAD FormService."); + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); + string version = fvi.FileVersion; + this._log.InfoFormat("Starting EU-NOAD FormService. v.{0}", version); this.DoOnce(); } diff --git a/nsw/Source/bsmd.herberg.FormService/Util.cs b/nsw/Source/bsmd.herberg.FormService/Util.cs index cb2d208a..2e739d4d 100644 --- a/nsw/Source/bsmd.herberg.FormService/Util.cs +++ b/nsw/Source/bsmd.herberg.FormService/Util.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; +using System.Text.RegularExpressions; using log4net; using bsmd.database; @@ -39,13 +40,22 @@ namespace bsmd.herberg.FormService //for (int i = 0; i < formResponse.formDatasets.Length; i++) if(formResponse.formDatasets.Length > 0) // wir verarbeiten nur das "neueste" form dataset - { + { int i = formResponse.formDatasets.Length - 1; - // Daten werden nur aktualisiert, wenn die form ein anderes (=neueres) Rev. Date hat - if (aMessageCore.HerbergRevDate.HasValue && (formResponse.formDatasets[i].revisionDate == aMessageCore.HerbergRevDate.Value)) - return; + // nur zum debuggen + for (int n = 0; n < formResponse.formDatasets[i].formData.Length; n++) + { + if (formResponse.formDatasets[i].formData[n].name.Contains("Transmission")) + { + _log.Info("foundit"); + } + } + + // Daten werden nur aktualisiert, wenn die form ein anderes (=neueres) Rev. Date hat + if (aMessageCore.HerbergRevDate.HasValue && (formResponse.formDatasets[i].revisionDate == aMessageCore.HerbergRevDate.Value)) + return; if (aMessageCore.ReportStatus != MessageCore.ReportStatusEnum.COMPLETE) aMessageCore.ReportStatus = MessageCore.ReportStatusEnum.HE_REVISION; @@ -588,9 +598,11 @@ namespace bsmd.herberg.FormService #region BKRA case "BKRA": { + Dictionary keysInMessage = new Dictionary(); foreach (int key in nDict.Keys) { Dictionary bDict = nDict[key]; + keysInMessage.Add(key.ToString(), key.ToString()); BRKA bkra = theMessage.GetSublistElementWithIdentifier(key.ToString()) as BRKA; if (bkra == null) { @@ -611,7 +623,19 @@ namespace bsmd.herberg.FormService _log.ErrorFormat("Error reading BKRA fields: {0}", ex.Message); } saveMessages.Add(bkra); - } + } + + // check for missing messages (passenger deleted in EU-NOAD) + foreach (BRKA bkra in theMessage.Elements) + { + if (!keysInMessage.ContainsKey(bkra.Identifier)) + { + _log.InfoFormat("BRKA {0}, Ident {1} not found in EU-NOAD message, removing!", + bkra.BunkerFuelType ?? "", bkra.Identifier); + DBManager.Instance.Delete(bkra); + } + } + } break; #endregion @@ -619,9 +643,11 @@ namespace bsmd.herberg.FormService #region SERV case "SERV": { + Dictionary keysInMessage = new Dictionary(); foreach (int key in nDict.Keys) { Dictionary pDict = nDict[key]; + keysInMessage.Add(key.ToString(), key.ToString()); SERV serv = theMessage.GetSublistElementWithIdentifier(key.ToString()) as SERV; if (serv == null) { @@ -644,6 +670,16 @@ namespace bsmd.herberg.FormService saveMessages.Add(serv); } + // check for missing messages (passenger deleted in EU-NOAD) + foreach (SERV serv in theMessage.Elements) + { + if (!keysInMessage.ContainsKey(serv.Identifier)) + { + _log.InfoFormat("SERV {0}, Ident {1} not found in EU-NOAD message, removing!", + serv.ServiceName ?? "", serv.Identifier); + DBManager.Instance.Delete(serv); + } + } } break; #endregion @@ -701,9 +737,11 @@ namespace bsmd.herberg.FormService #region BKRD case "BKRD": { + Dictionary keysInMessage = new Dictionary(); foreach (int key in nDict.Keys) { Dictionary bDict = nDict[key]; + keysInMessage.Add(key.ToString(), key.ToString()); BRKD bkrd = theMessage.GetSublistElementWithIdentifier(key.ToString()) as BRKD; if (bkrd == null) { @@ -726,6 +764,18 @@ namespace bsmd.herberg.FormService saveMessages.Add(bkrd); } + + // check for missing messages (passenger deleted in EU-NOAD) + foreach (BRKD brkd in theMessage.Elements) + { + if (!keysInMessage.ContainsKey(brkd.Identifier)) + { + _log.InfoFormat("BRKD {0}, Ident {1} not found in EU-NOAD message, removing!", + brkd.BunkerFuelType ?? "", brkd.Identifier); + DBManager.Instance.Delete(brkd); + } + } + } break; #endregion @@ -749,9 +799,18 @@ namespace bsmd.herberg.FormService if (vDict.ContainsKey("ShippingArea")) info.ShippingArea = (byte) Enum.Parse(typeof(Enums.ShippingArea), vDict["ShippingArea"]); if (vDict.ContainsKey("RequestedPositionInPortOfCall")) info.RequestedPositionInPortOfCall = vDict["RequestedPositionInPortOfCall"]; if (vDict.ContainsKey("SpecialRequirementsOfShipAtBerth")) info.SpecialRequirementsOfShipAtBerth = vDict["SpecialRequirementsOfShipAtBerth"]; - else info.SpecialRequirementsOfShipAtBerth = aMessageCore.Customer.Name; + if (info.SpecialRequirementsOfShipAtBerth.IsNullOrEmpty()) + info.SpecialRequirementsOfShipAtBerth = aMessageCore.Customer.Name; + else + { + if((aMessageCore.Customer != null) && (aMessageCore.Customer.Name != null)) + info.SpecialRequirementsOfShipAtBerth = string.Format("{0} - Agent: {1}", info.SpecialRequirementsOfShipAtBerth, aMessageCore.Customer.Name); + } if (vDict.ContainsKey("ConstructionCharacteristicsOfShip")) info.ConstructionCharacteristicsOfShip = vDict["ConstructionCharacteristicsOfShip"]; - if (vDict.ContainsKey("FumigatedBulkCargo")) info.FumigatedBulkCargo = (byte)Enum.Parse(typeof(Enums.FumigatedBulkCargo), vDict["FumigatedBulkCargo"]); + if (vDict.ContainsKey("FumigatedBulkCargo") && !vDict["FumigatedBulkCargo"].IsNullOrEmpty()) + info.FumigatedBulkCargo = (byte)Enum.Parse(typeof(Enums.FumigatedBulkCargo), vDict["FumigatedBulkCargo"]); + else + info.FumigatedBulkCargo = (byte) Enums.FumigatedBulkCargo.N; } catch(Exception ex) { @@ -801,9 +860,11 @@ namespace bsmd.herberg.FormService #region LADG case "LADG": { + Dictionary keysInMessage = new Dictionary(); foreach (int key in nDict.Keys) { Dictionary lDict = nDict[key]; + keysInMessage.Add(key.ToString(), key.ToString()); LADG ladg = theMessage.GetSublistElementWithIdentifier(key.ToString()) as LADG; if (ladg == null) { @@ -820,6 +881,17 @@ namespace bsmd.herberg.FormService saveMessages.Add(ladg); } + + // check for missing messages (passenger deleted in EU-NOAD) + foreach (LADG ladg in theMessage.Elements) + { + if (!keysInMessage.ContainsKey(ladg.Identifier)) + { + _log.InfoFormat("LADG {0}, Ident {1} not found in EU-NOAD message, removing!", + ladg.CargoCodeNST ?? "", ladg.Identifier); + DBManager.Instance.Delete(ladg); + } + } } break; #endregion @@ -936,6 +1008,14 @@ namespace bsmd.herberg.FormService if (wDict.ContainsKey("WasteDisposalCountryCode") && wDict.ContainsKey("WasteDisposalPortCode")) waste.WasteDisposalPort = wDict["WasteDisposalCountryCode"] + wDict["WasteDisposalPortCode"]; + // Wenn das Feld leer ist mit "-" entwerten + if (((waste.WasteType ?? 0) == 3) && waste.WasteDescription.IsNullOrEmpty()) + waste.WasteDescription = "-"; + if (((waste.WasteType ?? 0) == 8) && waste.WasteDescription.IsNullOrEmpty()) + waste.WasteDescription = "-"; + if (((waste.WasteType ?? 0) == 9) && waste.WasteDescription.IsNullOrEmpty()) + waste.WasteDescription = "-"; + saveMessages.Add(waste); } @@ -1051,6 +1131,20 @@ namespace bsmd.herberg.FormService poc.PortFacilityGISISCode = poc.PortFacilityGISISCode.Substring(0, 4); } + // sanitize GISIS code + if (poc.PortFacilityGISISCode.IsNullOrEmpty()) + { + poc.PortFacilityGISISCode = "0000"; + } + else { + Regex rgx = new Regex("[0-9]{4}"); + if (!rgx.IsMatch(poc.PortFacilityGISISCode)) + { + _log.WarnFormat("PortFacilityGISISCode invalid: {0}, replacing with 0000", poc.PortFacilityGISISCode); + poc.PortFacilityGISISCode = "0000"; + } + } + if (sDict.ContainsKey("ShipToShipActivityLocationName")) { sts.ShipToShipActivityLocationName = sDict["ShipToShipActivityLocationName"]; changedStS = true; } if (sDict.ContainsKey("ShipToShipActivityLocationLoCode") && sDict.ContainsKey("ShipToShipActivityCountryCode") && (sDict["ShipToShipActivityLocationLoCode"].Length < 4)) { @@ -1262,6 +1356,10 @@ namespace bsmd.herberg.FormService if (vDict.ContainsKey("DPGClassificationIBC")) haz.DPGClassificationIMDG = vDict["DPGClassificationIBC"].Equals("1"); if (vDict.ContainsKey("DPGClassificationIMSBC")) haz.DPGClassificationIMDG = vDict["DPGClassificationIMSBC"].Equals("1"); if (vDict.ContainsKey("DPGClassificationMARPOL_ANNEX_I")) haz.DPGClassificationIMDG = vDict["DPGClassificationMARPOL_ANNEX_I"].Equals("1"); + if (vDict.ContainsKey("TransmissionType")) + { + _log.DebugFormat("TransmissionType: {0}", vDict["TransmissionType"]); + } Dictionary> subDict = null; if (groupedRowVals.ContainsKey("HAZ.IMDG"))