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
MODE = ONCE
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;
}
bool sendSucceeded;
if (DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString))
{
@ -69,104 +71,111 @@ namespace SendNSWMessageService
foreach (MessageCore core in coresMarkedForSending)
{
List<Message> messages = DBManager.Instance.GetMessagesForCore(core);
List<Message> toSendMessageList = new List<Message>();
if ((core.IsTransit && core.TransitId.IsNullOrEmpty()) ||
(!core.IsTransit && core.VisitId.IsNullOrEmpty()))
if (core.InitialHIS == Message.NSWProvider.DUDR)
{
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) ||
(message.MessageNotificationClass == Message.NotificationClass.TRANSIT))
foreach (Message message in messages)
{
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.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)
foreach (Message message in toSendMessageList)
{
if ((message.InternalStatus == Message.BSMDStatus.UNDEFINED) ||
(message.InternalStatus == Message.BSMDStatus.PREPARE) ||
(message.InternalStatus == Message.BSMDStatus.TOSEND))
try
{
if (message.HIS == Message.NSWProvider.UNDEFINED)
message.HIS = core.InitialHIS;
_log.InfoFormat("Sending {0} message to {1}",
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);
}
}
}
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)
catch (Exception ex)
{
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;
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;
_log.ErrorFormat("SENDING message {0}: {1}", message.Id.ToString(), ex.Message);
}
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
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
Document document = new Document();
@ -37,7 +37,7 @@ namespace bsmd.ReportGenerator
BSMDDocument.DefineStyles(document);
BSMDDocument.DefineCover(document, coverInfos);
BSMDDocument.DefineCover(document, coverInfos, isUpdate);
BSMDDocument.DefineContentSection(document, Orientation.Portrait, true);
//TableOfContents.DefineTableOfContents(document);
@ -137,7 +137,7 @@ namespace bsmd.ReportGenerator
/// <summary>
/// Defines the cover page.
/// </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();
@ -147,7 +147,11 @@ namespace bsmd.ReportGenerator
Image image = section.AddImage(Properties.Settings.Default.LogoPath);
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.Color = Colors.DarkRed;
paragraph.Format.SpaceBefore = Unit.FromCentimeter(4);

View File

