This commit is contained in:
Daniel Schick 2015-08-12 06:14:59 +00:00
parent d6662eb43a
commit 8204f19121
19 changed files with 1266 additions and 835 deletions

Binary file not shown.

View File

@ -0,0 +1 @@
"C:\Program Files\Java\jre1.8.0_51\bin\java" -jar DD-ImportClient.jar -log=client.log -cfg=client.conf

View File

@ -21,3 +21,4 @@ CORDIR = CORRUPT
VERSION = NSW_V1-0 VERSION = NSW_V1-0
MODE = ONCE MODE = ONCE
XMLRESULTDIR = RESULTS\ XMLRESULTDIR = RESULTS\
ANSWERDIR = ANSWERS\

View File

@ -0,0 +1,55 @@
-----------------------------
25.07.2015 12:26:38 Client started
-----------------------------
25.07.2015 12:26:38 No files to send
-----------------------------
25.07.2015 02:59:17 Client started
-----------------------------
25.07.2015 02:59:18 FileName: IMP\20150725145813-df8bb348-81ee-4803-85af-fff6641a810c.xml
25.07.2015 02:59:18 FileSize: 11525
-----------------------------
25.07.2015 02:59:21 20150725145813-df8bb348-81ee-4803-85af-fff6641a810c.xml(11,25 kB) - XML file doesnt fit Schema
25.07.2015 02:59:21 XML Document has Error:truecvc-type.3.1.3: The value '0' of element 'TowageBeam_MTR' is not valid.
-----------------------------
25.07.2015 03:12:21 Client started
-----------------------------
25.07.2015 03:12:22 FileName: IMP\20150725151154-df8bb348-81ee-4803-85af-fff6641a810c.xml
25.07.2015 03:12:22 FileSize: 12369
-----------------------------
25.07.2015 03:12:23 20150725151154-df8bb348-81ee-4803-85af-fff6641a810c.xml(12,08 kB) - XML file doesnt fit Schema
25.07.2015 03:12:23 XML Document has Error:truecvc-complex-type.2.4.a: Invalid content was found starting with element 'PortOfItineryETA'. One of '{PortOfItineryName}' is expected.
-----------------------------
25.07.2015 03:15:22 Client started
-----------------------------
25.07.2015 03:15:24 FileName: IMP\20150725151517-df8bb348-81ee-4803-85af-fff6641a810c.xml
25.07.2015 03:15:24 FileSize: 12428
-----------------------------
25.07.2015 03:15:24 20150725151517-df8bb348-81ee-4803-85af-fff6641a810c.xml(12,14 kB) - XML file doesnt fit Schema
25.07.2015 03:15:24 XML Document has Error:truecvc-complex-type.4: Attribute 'Index' must appear on element 'PortOfItinery'.
-----------------------------
25.07.2015 03:29:38 Client started
-----------------------------
25.07.2015 03:29:40 FileName: IMP\20150725152924-df8bb348-81ee-4803-85af-fff6641a810c.xml
25.07.2015 03:29:40 FileSize: 12438
-----------------------------
25.07.2015 03:29:40 20150725152924-df8bb348-81ee-4803-85af-fff6641a810c.xml(12,15 kB) - XML file doesnt fit Schema
25.07.2015 03:29:40 XML Document has Error:truecvc-complex-type.2.4.a: Invalid content was found starting with element 'ConfirmationOfCorrectness'. One of '{Wastes}' is expected.
-----------------------------
29.07.2015 21:50:35 Client started
-----------------------------
29.07.2015 21:50:37 FileName: IMP\20150729214822-df8bb348-81ee-4803-85af-fff6641a810c.xml
29.07.2015 21:50:37 FileSize: 12538(12,24 kB)
-----------------------------
29.07.2015 21:50:39 Getting Answers
29.07.2015 21:50:39 20150729214822-df8bb348-81ee-4803-85af-fff6641a810c.xml(12538) - XML file doesnt fit Schema
29.07.2015 21:50:39 XML Document has Error:truecvc-complex-type.2.4.a: Invalid content was found starting with element 'ConfirmationOfCorrectness'. One of '{Wastes}' is expected.
29.07.2015 21:50:39 Filename: DEWVN-2015-ZGGPEQ_VISIT.xml
29.07.2015 21:50:39 Filesize: 149(149 B)
29.07.2015 21:50:39 PACKETSIZE: 500
29.07.2015 21:50:39 Tiles: 1
29.07.2015 21:50:39 Getting Answers
29.07.2015 21:50:40 Filename: DEWVN-2015-XTGWNE_VISIT.xml
29.07.2015 21:50:40 Filesize: 148(148 B)
29.07.2015 21:50:40 PACKETSIZE: 500
29.07.2015 21:50:40 Tiles: 1
29.07.2015 21:50:40 No more Answers

View File

