407 lines
24 KiB
C#
407 lines
24 KiB
C#
// Copyright (c) 2020-present schick Informatik
|
|
// Description: Tooling zum Erzeugen von Nachrichten für dbh Interface
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Xml.Serialization;
|
|
using bsmd.database;
|
|
using log4net;
|
|
using bsmd.dbh.Request;
|
|
|
|
namespace bsmd.dbh
|
|
{
|
|
internal static class RequestUtil
|
|
{
|
|
private static readonly ILog _log = LogManager.GetLogger(typeof(RequestUtil));
|
|
|
|
public static string CreateMessageFile(MessageCore core, Message message)
|
|
{
|
|
|
|
// create output structure
|
|
try
|
|
{
|
|
Root root = new Root();
|
|
root.Version = RootVersion.Item70;
|
|
root.SourceDocumentVersion = "7.0";
|
|
root.Timestamp = DateTime.Now;
|
|
root.Sender = Properties.Settings.Default.Sender;
|
|
root.SenderReference = "N";
|
|
bsmd.database.ReportingParty reportingParty = DBManager.Instance.GetReportingPartyDict()[core.DefaultReportingPartyId.Value];
|
|
Request.ReportingParty rp = new Request.ReportingParty();
|
|
rp.RPCity = reportingParty.City;
|
|
rp.RPCountry = reportingParty.Country;
|
|
rp.RPEMail = reportingParty.EMail;
|
|
rp.RPFax = reportingParty.Fax;
|
|
rp.RPFirstName = reportingParty.FirstName;
|
|
rp.RPLastName = reportingParty.LastName;
|
|
rp.RPName = reportingParty.Name;
|
|
rp.RPPhone = reportingParty.Phone;
|
|
rp.RPPostalCode = reportingParty.PostalCode;
|
|
rp.RPStreetAndNumber = reportingParty.StreetAndNumber;
|
|
rp.RPTypeSpecified = reportingParty.ReportingPartyType.HasValue;
|
|
if (rp.RPTypeSpecified)
|
|
rp.RPType = (ReportingPartyRPType)reportingParty.ReportingPartyType.Value;
|
|
root.ReportingParty = rp;
|
|
|
|
switch (message.MessageNotificationClass)
|
|
{
|
|
|
|
#region VISIT
|
|
case Message.NotificationClass.VISIT:
|
|
root.Type = RootType.VISIT;
|
|
RootVisit rootVisit = new RootVisit();
|
|
rootVisit.PortOfCall = core.PoC;
|
|
if (core.ETA.HasValue)
|
|
rootVisit.ETAPortOfCall = core.ETA.Value;
|
|
rootVisit.ETAPortOfCall = core.ETA.Value;
|
|
if (!core.IMO.IsNullOrEmpty())
|
|
{
|
|
rootVisit.ItemElementName = ItemChoiceType.IMONumber;
|
|
rootVisit.Item = core.IMO;
|
|
}
|
|
else
|
|
{
|
|
rootVisit.ItemElementName = ItemChoiceType.ENINumber;
|
|
rootVisit.Item = core.ENI;
|
|
}
|
|
root.Item = rootVisit;
|
|
root.ItemElementName = ItemChoiceType2.Visit;
|
|
break;
|
|
#endregion
|
|
|
|
#region TRANSIT
|
|
case Message.NotificationClass.TRANSIT:
|
|
root.Type = RootType.TRANSIT;
|
|
RootTransit rootTransit = new RootTransit();
|
|
|
|
if (!core.IMO.IsNullOrEmpty())
|
|
{
|
|
rootTransit.ItemElementName = ItemChoiceType1.IMONumber;
|
|
rootTransit.Item = core.IMO;
|
|
}
|
|
else
|
|
{
|
|
rootTransit.ItemElementName = ItemChoiceType1.ENINumber;
|
|
rootTransit.Item = core.ENI;
|
|
}
|
|
if (core.ETAKielCanal.HasValue)
|
|
rootTransit.ETAKielCanal = core.ETAKielCanal.Value;
|
|
root.Item = rootTransit;
|
|
root.ItemElementName = ItemChoiceType2.Transit;
|
|
break;
|
|
#endregion
|
|
|
|
#region STAT
|
|
case Message.NotificationClass.STAT:
|
|
root.Type = RootType.DATA;
|
|
RootSTAT rootStat = new RootSTAT();
|
|
STAT stat = message.Elements[0] as STAT;
|
|
rootStat.ShipName = stat.ShipName;
|
|
rootStat.CallSign = stat.CallSign;
|
|
rootStat.MMSINumber = stat.MMSINumber;
|
|
rootStat.Flag = stat.Flag;
|
|
if (stat.LengthOverall_MTR.HasValue) rootStat.LengthOverall_MTR = Decimal.Round((decimal)(stat.LengthOverall_MTR.Value), 2);
|
|
if (stat.Beam_MTR.HasValue) rootStat.Beam_MTR = Decimal.Round((decimal)(stat.Beam_MTR.Value), 2);
|
|
if (stat.GrossTonnage.HasValue) rootStat.GrossTonnage = stat.GrossTonnage.Value;
|
|
rootStat.PortOfRegistry = stat.PortOfRegistry;
|
|
rootStat.ShipType = stat.ShipType;
|
|
|
|
if (!stat.InmarsatCallNumber.IsNullOrEmpty())
|
|
{
|
|
rootStat.InmarsatCallNumbers = stat.InmarsatCallNumber.Trim().Split('\n');
|
|
for (int i = 0; i < Math.Min(rootStat.InmarsatCallNumbers.Length, 5); i++)
|
|
rootStat.InmarsatCallNumbers[i] = rootStat.InmarsatCallNumbers[i].Trim();
|
|
}
|
|
|
|
rootStat.TransportMode = RootSTATTransportMode.Item1; // default is maritime transport!
|
|
if (!stat.TransportMode.IsNullOrEmpty() && stat.TransportMode.Equals("8"))
|
|
rootStat.TransportMode = RootSTATTransportMode.Item8;
|
|
|
|
if (!stat.ISMCompanyName.IsNullOrEmpty())
|
|
{
|
|
rootStat.ISMCompany = new RootSTATISMCompany();
|
|
rootStat.ISMCompany.ISMCompanyName = stat.ISMCompanyName;
|
|
rootStat.ISMCompany.ISMCompanyId = stat.ISMCompanyId;
|
|
rootStat.ISMCompany.ISMCompanyStreetAndNumber = stat.ISMCompanyStreetAndNumber;
|
|
rootStat.ISMCompany.ISMCompanyPostalCode = stat.ISMCompanyPostalCode;
|
|
rootStat.ISMCompany.ISMCompanyCity = stat.ISMCompanyCity;
|
|
rootStat.ISMCompany.ISMCompanyCountry = stat.ISMCompanyCountry;
|
|
}
|
|
|
|
root.Items = new object[1];
|
|
root.Items[0] = rootStat;
|
|
break;
|
|
#endregion
|
|
|
|
#region NOA_NOD
|
|
case Message.NotificationClass.NOA_NOD:
|
|
NOA_NOD noa_nod = message.Elements[0] as NOA_NOD;
|
|
RootNOA_NOD rootNOA_NOD = new RootNOA_NOD();
|
|
rootNOA_NOD.ETAToNextPortSpecified = noa_nod.ETAToNextPort.HasValue;
|
|
if(noa_nod.ETAToNextPort.HasValue)
|
|
rootNOA_NOD.ETAToNextPort = noa_nod.ETAToNextPort.Value;
|
|
rootNOA_NOD.ETDFromLastPortSpecified = noa_nod.ETDFromLastPort.HasValue;
|
|
if (noa_nod.ETDFromLastPort.HasValue)
|
|
rootNOA_NOD.ETDFromLastPort = noa_nod.ETDFromLastPort.Value;
|
|
rootNOA_NOD.LastPort = noa_nod.LastPort;
|
|
rootNOA_NOD.NextPort = noa_nod.NextPort;
|
|
List<ItemsChoiceType> choiceList = new List<ItemsChoiceType>();
|
|
List<object> choices = new List<object>();
|
|
if (message.MessageCore.IsTransit)
|
|
{
|
|
if (noa_nod.ETAToKielCanal.HasValue)
|
|
{
|
|
choiceList.Add(ItemsChoiceType.ETAToKielCanal);
|
|
choices.Add(noa_nod.ETAToKielCanal.Value.ToDBHDateString());
|
|
}
|
|
|
|
if (noa_nod.ETDFromKielCanal.HasValue)
|
|
{
|
|
choiceList.Add(ItemsChoiceType.ETDFromKielCanal);
|
|
choices.Add(noa_nod.ETDFromKielCanal.Value.ToDBHDateString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (noa_nod.ETAToPortOfCall.HasValue)
|
|
{
|
|
choiceList.Add(ItemsChoiceType.ETAToPortOfCall);
|
|
choices.Add(noa_nod.ETAToPortOfCall.Value.ToDBHDateString());
|
|
}
|
|
|
|
if (noa_nod.ETDFromPortOfCall.HasValue)
|
|
{
|
|
choiceList.Add(ItemsChoiceType.ETDFromPortOfCall);
|
|
choices.Add(noa_nod.ETDFromPortOfCall.Value.ToDBHDateString());
|
|
}
|
|
|
|
for (int i = 0; i < noa_nod.CallPurposes.Count; i++)
|
|
{
|
|
choiceList.Add(ItemsChoiceType.CallPurpose);
|
|
RootNOA_NODCallPurpose rnncp = new RootNOA_NODCallPurpose();
|
|
CallPurpose callPurpose = noa_nod.CallPurposes[i];
|
|
rnncp.CallPurposeCode = callPurpose.CallPurposeCode;
|
|
if (callPurpose.CallPurposeDescription != string.Empty)
|
|
rnncp.CallPurposeDescription = callPurpose.CallPurposeDescription;
|
|
choices.Add(rnncp);
|
|
}
|
|
}
|
|
|
|
rootNOA_NOD.Items = choices.ToArray();
|
|
rootNOA_NOD.ItemsElementName = choiceList.ToArray();
|
|
|
|
root.Items = new object[1];
|
|
root.Items[0] = rootNOA_NOD;
|
|
break;
|
|
|
|
#endregion
|
|
|
|
#region AGNT
|
|
case Message.NotificationClass.AGNT:
|
|
AGNT agnt = message.Elements[0] as AGNT;
|
|
RootAGNT rootAGNT = new RootAGNT();
|
|
rootAGNT.AgentCity = agnt.AgentCity;
|
|
rootAGNT.AgentCompanyName = agnt.AgentCompanyName;
|
|
rootAGNT.AgentCountry = agnt.AgentCountry;
|
|
rootAGNT.AgentEMail = agnt.AgentEMail;
|
|
rootAGNT.AgentFax = agnt.AgentFax;
|
|
rootAGNT.AgentFirstName = agnt.AgentFirstName;
|
|
rootAGNT.AgentLastName = agnt.AgentLastName;
|
|
rootAGNT.AgentPhone = agnt.AgentPhone;
|
|
rootAGNT.AgentPostalCode = agnt.AgentPostalCode;
|
|
rootAGNT.AgentStreetAndNumber = agnt.AgentStreetAndNumber;
|
|
root.Items = new object[1];
|
|
root.Items[0] = rootAGNT;
|
|
break;
|
|
#endregion
|
|
|
|
#region ATA
|
|
case Message.NotificationClass.ATA:
|
|
if (message.Elements[0] is ATA ata)
|
|
{
|
|
RootATA rootATA = new RootATA();
|
|
if (ata.ATAPortOfCall.HasValue)
|
|
rootATA.ATAPortOfCall = ata.ATAPortOfCall.Value;
|
|
root.Items = new object[1];
|
|
root.Items[0] = rootATA;
|
|
}
|
|
break;
|
|
#endregion
|
|
|
|
#region ATD
|
|
case Message.NotificationClass.ATD:
|
|
{
|
|
if (message.Elements[0] is ATD atd)
|
|
{
|
|
RootATD rootATD = new RootATD();
|
|
if(atd.ATDPortOfCall.HasValue)
|
|
rootATD.ATDPortOfCall = atd.ATDPortOfCall.Value;
|
|
root.Items = new object[1];
|
|
root.Items[0] = rootATD;
|
|
}
|
|
break;
|
|
}
|
|
#endregion
|
|
|
|
#region SEC
|
|
case Message.NotificationClass.SEC:
|
|
{
|
|
RootSEC rootSEC = new RootSEC();
|
|
SEC sec = message.Elements[0] as SEC;
|
|
|
|
List<object> secItems = new List<object>();
|
|
List<ItemsChoiceType1> choiceType1s = new List<ItemsChoiceType1>();
|
|
|
|
if (!message.MessageCore.IsTransit && (sec.KielCanalPassagePlanned ?? false))
|
|
{
|
|
rootSEC.KielCanalPassage = new RootSECKielCanalPassage();
|
|
rootSEC.KielCanalPassage.KielCanalPassagePlanned = "Y";
|
|
if (sec.KielCanalPassagePlannedIncomming.HasValue)
|
|
rootSEC.KielCanalPassage.KielCanalPassagePlannedIncoming = sec.KielCanalPassagePlannedIncomming.Value;
|
|
if (sec.KielCanalPassagePlannedOutgoing.HasValue)
|
|
rootSEC.KielCanalPassage.KielCanalPassagePlannedOutgoing = sec.KielCanalPassagePlannedOutgoing.Value;
|
|
}
|
|
|
|
rootSEC.CurrentShipSecurityLevel = (int)sec.CurrentShipSecurityLevel.Value;
|
|
|
|
if (sec.SECSimplification ?? false)
|
|
{
|
|
choiceType1s.Add(ItemsChoiceType1.SECSimplification);
|
|
secItems.Add("Y");
|
|
choiceType1s.Add(ItemsChoiceType1.PortOfCallWhereCompleteSECNotified);
|
|
secItems.Add(sec.PortOfCallWhereCompleteSECNotified);
|
|
}
|
|
else
|
|
{ // ACHTUNG Reihenfolge muss exakt dem .xsd entsprechen!
|
|
choiceType1s.Add(ItemsChoiceType1.CSOLastName);
|
|
secItems.Add(sec.CSOLastName);
|
|
choiceType1s.Add(ItemsChoiceType1.CSOFirstName);
|
|
secItems.Add(sec.CSOFirstName);
|
|
choiceType1s.Add(ItemsChoiceType1.CSOPhone);
|
|
secItems.Add(sec.CSOPhone);
|
|
choiceType1s.Add(ItemsChoiceType1.CSOFax);
|
|
secItems.Add(sec.CSOFax);
|
|
choiceType1s.Add(ItemsChoiceType1.CSOEMail);
|
|
secItems.Add(sec.CSOEMail);
|
|
choiceType1s.Add(ItemsChoiceType1.ValidISSCOnBoard);
|
|
secItems.Add(sec.ValidISSCOnBoard ?? false ? RootSECValidISSCOnBoard.Y : RootSECValidISSCOnBoard.N);
|
|
if (!(sec.ValidISSCOnBoard ?? false) && !sec.ReasonsForNoValidISSC.IsNullOrEmpty())
|
|
{
|
|
choiceType1s.Add(ItemsChoiceType1.ReasonsForNoValidISSC);
|
|
secItems.Add(sec.ReasonsForNoValidISSC);
|
|
}
|
|
choiceType1s.Add(ItemsChoiceType1.ISSCType);
|
|
secItems.Add((ISSCType)(sec.ISSCType ?? 0));
|
|
choiceType1s.Add(ItemsChoiceType1.ISSCIssuerType);
|
|
secItems.Add((ISSCIssuerType)(sec.ISSCIssuerType ?? 0));
|
|
choiceType1s.Add(ItemsChoiceType1.ISSCIssuerName);
|
|
secItems.Add(sec.ISSCIssuerName);
|
|
if (sec.ISSCDateOfExpiration.HasValue)
|
|
{
|
|
choiceType1s.Add(ItemsChoiceType1.ISSCDateOfExpiration);
|
|
secItems.Add(sec.ISSCDateOfExpiration.Value);
|
|
}
|
|
choiceType1s.Add(ItemsChoiceType1.ApprovedSecurityPlanOnBoard);
|
|
secItems.Add(sec.ApprovedSecurityPlanOnBoard ?? false ? RootSECValidISSCOnBoard.Y : RootSECValidISSCOnBoard.N);
|
|
|
|
choiceType1s.Add(ItemsChoiceType1.PortFacilityOfArrival);
|
|
secItems.Add(sec.PortFacilityOfArrival);
|
|
if (sec.GeneralDescriptionOfCargo.HasValue)
|
|
{
|
|
choiceType1s.Add(ItemsChoiceType1.GeneralDescriptionOfCargo);
|
|
secItems.Add((CargoDescription)sec.GeneralDescriptionOfCargo.Value);
|
|
}
|
|
|
|
for (int i = 0; i < sec.LastTenPortFacilitesCalled.Count; i++)
|
|
{
|
|
choiceType1s.Add(ItemsChoiceType1.LastTenPortFacilitiesCalled);
|
|
RootSECLastTenPortFacilitiesCalled lastTen = new RootSECLastTenPortFacilitiesCalled();
|
|
secItems.Add(lastTen);
|
|
LastTenPortFacilitiesCalled lastTenPortFacilitiesCalled = sec.LastTenPortFacilitesCalled[i] as LastTenPortFacilitiesCalled;
|
|
lastTen.PortFacilityPortName = lastTenPortFacilitiesCalled.PortFacilityPortName;
|
|
lastTen.PortFacilityPortCountry = lastTenPortFacilitiesCalled.PortFacilityPortCountry;
|
|
lastTen.PortFacilityPortLoCode = lastTenPortFacilitiesCalled.PortFacilityPortLoCode;
|
|
if (lastTenPortFacilitiesCalled.PortFacilityDateOfArrival.HasValue)
|
|
lastTen.PortFacilityDateOfArrival = lastTenPortFacilitiesCalled.PortFacilityDateOfArrival.Value;
|
|
if (lastTenPortFacilitiesCalled.PortFacilityDateOfDeparture.HasValue)
|
|
lastTen.PortFacilityDateOfDeparture = lastTenPortFacilitiesCalled.PortFacilityDateOfDeparture.Value;
|
|
if (lastTenPortFacilitiesCalled.PortFacilityShipSecurityLevel.HasValue)
|
|
lastTen.PortFacilityShipSecurityLevel = lastTenPortFacilitiesCalled.PortFacilityShipSecurityLevel.Value;
|
|
lastTen.PortFacilitySecurityMattersToReport = lastTenPortFacilitiesCalled.PortFacilitySecurityMattersToReport;
|
|
lastTen.PortFacilityGISISCode = lastTenPortFacilitiesCalled.PortFacilityGISISCode;
|
|
if (!lastTenPortFacilitiesCalled.PortFacilityGISISCodeLocode.IsNullOrEmpty())
|
|
lastTen.PortFacilityGISISCodeLoCode = lastTenPortFacilitiesCalled.PortFacilityGISISCodeLocode;
|
|
}
|
|
|
|
for (int i = 0; i < sec.ShipToShipActivitiesDuringLastTenPortFacilitiesCalled.Count; i++)
|
|
{
|
|
choiceType1s.Add(ItemsChoiceType1.ShipToShipActivities);
|
|
RootSECShipToShipActivities s2s = new RootSECShipToShipActivities();
|
|
secItems.Add(s2s);
|
|
ShipToShipActivitiesDuringLastTenPortFacilitiesCalled shipToShip = sec.ShipToShipActivitiesDuringLastTenPortFacilitiesCalled[i] as ShipToShipActivitiesDuringLastTenPortFacilitiesCalled;
|
|
s2s.ShipToShipActivityLocation = new RootSECShipToShipActivitiesShipToShipActivityLocation();
|
|
s2s.ShipToShipActivityLocation.ShipToShipActivityLocationName = shipToShip.ShipToShipActivityLocationName;
|
|
s2s.ShipToShipActivityLocation.ShipToShipActivityLocationLoCode = shipToShip.ShipToShipActivityLocationLoCode;
|
|
s2s.ShipToShipActivityLocation.ShipToShipActivityLocationCoordinates = new RootSECShipToShipActivitiesShipToShipActivityLocationShipToShipActivityLocationCoordinates();
|
|
if (shipToShip.ShipToShipActivityLocationCoordinatesLatitude.HasValue)
|
|
s2s.ShipToShipActivityLocation.ShipToShipActivityLocationCoordinates.ShipToShipActivityLocationCoordinatesLatitude = shipToShip.ShipToShipActivityLocationCoordinatesLatitude.Value;
|
|
if (shipToShip.ShipToShipActivityLocationCoordinatesLongitude.HasValue)
|
|
s2s.ShipToShipActivityLocation.ShipToShipActivityLocationCoordinates.ShipToShipActivityLocationCoordinatesLongitude = shipToShip.ShipToShipActivityLocationCoordinatesLongitude.Value;
|
|
if (shipToShip.ShipToShipActivityDateFrom.HasValue)
|
|
s2s.ShipToShipActivityDateFrom = shipToShip.ShipToShipActivityDateFrom.Value;
|
|
if (shipToShip.ShipToShipActivityDateTo.HasValue)
|
|
s2s.ShipToShipActivityDateTo = shipToShip.ShipToShipActivityDateTo.Value;
|
|
|
|
//int activityType;
|
|
//if (!Int32.TryParse(shipToShip.ShipToShipActivityType, out activityType))
|
|
//activityType = NOA_NOD.getCallPurposeCodeFromDescription(shipToShip.ShipToShipActivityType) ?? 0;
|
|
//s2s.ShipToShipActivityType = activityType;
|
|
|
|
if (shipToShip.ShipToShipActivityTypeCode.HasValue)
|
|
s2s.ShipToShipActivityType = shipToShip.ShipToShipActivityTypeCode.Value;
|
|
|
|
s2s.ShipToShipActivitySecurityMattersToReport = shipToShip.ShipToShipActivitySecurityMattersToReport;
|
|
}
|
|
}
|
|
|
|
rootSEC.Items = secItems.ToArray();
|
|
rootSEC.ItemsElementName = choiceType1s.ToArray();
|
|
|
|
root.Items = new object[1];
|
|
root.Items[0] = rootSEC;
|
|
}
|
|
break;
|
|
#endregion
|
|
|
|
default:
|
|
_log.WarnFormat("Message type {0} not (yet) supported for dbh", message.MessageNotificationClassDisplay);
|
|
break;
|
|
}
|
|
|
|
// serialize output structure to file
|
|
|
|
string filename = string.Format("NSW.BSMD.DBH.{1}.{0}.xml", (message == null) ? "CANCEL" : message.MessageNotificationClassDisplay, core.Id.Value);
|
|
_log.InfoFormat("saving {0} to output directory", filename);
|
|
|
|
string filePath = Path.Combine(Path.GetTempPath(), filename);
|
|
XmlSerializer serializer = new XmlSerializer(typeof(Root));
|
|
using (TextWriter tw = new StreamWriter(filePath))
|
|
{
|
|
serializer.Serialize(tw, root);
|
|
}
|
|
|
|
return filename;
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
_log.Error(ex.ToString());
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|