@ -60,93 +60,12 @@ namespace bsmd.ReportGenerator
{
// load all messages with report flag set
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
foreach (MessageCore reportCore in reportCores)
{
List<Message> messages = DBManager.Instance.GetMessagesForCore(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);
this.CreateReport(reportCore);
}
DBManager.Instance.Disconnect();
@ -178,5 +97,103 @@ namespace bsmd.ReportGenerator
{
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
{
#region Fields
private SqlConnection _con;
private static DBManager _instance;
private static ILog _log = LogManager.GetLogger(typeof(DBManager));
private static Dictionary<Guid, ReportingParty> allReportingParties;
#endregion
#region Properties
public static DBManager Instance
@ -66,6 +71,7 @@ namespace bsmd.database
#region public helper funcs
/*
public Dictionary<Guid, MessageCore> GetToSendMessageCoreList()
{
List<MessageCore> toSendList = this.GetMessageCoresByStatus(MessageCore.BSMDStatus.TOSEND);
@ -75,6 +81,8 @@ namespace bsmd.database
return result;
}
*/
public List<MessageCore> GetMessageCoresByStatus(MessageCore.BSMDStatus status)
{
MessageCore aMessageCore = new MessageCore();
@ -85,7 +93,10 @@ namespace bsmd.database
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
List<MessageCore> result = new List<MessageCore>();
foreach (MessageCore core in cores)
{
this.LoadCustomer(core);
result.Add(core);
}
return result;
}
@ -100,19 +111,8 @@ namespace bsmd.database
List<MessageCore> result = new List<MessageCore>();
foreach (MessageCore core in cores)
{
this.LoadCustomer(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;
}
@ -124,6 +124,7 @@ namespace bsmd.database
/// <returns></returns>
public MessageCore GetHerbergFormMessage(Guid herbergFormGuid)
{
MessageCore result = null;
MessageCore aMessageCore = new MessageCore();
SqlCommand cmd = new SqlCommand();
aMessageCore.PrepareLoadCommand(cmd, Message.LoadFilter.HERBERG_FORMGUID, herbergFormGuid);
@ -132,9 +133,12 @@ namespace bsmd.database
List<DatabaseEntity> cores = aMessageCore.LoadList(reader);
if (cores.Count > 1) _log.WarnFormat("Herberg form message: {0} cores found for guid {1}",
cores.Count, herbergFormGuid);
if(cores.Count > 0)
return (MessageCore) cores[0];
return null;
if (cores.Count > 0)
{
result = (MessageCore)cores[0];
this.LoadCustomer(result);
}
return result;
}
public List<Message> GetMessagesForCore(MessageCore core)
@ -638,6 +642,20 @@ namespace bsmd.database
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
internal SqlDataReader PerformCommand(SqlCommand cmd)
@ -645,7 +663,11 @@ namespace bsmd.database
try
{
cmd.Connection = this._con;
Stopwatch sw = new Stopwatch();
sw.Start();
SqlDataReader reader = cmd.ExecuteReader();
sw.Stop();
_log.DebugFormat("{1}ms: {0}", cmd.CommandText, sw.ElapsedMilliseconds);
return reader;
}
catch (SqlException ex)

View File

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

View File

@ -141,6 +141,7 @@ namespace bsmd.database
scmd.Parameters.AddWithNullableValue("@P21", this.HerbergRevDate);
scmd.Parameters.AddWithValue("@P22", this.ReportStatus);
scmd.Parameters.AddWithNullableValue("@P23", this.SietasSheetVersion);
scmd.Parameters.AddWithValue("@P24", this.Incoming ? 1 : 0);
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, " +
"Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, HerbergFormGuid, " +
"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, " +
"@P18, @P19, @P20, @P21, @P22, @P23)",
"@P18, @P19, @P20, @P21, @P22, @P23, @P24)",
this.Tablename);
scmd.CommandText = query;
}
@ -163,7 +164,7 @@ namespace bsmd.database
"Wetris_zz_56_datensatz_id = @P12, BSMDStatus = @P13, InitialHIS = @P14, HerbergFormGuid = @P15, " +
"HerbergFormTemplateGuid = @P16, HerbergReportType = @P17, HerbergEmailContactReportingVessel = @P18, " +
"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;
}
}
@ -173,7 +174,7 @@ namespace bsmd.database
string query = string.Format("SELECT Id, VisitId, TransitId, IMO, ENI, PoC, Portname, " +
"ETA, CustomerId, Previous, Next, IsTransit, Wetris_zz_56_datensatz_id, BSMDStatus, InitialHIS, " +
"HerbergFormGuid, HerbergFormTemplateGuid, HerbergReportType, HerbergEmailContactReportingVessel, " +
"HerbergEmail24HrsContact, ETAKielCanal, HerbergRevDate, ReportStatus, SietasSheetVersion FROM {0} ",
"HerbergEmail24HrsContact, ETAKielCanal, HerbergRevDate, ReportStatus, SietasSheetVersion, Incoming FROM {0} ",
this.Tablename);
switch (filter)
@ -254,6 +255,7 @@ namespace bsmd.database
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(23)) core.SietasSheetVersion = reader.GetString(23);
if (!reader.IsDBNull(24)) core.Incoming = reader.GetBoolean(24);
result.Add(core);
}

View File

@ -2,6 +2,6 @@
[assembly: AssemblyCompany("Informatikbüro Daniel Schick")]
[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: AssemblyTrademark("")]

View File

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

View File

@ -74,7 +74,7 @@ namespace bsmd.herberg.FormService
if ((aMessageCore.HerbergReportType != formData.value) &&
(aMessageCore.ReportStatus != MessageCore.ReportStatusEnum.COMPLETE))
aMessageCore.ReportStatus = MessageCore.ReportStatusEnum.HE_REPORTTYPE;
aMessageCore.ReportStatus = MessageCore.ReportStatusEnum.HE_REPORTTYPE; // neuer Report-Type!
aMessageCore.HerbergReportType = formData.value;
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 Include="his-nord.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="transmitter.cs" />
</ItemGroup>
@ -68,6 +73,16 @@
<Name>bsmd.database</Name>
</ProjectReference>
</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" />
<!-- 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.

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.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
@ -20,6 +21,38 @@ namespace bsmd.hisnord
public class 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>
/// class to read transmitter result xml files
/// </summary>
@ -53,5 +86,7 @@ namespace bsmd.hisnord
}
}
}
}