@ -60,6 +60,8 @@ namespace SendNSWMessageService
else this.processRunning = true; else this.processRunning = true;
} }
bool sendSucceeded;
if (DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString)) if (DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString))
{ {
@ -69,104 +71,111 @@ namespace SendNSWMessageService
foreach (MessageCore core in coresMarkedForSending) foreach (MessageCore core in coresMarkedForSending)
{ {
List<Message> messages = DBManager.Instance.GetMessagesForCore(core); List<Message> messages = DBManager.Instance.GetMessagesForCore(core);
List<Message> toSendMessageList = new List<Message>(); if (core.InitialHIS == Message.NSWProvider.DUDR)
if ((core.IsTransit && core.TransitId.IsNullOrEmpty()) ||
(!core.IsTransit && core.VisitId.IsNullOrEmpty()))
{ {
foreach (Message message in messages) // Rostocker: wir senden alle Nachrichten auf einmal
sendSucceeded = bsmd.hisnord.Request.Send(messages);
if (!sendSucceeded) core.BSMDStatusInternal = MessageCore.BSMDStatus.FAILURE;
else core.BSMDStatusInternal = MessageCore.BSMDStatus.SENT;
DBManager.Instance.Save(core);
}
else
{
List<Message> toSendMessageList = new List<Message>();
if ((core.IsTransit && core.TransitId.IsNullOrEmpty()) ||
(!core.IsTransit && core.VisitId.IsNullOrEmpty()))
{ {
if((message.MessageNotificationClass == Message.NotificationClass.VISIT) || foreach (Message message in messages)
(message.MessageNotificationClass == Message.NotificationClass.TRANSIT))
{ {
if((message.InternalStatus == Message.BSMDStatus.UNDEFINED) || if ((message.MessageNotificationClass == Message.NotificationClass.VISIT) ||
(message.MessageNotificationClass == Message.NotificationClass.TRANSIT))
{
if ((message.InternalStatus == Message.BSMDStatus.UNDEFINED) ||
(message.InternalStatus == Message.BSMDStatus.PREPARE) ||
(message.InternalStatus == Message.BSMDStatus.TOSEND))
{
if (message.HIS == Message.NSWProvider.UNDEFINED)
message.HIS = core.InitialHIS;
toSendMessageList.Add(message);
}
}
}
}
else // eine VISIT/TRANSIT Id ist vorhanden, die Daten können gesendet werden
{
// versendet werden nur die Nachrichten, die den Status "UNDEFINED", "PREPARE" und "TOSEND" haben
// diese wurden entweder von EU-NOAD angelegt oder durch den Melder bearbeitet
// Wichtig ist eine erfolgreich versendete Meldung nicht erneut zu versenden
foreach (Message message in messages)
{
if ((message.InternalStatus == Message.BSMDStatus.UNDEFINED) ||
(message.InternalStatus == Message.BSMDStatus.PREPARE) || (message.InternalStatus == Message.BSMDStatus.PREPARE) ||
(message.InternalStatus == Message.BSMDStatus.TOSEND)) (message.InternalStatus == Message.BSMDStatus.TOSEND))
{ {
if (message.HIS == Message.NSWProvider.UNDEFINED) if (message.HIS == Message.NSWProvider.UNDEFINED)
message.HIS = core.InitialHIS; message.HIS = core.InitialHIS;
toSendMessageList.Add(message); toSendMessageList.Add(message);
} }
} }
} }
}
else // eine VISIT/TRANSIT Id ist vorhanden, die Daten können gesendet werden foreach (Message message in toSendMessageList)
{
// versendet werden nur die Nachrichten, die den Status "UNDEFINED", "PREPARE" und "TOSEND" haben
// diese wurden entweder von EU-NOAD angelegt oder durch den Melder bearbeitet
// Wichtig ist eine erfolgreich versendete Meldung nicht erneut zu versenden
foreach (Message message in messages)
{ {
if ((message.InternalStatus == Message.BSMDStatus.UNDEFINED) || try
(message.InternalStatus == Message.BSMDStatus.PREPARE) ||
(message.InternalStatus == Message.BSMDStatus.TOSEND))
{ {
if (message.HIS == Message.NSWProvider.UNDEFINED) _log.InfoFormat("Sending {0} message to {1}",
message.HIS = core.InitialHIS; message.MessageNotificationClass.ToString(), message.HIS.ToString());
sendSucceeded = false;
// switch über passendes HIS / Schnittstelle
switch (message.HIS)
{
case Message.NSWProvider.DBH:
sendSucceeded = bsmd.dbh.Request.SendMessage(message);
if (!sendSucceeded)
message.InternalStatus = Message.BSMDStatus.SEND_FAILED;
break;
case Message.NSWProvider.DAKOSY:
sendSucceeded = bsmd.dakosy.Request.Send(message);
if (!sendSucceeded) message.InternalStatus = Message.BSMDStatus.SEND_FAILED;
break;
default:
_log.WarnFormat("Initial HIS not specified for message {0}", message.Id);
break;
}
if (sendSucceeded)
{
// alte Fehlerliste entfernen (die Antwort kann praktisch noch nicht da sein)
// vor dem Versenden zu entfernen halte ich für doof, wenn das Versenden scheitert
foreach (MessageError messageError in message.ErrorList)
DBManager.Instance.Delete(messageError);
foreach (MessageViolation messageViolation in message.ViolationList)
DBManager.Instance.Delete(messageViolation);
_log.Info("send successful, saving message.");
message.InternalStatus = Message.BSMDStatus.SENT;
message.SentAt = DateTime.Now;
}
DBManager.Instance.Save(message);
toSendMessageList.Add(message);
} }
} catch (Exception ex)
}
foreach (Message message in toSendMessageList)
{
try
{
_log.InfoFormat("Sending {0} message to {1}",
message.MessageNotificationClass.ToString(), message.HIS.ToString());
bool sendSucceeded = false;
// switch über passendes HIS / Schnittstelle
switch (message.HIS)
{ {
case Message.NSWProvider.DBH: _log.ErrorFormat("SENDING message {0}: {1}", message.Id.ToString(), ex.Message);
sendSucceeded = bsmd.dbh.Request.SendMessage(message);
if (!sendSucceeded)
message.InternalStatus = Message.BSMDStatus.SEND_FAILED;
break;
case Message.NSWProvider.DAKOSY:
sendSucceeded = bsmd.dakosy.Request.Send(message);
if (!sendSucceeded) message.InternalStatus = Message.BSMDStatus.SEND_FAILED;
break;
case Message.NSWProvider.DUDR:
sendSucceeded = bsmd.hisnord.Request.Send(message);
if (!sendSucceeded) message.InternalStatus = Message.BSMDStatus.SEND_FAILED;
break;
default:
_log.WarnFormat("Initial HIS not specified for message {0}", message.Id);
break;
} }
if (sendSucceeded)
{
// alte Fehlerliste entfernen (die Antwort kann praktisch noch nicht da sein)
// vor dem Versenden zu entfernen halte ich für doof, wenn das Versenden scheitert
foreach (MessageError messageError in message.ErrorList)
DBManager.Instance.Delete(messageError);
foreach (MessageViolation messageViolation in message.ViolationList)
DBManager.Instance.Delete(messageViolation);
_log.Info("send successful, saving message.");
message.InternalStatus = Message.BSMDStatus.SENT;
message.SentAt = DateTime.Now;
}
DBManager.Instance.Save(message);
}
catch (Exception ex)
{
_log.ErrorFormat("SENDING message {0}: {1}", message.Id.ToString(), ex.Message);
} }
} }
} }

View File

@ -27,7 +27,7 @@ namespace bsmd.ReportGenerator
#region create document #region create document
public static Document CreateDocument(string title, string subject, string author, public static Document CreateDocument(string title, string subject, string author,
Dictionary<string, string> coverInfos) Dictionary<string, string> coverInfos, bool isUpdate)
{ {
// Create a new MigraDoc document // Create a new MigraDoc document
Document document = new Document(); Document document = new Document();
@ -37,7 +37,7 @@ namespace bsmd.ReportGenerator
BSMDDocument.DefineStyles(document); BSMDDocument.DefineStyles(document);
BSMDDocument.DefineCover(document, coverInfos); BSMDDocument.DefineCover(document, coverInfos, isUpdate);
BSMDDocument.DefineContentSection(document, Orientation.Portrait, true); BSMDDocument.DefineContentSection(document, Orientation.Portrait, true);
//TableOfContents.DefineTableOfContents(document); //TableOfContents.DefineTableOfContents(document);
@ -137,7 +137,7 @@ namespace bsmd.ReportGenerator
/// <summary> /// <summary>
/// Defines the cover page. /// Defines the cover page.
/// </summary> /// </summary>
public static void DefineCover(Document document, Dictionary<string, string> coverInfos) public static void DefineCover(Document document, Dictionary<string, string> coverInfos, bool isUpdate)
{ {
Section section = document.AddSection(); Section section = document.AddSection();
@ -147,7 +147,11 @@ namespace bsmd.ReportGenerator
Image image = section.AddImage(Properties.Settings.Default.LogoPath); Image image = section.AddImage(Properties.Settings.Default.LogoPath);
image.Width = "3cm"; image.Width = "3cm";
paragraph = section.AddParagraph("EU-NOAD incoming data receipt"); if (isUpdate)
section.AddParagraph("EU-NOAD data UPDATE");
else
paragraph = section.AddParagraph("EU-NOAD incoming data receipt");
paragraph.Format.Font.Size = 16; paragraph.Format.Font.Size = 16;
paragraph.Format.Font.Color = Colors.DarkRed; paragraph.Format.Font.Color = Colors.DarkRed;
paragraph.Format.SpaceBefore = Unit.FromCentimeter(4); paragraph.Format.SpaceBefore = Unit.FromCentimeter(4);

View File

@ -60,93 +60,12 @@ namespace bsmd.ReportGenerator
{ {
// load all messages with report flag set // load all messages with report flag set
List<MessageCore> reportCores = DBManager.Instance.GetMessageCoresByReportStatus(MessageCore.ReportStatusEnum.COMPLETE); List<MessageCore> reportCores = DBManager.Instance.GetMessageCoresByReportStatus(MessageCore.ReportStatusEnum.COMPLETE);
reportCores.AddRange(DBManager.Instance.GetMessageCoresByReportStatus(MessageCore.ReportStatusEnum.HE_REPORTTYPE));
reportCores.AddRange(DBManager.Instance.GetMessageCoresByReportStatus(MessageCore.ReportStatusEnum.HE_REVISION));
// create report documents for each of the messages // create report documents for each of the messages
foreach (MessageCore reportCore in reportCores) foreach (MessageCore reportCore in reportCores)
{ {
List<Message> messages = DBManager.Instance.GetMessagesForCore(reportCore); this.CreateReport(reportCore);
Dictionary<string, string> coverInfos = new Dictionary<string, string>();
// Schiffsname aus der STAT meldung fischen
foreach (Message msg in messages)
{
if (msg.MessageNotificationClass == Message.NotificationClass.STAT)
{
if (msg.Elements.Count > 0)
{
STAT stat = msg.Elements[0] as STAT;
if (stat != null)
{
coverInfos.Add("Ship", stat.ShipName);
}
}
}
}
coverInfos.Add("IMO", reportCore.IMO);
DateTime eta = reportCore.ETA ?? (reportCore.ETAKielCanal ?? new DateTime(0));
coverInfos.Add("ETA", eta.ToShortDateString());
coverInfos.Add("Port", reportCore.Portname);
coverInfos.Add("", "");
if (reportCore.Customer != null)
{
coverInfos.Add("Name", reportCore.Customer.Name);
coverInfos.Add("Contact first name", reportCore.Customer.ContactFirstName);
coverInfos.Add("Contact last name", reportCore.Customer.ContactLastName);
coverInfos.Add("Customer number", reportCore.Customer.CustomerNumber);
coverInfos.Add("Street", reportCore.Customer.StreetAndNumber);
coverInfos.Add("Postal code", reportCore.Customer.PostalCode);
coverInfos.Add("City", reportCore.Customer.City);
coverInfos.Add("Country", reportCore.Customer.Country);
coverInfos.Add("Phone", reportCore.Customer.Phone);
coverInfos.Add("E-Mail", reportCore.Customer.Email);
}
Document migraDocument = BSMDDocument.CreateDocument(
string.Format("NSW Eingangsdatenübersicht für IMO {0}, ETA {1}", reportCore.IMO, reportCore.ETA),
"NSW Meldung",
Properties.Settings.Default.ReportAuthor, coverInfos);
// print header area (with message core data)
// print messages in subsequent tables
foreach (Message message in messages)
{
BSMDDocument.AddNSWMessageParagraph(migraDocument, message);
}
// prepare and send E-Mail with generated attachment
string fullPath = string.Format("{0}\\{1}.pdf", Properties.Settings.Default.OutputDirectory,
reportCore.Id);
BSMDDocument.RenderDocument(migraDocument, fullPath);
_log.InfoFormat("Document created for MessageCoreId {0}, IMO {1}", reportCore.Id, reportCore.IMO);
string subject = string.Format("NSW message report for {0}", reportCore.IMO);
List<string> attachments = new List<string>();
attachments.Add(fullPath);
// 10.7.15: Check PAS/CREW messages to create extra csv files and add them as well
Message pas = messages.Find(x => x.MessageNotificationClass == Message.NotificationClass.PAS);
string passengerCSV = null;
if ((pas != null) && (pas.Elements.Count > 0))
{
passengerCSV = CrewPasHelper.CreateCSV(pas);
attachments.Add(passengerCSV);
}
Message crew = messages.Find(x => x.MessageNotificationClass == Message.NotificationClass.CREW);
string crewCSV = null;
if ((crew != null) && (crew.Elements.Count > 0))
{
crewCSV = CrewPasHelper.CreateCSV(crew);
attachments.Add(crewCSV);
}
BSMDMail.SendNSWReportWithAttachments(subject, attachments);
// reset report status
reportCore.ReportStatus = MessageCore.ReportStatusEnum.NONE;
DBManager.Instance.Save(reportCore);
if (passengerCSV != null) File.Delete(passengerCSV);
if (crewCSV != null) File.Delete(crewCSV);
} }
DBManager.Instance.Disconnect(); DBManager.Instance.Disconnect();
@ -178,5 +97,103 @@ namespace bsmd.ReportGenerator
{ {
this._timer_Elapsed(null, null); this._timer_Elapsed(null, null);
} }
#region create and send report
private void CreateReport(MessageCore reportCore)
{
List<Message> messages = DBManager.Instance.GetMessagesForCore(reportCore);
Dictionary<string, string> coverInfos = new Dictionary<string, string>();
bool isReportUpdate = reportCore.ReportStatus != MessageCore.ReportStatusEnum.COMPLETE;
coverInfos.Add("Type", reportCore.HerbergReportType);
// Schiffsname aus der STAT meldung fischen
foreach (Message msg in messages)
{
if (msg.MessageNotificationClass == Message.NotificationClass.STAT)
{
if (msg.Elements.Count > 0)
{
STAT stat = msg.Elements[0] as STAT;
if (stat != null)
{
coverInfos.Add("Ship", stat.ShipName);
}
}
}
}
coverInfos.Add("IMO", reportCore.IMO);
DateTime eta = reportCore.ETA ?? (reportCore.ETAKielCanal ?? new DateTime(0));
coverInfos.Add("ETA", eta.ToShortDateString());
coverInfos.Add("Port", reportCore.Portname);
coverInfos.Add("", "");
if (reportCore.Customer != null)
{
coverInfos.Add("Name", reportCore.Customer.Name);
coverInfos.Add("Contact first name", reportCore.Customer.ContactFirstName);
coverInfos.Add("Contact last name", reportCore.Customer.ContactLastName);
coverInfos.Add("Customer number", reportCore.Customer.CustomerNumber);
coverInfos.Add("Street", reportCore.Customer.StreetAndNumber);
coverInfos.Add("Postal code", reportCore.Customer.PostalCode);
coverInfos.Add("City", reportCore.Customer.City);
coverInfos.Add("Country", reportCore.Customer.Country);
coverInfos.Add("Phone", reportCore.Customer.Phone);
coverInfos.Add("E-Mail", reportCore.Customer.Email);
}
// create document and print header area (with message core data)
Document migraDocument = BSMDDocument.CreateDocument(
string.Format("NSW Eingangsdatenübersicht für IMO {0}, ETA {1}", reportCore.IMO, reportCore.ETA),
"NSW Meldung",
Properties.Settings.Default.ReportAuthor,
coverInfos,
isReportUpdate);
// print messages in subsequent tables
foreach (Message message in messages)
{
BSMDDocument.AddNSWMessageParagraph(migraDocument, message);
}
// prepare and send E-Mail with generated attachment
string fullPath = string.Format("{0}\\{1}.pdf", Properties.Settings.Default.OutputDirectory,
reportCore.Id);
BSMDDocument.RenderDocument(migraDocument, fullPath);
_log.InfoFormat("Document created for MessageCoreId {0}, IMO {1}", reportCore.Id, reportCore.IMO);
string subject = string.Format("NEW EU-NOAD message IMO {0}", reportCore.IMO);
if(isReportUpdate)
subject = string.Format("UPDATE EU-NOAD message IMO {0}", reportCore.IMO);
List<string> attachments = new List<string>();
attachments.Add(fullPath);
// 10.7.15: Check PAS/CREW messages to create extra csv files and add them as well
Message pas = messages.Find(x => x.MessageNotificationClass == Message.NotificationClass.PAS);
string passengerCSV = null;
if ((pas != null) && (pas.Elements.Count > 0))
{
passengerCSV = CrewPasHelper.CreateCSV(pas);
attachments.Add(passengerCSV);
}
Message crew = messages.Find(x => x.MessageNotificationClass == Message.NotificationClass.CREW);
string crewCSV = null;
if ((crew != null) && (crew.Elements.Count > 0))
{
crewCSV = CrewPasHelper.CreateCSV(crew);
attachments.Add(crewCSV);
}
BSMDMail.SendNSWReportWithAttachments(subject, attachments);
// reset report status
reportCore.ReportStatus = MessageCore.ReportStatusEnum.NONE;
DBManager.Instance.Save(reportCore);
if (passengerCSV != null) File.Delete(passengerCSV);
if (crewCSV != null) File.Delete(crewCSV);
}
#endregion
} }
} }

View File

@ -18,11 +18,16 @@ namespace bsmd.database
{ {
public class DBManager public class DBManager
{ {
#region Fields
private SqlConnection _con; private SqlConnection _con;
private static DBManager _instance; private static DBManager _instance;
private static ILog _log = LogManager.GetLogger(typeof(DBManager)); private static ILog _log = LogManager.GetLogger(typeof(DBManager));
private static Dictionary<Guid, ReportingParty> allReportingParties; private static Dictionary<Guid, ReportingParty> allReportingParties;
#endregion
#region Properties #region Properties
public static DBManager Instance public static DBManager Instance
@ -66,6 +71,7 @@ namespace bsmd.database
#region public helper funcs #region public helper funcs
/*
public Dictionary<Guid, MessageCore> GetToSendMessageCoreList() public Dictionary<Guid, MessageCore> GetToSendMessageCoreList()
{ {
List<MessageCore> toSendList = this.GetMessageCoresByStatus(MessageCore.BSMDStatus.TOSEND); List<MessageCore> toSendList = this.GetMessageCoresByStatus(MessageCore.BSMDStatus.TOSEND);
@ -75,6 +81,8 @@ namespace bsmd.database
return result; return result;
} }
*/
public List<MessageCore> GetMessageCoresByStatus(MessageCore.BSMDStatus status) public List<MessageCore> GetMessageCoresByStatus(MessageCore.BSMDStatus status)
{ {
MessageCore aMessageCore = new MessageCore(); MessageCore aMessageCore = new MessageCore();
@ -85,7 +93,10 @@ namespace bsmd.database
List<DatabaseEntity> cores = aMessageCore.LoadList(reader); List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
List<MessageCore> result = new List<MessageCore>(); List<MessageCore> result = new List<MessageCore>();
foreach (MessageCore core in cores) foreach (MessageCore core in cores)
{
this.LoadCustomer(core);
result.Add(core); result.Add(core);
}
return result; return result;
} }
@ -100,19 +111,8 @@ namespace bsmd.database
List<MessageCore> result = new List<MessageCore>(); List<MessageCore> result = new List<MessageCore>();
foreach (MessageCore core in cores) foreach (MessageCore core in cores)
{ {
this.LoadCustomer(core);
result.Add(core); result.Add(core);
if (core.CustomerId.HasValue)
{
Customer c = new Customer();
SqlCommand cCmd = new SqlCommand();
c.PrepareLoadCommand(cCmd, Message.LoadFilter.BY_ID, core.CustomerId.Value);
reader = this.PerformCommand(cCmd);
List<DatabaseEntity> customers = c.LoadList(reader);
if (customers.Count > 0)
core.Customer = customers[0] as Customer;
}
} }
return result; return result;
} }
@ -124,6 +124,7 @@ namespace bsmd.database
/// <returns></returns> /// <returns></returns>
public MessageCore GetHerbergFormMessage(Guid herbergFormGuid) public MessageCore GetHerbergFormMessage(Guid herbergFormGuid)
{ {
MessageCore result = null;
MessageCore aMessageCore = new MessageCore(); MessageCore aMessageCore = new MessageCore();
SqlCommand cmd = new SqlCommand(); SqlCommand cmd = new SqlCommand();
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.HERBERG_FORMGUID, herbergFormGuid); aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.HERBERG_FORMGUID, herbergFormGuid);
@ -132,9 +133,12 @@ namespace bsmd.database
List<DatabaseEntity> cores = aMessageCore.LoadList(reader); List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
if (cores.Count > 1) _log.WarnFormat("Herberg form message: {0} cores found for guid {1}", if (cores.Count > 1) _log.WarnFormat("Herberg form message: {0} cores found for guid {1}",
cores.Count, herbergFormGuid); cores.Count, herbergFormGuid);
if(cores.Count > 0) if (cores.Count > 0)
return (MessageCore) cores[0]; {
return null; result = (MessageCore)cores[0];
this.LoadCustomer(result);
}
return result;
} }
public List<Message> GetMessagesForCore(MessageCore core) public List<Message> GetMessagesForCore(MessageCore core)
@ -638,6 +642,20 @@ namespace bsmd.database
message.ViolationList.Add(violation); message.ViolationList.Add(violation);
} }
internal void LoadCustomer(MessageCore core)
{
if (core.CustomerId.HasValue)
{
Customer c = new Customer();
SqlCommand cCmd = new SqlCommand();
c.PrepareLoadCommand(cCmd, Message.LoadFilter.BY_ID, core.CustomerId.Value);
SqlDataReader reader = this.PerformCommand(cCmd);
List<DatabaseEntity> customers = c.LoadList(reader);
if (customers.Count > 0)
core.Customer = customers[0] as Customer;
}
}
#region DB access methods #region DB access methods
internal SqlDataReader PerformCommand(SqlCommand cmd) internal SqlDataReader PerformCommand(SqlCommand cmd)
@ -645,7 +663,11 @@ namespace bsmd.database
try try
{ {
cmd.Connection = this._con; cmd.Connection = this._con;
Stopwatch sw = new Stopwatch();
sw.Start();
SqlDataReader reader = cmd.ExecuteReader(); SqlDataReader reader = cmd.ExecuteReader();
sw.Stop();
_log.DebugFormat("{1}ms: {0}", cmd.CommandText, sw.ElapsedMilliseconds);
return reader; return reader;
} }
catch (SqlException ex) catch (SqlException ex)

View File

@ -13,6 +13,9 @@ namespace bsmd.database
/// </summary> /// </summary>
public class Message : DatabaseEntity, ISublistContainer public class Message : DatabaseEntity, ISublistContainer
{ {
#region Fields
private Guid? messageCoreId; private Guid? messageCoreId;
private Guid? reportingPartyId; private Guid? reportingPartyId;
private ReportingParty reportingParty; private ReportingParty reportingParty;
@ -21,6 +24,8 @@ namespace bsmd.database
private List<MessageViolation> violationList = new List<MessageViolation>(); private List<MessageViolation> violationList = new List<MessageViolation>();
private List<DatabaseEntity> elements = new List<DatabaseEntity>(); private List<DatabaseEntity> elements = new List<DatabaseEntity>();
#endregion
#region Enumerations #region Enumerations
/// <summary> /// <summary>
@ -90,11 +95,15 @@ namespace bsmd.database
#endregion #endregion
#region Construction
public Message() public Message()
{ {
this.tablename = "[dbo].[MessageHeader]"; this.tablename = "[dbo].[MessageHeader]";
} }
#endregion
#region Properties #region Properties
/// <summary> /// <summary>

View File

@ -141,6 +141,7 @@ namespace bsmd.database
scmd.Parameters.AddWithNullableValue("@P21", this.HerbergRevDate); scmd.Parameters.AddWithNullableValue("@P21", this.HerbergRevDate);
scmd.Parameters.AddWithValue("@P22", this.ReportStatus); scmd.Parameters.AddWithValue("@P22", this.ReportStatus);
scmd.Parameters.AddWithNullableValue("@P23", this.SietasSheetVersion); scmd.Parameters.AddWithNullableValue("@P23", this.SietasSheetVersion);
scmd.Parameters.AddWithValue("@P24", this.Incoming ? 1 : 0);
if (this.IsNew) if (this.IsNew)
{ {
@ -149,9 +150,9 @@ namespace bsmd.database
string query = string.Format("INSERT INTO {0} (Id, VisitId, TransitId, IMO, ENI, PoC, Portname, ETA, CustomerId, " + string query = string.Format("INSERT INTO {0} (Id, VisitId, TransitId, IMO, ENI, PoC, Portname, ETA, CustomerId, " +
"Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, HerbergFormGuid, " + "Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, HerbergFormGuid, " +
"HerbergFormTemplateGuid, HerbergReportType, HerbergEmailcontactReportingVessel, HerbergEmail24HrsContact, " + "HerbergFormTemplateGuid, HerbergReportType, HerbergEmailcontactReportingVessel, HerbergEmail24HrsContact, " +
"ETAKielCanal, HerbergRevDate, ReportStatus, SietasSheetVersion) VALUES " + "ETAKielCanal, HerbergRevDate, ReportStatus, SietasSheetVersion, Incoming) VALUES " +
"(@ID, @P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16, @P17, " + "(@ID, @P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16, @P17, " +
"@P18, @P19, @P20, @P21, @P22, @P23)", "@P18, @P19, @P20, @P21, @P22, @P23, @P24)",
this.Tablename); this.Tablename);
scmd.CommandText = query; scmd.CommandText = query;
} }
@ -163,7 +164,7 @@ namespace bsmd.database
"Wetris_zz_56_datensatz_id = @P12, BSMDStatus = @P13, InitialHIS = @P14, HerbergFormGuid = @P15, " + "Wetris_zz_56_datensatz_id = @P12, BSMDStatus = @P13, InitialHIS = @P14, HerbergFormGuid = @P15, " +
"HerbergFormTemplateGuid = @P16, HerbergReportType = @P17, HerbergEmailContactReportingVessel = @P18, " + "HerbergFormTemplateGuid = @P16, HerbergReportType = @P17, HerbergEmailContactReportingVessel = @P18, " +
"HerbergEmail24HrsContact = @P19, ETAKielCanal = @P20, HerbergRevDate = @P21, ReportStatus = @P22, " + "HerbergEmail24HrsContact = @P19, ETAKielCanal = @P20, HerbergRevDate = @P21, ReportStatus = @P22, " +
"SietasSheetVersion = @P23 WHERE Id = @ID", this.Tablename); "SietasSheetVersion = @P23, Incoming = @P24 WHERE Id = @ID", this.Tablename);
scmd.CommandText = query; scmd.CommandText = query;
} }
} }
@ -173,7 +174,7 @@ namespace bsmd.database
string query = string.Format("SELECT Id, VisitId, TransitId, IMO, ENI, PoC, Portname, " + string query = string.Format("SELECT Id, VisitId, TransitId, IMO, ENI, PoC, Portname, " +
"ETA, CustomerId, Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, " + "ETA, CustomerId, Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, " +
"HerbergFormGuid, HerbergFormTemplateGuid, HerbergReportType, HerbergEmailContactReportingVessel, " + "HerbergFormGuid, HerbergFormTemplateGuid, HerbergReportType, HerbergEmailContactReportingVessel, " +
"HerbergEmail24HrsContact, ETAKielCanal, HerbergRevDate, ReportStatus, SietasSheetVersion FROM {0} ", "HerbergEmail24HrsContact, ETAKielCanal, HerbergRevDate, ReportStatus, SietasSheetVersion, Incoming FROM {0} ",
this.Tablename); this.Tablename);
switch (filter) switch (filter)
@ -254,6 +255,7 @@ namespace bsmd.database
if (!reader.IsDBNull(21)) core.HerbergRevDate = reader.GetDateTime(21); if (!reader.IsDBNull(21)) core.HerbergRevDate = reader.GetDateTime(21);
if (!reader.IsDBNull(22)) core.ReportStatus = (ReportStatusEnum) Enum.ToObject(typeof(ReportStatusEnum), reader.GetByte(22)); if (!reader.IsDBNull(22)) core.ReportStatus = (ReportStatusEnum) Enum.ToObject(typeof(ReportStatusEnum), reader.GetByte(22));
if (!reader.IsDBNull(23)) core.SietasSheetVersion = reader.GetString(23); if (!reader.IsDBNull(23)) core.SietasSheetVersion = reader.GetString(23);
if (!reader.IsDBNull(24)) core.Incoming = reader.GetBoolean(24);
result.Add(core); result.Add(core);
} }

View File

@ -2,6 +2,6 @@
[assembly: AssemblyCompany("Informatikbüro Daniel Schick")] [assembly: AssemblyCompany("Informatikbüro Daniel Schick")]
[assembly: AssemblyProduct("BSMD NSW interface")] [assembly: AssemblyProduct("BSMD NSW interface")]
[assembly: AssemblyInformationalVersion("2.0.0")] [assembly: AssemblyInformationalVersion("2.1.0")]
[assembly: AssemblyCopyright("Copyright © 2014-2015 Informatikbüro Daniel Schick. All rights reserved.")] [assembly: AssemblyCopyright("Copyright © 2014-2015 Informatikbüro Daniel Schick. All rights reserved.")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]

View File

@ -4,6 +4,6 @@
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0.*")] [assembly: AssemblyVersion("2.1.0.*")]
// wenn das nicht auskommentiert wird erhalten wir eine Warnung // wenn das nicht auskommentiert wird erhalten wir eine Warnung
// [assembly: AssemblyFileVersion("1.0.0.*")] // [assembly: AssemblyFileVersion("1.0.0.*")]

View File

@ -74,7 +74,7 @@ namespace bsmd.herberg.FormService
if ((aMessageCore.HerbergReportType != formData.value) && if ((aMessageCore.HerbergReportType != formData.value) &&
(aMessageCore.ReportStatus != MessageCore.ReportStatusEnum.COMPLETE)) (aMessageCore.ReportStatus != MessageCore.ReportStatusEnum.COMPLETE))
aMessageCore.ReportStatus = MessageCore.ReportStatusEnum.HE_REPORTTYPE; aMessageCore.ReportStatus = MessageCore.ReportStatusEnum.HE_REPORTTYPE; // neuer Report-Type!
aMessageCore.HerbergReportType = formData.value; aMessageCore.HerbergReportType = formData.value;
if (aMessageCore.HerbergReportType.Equals("Pre-Departure Notification Update") || if (aMessageCore.HerbergReportType.Equals("Pre-Departure Notification Update") ||

File diff suppressed because it is too large Load Diff

View File

@ -59,6 +59,11 @@
</Compile> </Compile>
<Compile Include="his-nord.cs" /> <Compile Include="his-nord.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="Request.cs" /> <Compile Include="Request.cs" />
<Compile Include="transmitter.cs" /> <Compile Include="transmitter.cs" />
</ItemGroup> </ItemGroup>
@ -68,6 +73,16 @@
<Name>bsmd.database</Name> <Name>bsmd.database</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -0,0 +1,161 @@
Spezialitäten bei HIS Nord (Stand 25.7.15)
- "transmitter" wird verwendet um die erzeugten Daten an D&D zu schicken
- eine Rückmeldung erfolgt direkt über das Transmitter-Tool (Verstoß gegen XSD) oder über Email an den Meldenden, das passiert
bei "Highlevel" Fehlern aus dem NSW (Error/Violation).
- Da ein Haufen Pflichtangaben notwendig sind habe ich mich entschlossen, bei D&D den Message-Core immer komplett zu schicken
Sollen die doch das ganze auseinanderflöhen.
Ursprüngliche Mail von Deffke:
- Generell: Ist es möglich nur Teilnachrichten zu verschicken oder erwartet die Schnittstelle eine komplette Anmeldung?
à Die Schnittstelle erwartet bisher folgende Pflichtangaben, damit ein reibungsloser Ablauf funktioniert:
· Angabe der VISITID, TRANSITID oder ein eindeutiger CODE (können Sie selbst festlegen), zu dem alle Nachrichten gesandt bzw. zusammengefasst werden können
· Angabe der Melderdaten (OWNER_SENDER)
o Hier schlagen wir Ihnen folgende Handhabung vor:
§ In „name_short“ und „name_long“ werden die Firmenkurz- und langnamen eingetragen von dem jeweiligen Makler, Reederei etc.
· Auf dieser Basis können wir in unserem System eine eindeutige Zuordnung erreichen
· Deshalb besteht hier Abstimmungsbedarf hinsichtlich der Firmen für die Sie melden möchten.
o Zum Beispiel in unserem System ist Baltimar wie folgt gespeichert:
§ name_short: Baltimar
§ name_long: Baltimar Schiffahrt u. Transport GmbH
§ In der „address“ die Firmenadresse, z.B. von Baltimar
§ Im „contact“ bitte folgende Vorgaben berücksichtigen
· name: BSMD
· firstname: <Name eines zentral Verantwortlichen>
· phone: <Nummer unter der zentral jemand für Rückfragen erreichbar ist>
· fax:<Nummer, die zentral erreichbar ist>
· email: <Mail-Adresse, die zentral erreichbar ist>
· Angabe der notwendigen Schiffsstammdaten
· Angabe IMPORT, EXPORT, TRANSIT
o Sind Pflicht, da somit ermittelt werden kann, ob es sich um einen Eingang bzw. Ausgang für den Hafen bedeutet
o Transit ist für den Nord-Ostsee-Kanal (NOK) vorgesehen
· Angabe PERSONSONBOARD
o Zur Zeit noch Pflicht (historisch bedingt), könnten wir auf Wunsch auch optional machen
· Alle anderen Meldetypen und Angaben, die weiter oben nicht aufgezählt wurden, sind optional, d.h. können als Teilnachrichten gesandt werden
- Mit welchen Werten werden folgende Felder in nsw belegt:
- date_registration (aktuelle Zeit?)
· Dieser Wert wird bisher nicht für das Senden ans NSW benötigt
· Es dient lediglich der Auswertung, in welcher Reihenfolge die Meldung bzw. XML-Files erzeugt und abgearbeitet wurden
- message_sender
· Hier bitte BSMD eintragen
· Ans NSW werden aber die Werte aus dem OWNER_SENDER verwendet, speziell aus CONTACT
- message_recipient
· Hier bitte HIS-NORD eintragen
- document_reference (kann das verwendet werden um bei einer Antwort eine Rückwärts-Referenz auszuwerten?)
· Auf welcher Ebene erwarten Sie eine Rückwärts-Referenz?
o Beim Transmitter erhalten Sie die Fehlerausgabe der Schemavalidierung und dort wird der Dateiname als Referenz verwendet
o Falls was beim Import in unsere Datenbank bzw. beim Senden an das NSW schief geht und es an den gesandten XML-Files liegt, dann werden Mails an die Mail-Adresse aus CONTACT (OWNER_SENDER) gesendet
§ Über diesen Weg könnten auch angeforderte VISITIDs etc. gesendet werden, falls erwünscht
- Gibt es vom NSW Standard abweichende / ergänzende Felder und sind diese dokumentiert?
· Ich habe Ihnen hierzu die NSW-Spezifikation im Anhang zur Verfügung gestellt
· Grundsätzlich orientiert sich das an Ihnen überreichte XML-Schema an diesen Vorgaben mit folgenden Abweichungen
Meldetypen
Abweichungen
NOA_NOD
In IMPORT, EXPORT, TRANSIT vorkommend,
wobei zusätzlich Hafengebiet oder GISIS-Code gemeldet werden kann, ansonsten wird das Standard-Hafengebiet genommen, z.B. ÜSH für Überseehafen Rostock
ATA/ATD
In IMPORT, EXPORT
POBA/POBD
In PersonsOnBoard, je nach IMPORT, EXPORT wird entsprechender Ein-/Ausgang gemeldet
Name
In NameOfMaster
TIEFA/TIEFD
In Draught_DMT, je nach IMPORT, EXPORT wird entsprechender Ein-/Ausgang gemeldet
BKRA/BKRD
In BunkerFuelList, je nach IMPORT, EXPORT wird entsprechender Ein-/Ausgang gemeldet
STAT
In vessel
LADG
In GeneralCargo->LoadUnit
HAZA/HAZD
In GeneralCargo->LoadUnit, je nach IMPORT, EXPORT wird entsprechender Ein-/Ausgang gemeldet
SEC
In SEC
INFO
In Info
SERV
In SERV
PRE72H
In Pre72H
MDH
In MDH
WAS
In Waste
CREW/PAS/BPOL
In CREW/PAS/BPOL
TOWA/TOWD
In TOWS, je nach IMPORT, EXPORT wird entsprechender Ein-/Ausgang gemeldet
Für die Schemaänderung mit dem Hafengebiet erhalten Sie ein erneute Version des XML-Schemas.
· Unter PortOfCall (ComplexType: portofcallhazmat) kann zusätzlich das Hafengebiet/GISISCode zugeordnet werden, damit eine saubere Zuordnung im System erfolgen kann, ansonsten werden Standard-Hafengebiete verwendet

View File

@ -9,6 +9,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Xml; using System.Xml;
@ -20,6 +21,38 @@ namespace bsmd.hisnord
public class transmitter public class transmitter
{ {
private static ILog _log = LogManager.GetLogger(typeof(transmitter)); private static ILog _log = LogManager.GetLogger(typeof(transmitter));
/*
public static result UseHisNordTransmitter(string filenameFullPath)
{
Process process = new Process();
process.StartInfo.FileName = Properties.Settings.Default.Transmitter;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = false;
// der Transmitter schickt alles was im Ausgabe-Verzeichnis ist
// damit das gut geht schicken wir die Nachrichten einzeln und arbeiten jeweils das
// Ergebnis ab
process.Start();
int timeout = Properties.Settings.Default.BatchTimeoutMins * 1000 * 60; // convert to ms
process.WaitForExit((timeout == 0) ? int.MaxValue : timeout);
_log.Error(process.StandardError.ReadToEnd());
process.WaitForExit();
_log.Info(process.StandardOutput.ReadToEnd());
process.WaitForExit();
// now we should read the response message...
string resultFilename = string.Format("{0}.result.xml", Path.GetFileName(filenameFullPath));
string resultFullPath = Path.Combine(Properties.Settings.Default.ResultDir, resultFilename);
return result.ReadResult(resultFullPath);
}
*/
/// <summary> /// <summary>
/// class to read transmitter result xml files /// class to read transmitter result xml files
/// </summary> /// </summary>
@ -53,5 +86,7 @@ namespace bsmd.hisnord
} }
} }
} }
} }