// // Class: Util // Current CLR: 4.0.30319.34209 // System: Microsoft Visual Studio 10.0 // Author: dani // Created: 6/17/2015 7:12:38 AM // // Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved. using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using log4net; using bsmd.database; namespace bsmd.ExcelReadService { public class Util { private static ILog _log = LogManager.GetLogger(typeof(Util)); public static bool ProcessSheet(ExcelReader reader, out string readMessage, out MessageCore messageCore) { readMessage = "ok"; messageCore = Util.LookupMessageCore(reader, out readMessage); if (messageCore == null) return false; // cannot work with this sheet or create one // load messages if already present List messages = DBManager.Instance.GetMessagesForCore(messageCore, DBManager.MessageLoad.EXCEL); // start parsing fields if (messageCore.IsTransit) { // scan for transit messages ScanAGNT(messages, messageCore, reader); ScanNOA_NOD(messages, messageCore, reader); ScanSEC(messages, messageCore, reader); ScanPOBA(messages, messageCore, reader); ScanPOBD(messages, messageCore, reader); ScanTIEFA(messages, messageCore, reader); ScanBKRA(messages, messageCore, reader); ScanSTAT(messages, messageCore, reader); ScanMDH(messages, messageCore, reader); ScanCREW(messages, messageCore, reader); ScanPAS(messages, messageCore, reader); // BPOL nicht im sheet ScanTOWA(messages, messageCore, reader); // HAZA // HAZD } else { // scan for visit messages ScanAGNT(messages, messageCore, reader); ScanNOA_NOD(messages, messageCore, reader); ScanATA(messages, messageCore, reader); ScanATD(messages, messageCore, reader); ScanSEC(messages, messageCore, reader); ScanPOBA(messages, messageCore, reader); ScanPOBD(messages, messageCore, reader); ScanNAME(messages, messageCore, reader); ScanTIEFA(messages, messageCore, reader); ScanTIEFD(messages, messageCore, reader); ScanBKRA(messages, messageCore, reader); ScanBKRD(messages, messageCore, reader); ScanSTAT(messages, messageCore, reader); ScanLADG(messages, messageCore, reader); ScanINFO(messages, messageCore, reader); ScanSERV(messages, messageCore, reader); ScanPRE72H(messages, messageCore, reader); ScanMDH(messages, messageCore, reader); ScanWAS(messages, messageCore, reader); ScanCREW(messages, messageCore, reader); ScanPAS(messages, messageCore, reader); // BPOL nicht im Sheet ScanTOWA(messages, messageCore, reader); ScanTOWD(messages, messageCore, reader); // HAZA // HAZD } //string sheetVersion = reader.GetCell("Portcall", 2, 1) as string; //messageCore.SietasSheetVersion = sheetVersion; DBManager.Instance.Save(messageCore); // save all messages now foreach(Message message in messages) { message.CreatedBy = "EXCEL"; DBManager.Instance.Save(message); message.SaveElements(); } return true; } #region ATA static void ScanATA(List messages, MessageCore messageCore, ExcelReader reader) { Message ataMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.ATA); if (ataMessage.Elements.Count == 0) { ATA newATA = new ATA(); newATA.MessageHeader = ataMessage; ataMessage.Elements.Add(newATA); } ATA ata = ataMessage.Elements[0] as ATA; Util.ScanMessage(ata, reader); if (!ata.ATAPortOfCall.HasValue && ataMessage.IsNew) messages.Remove(ataMessage); } internal static string CreateConfirmationSheet(MessageCore messageCore) { throw new NotImplementedException(); } #endregion #region ATD static void ScanATD(List messages, MessageCore messageCore, ExcelReader reader) { Message atdMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.ATD); if (atdMessage.Elements.Count == 0) { ATD newATD = new ATD(); newATD.MessageHeader = atdMessage; atdMessage.Elements.Add(newATD); } ATD atd = atdMessage.Elements[0] as ATD; Util.ScanMessage(atd, reader); if (!atd.ATDPortOfCall.HasValue && atdMessage.IsNew) messages.Remove(atdMessage); } #endregion #region TIEFA static void ScanTIEFA(List messages, MessageCore messageCore, ExcelReader reader) { Message tiefaMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.TIEFA); if (tiefaMessage.Elements.Count == 0) { TIEFA newTIEFA = new TIEFA(); newTIEFA.MessageHeader = tiefaMessage; tiefaMessage.Elements.Add(newTIEFA); } TIEFA tiefa = tiefaMessage.Elements[0] as TIEFA; Util.ScanMessage(tiefa, reader); if (!tiefa.DraughtUponArrival_DMT.HasValue && tiefaMessage.IsNew) messages.Remove(tiefaMessage); } #endregion #region TIEFD static void ScanTIEFD(List messages, MessageCore messageCore, ExcelReader reader) { Message tiefdMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.TIEFD); if(tiefdMessage.Elements.Count == 0) { TIEFD newTIEFD = new TIEFD(); newTIEFD.MessageHeader = tiefdMessage; tiefdMessage.Elements.Add(newTIEFD); } TIEFD tiefd = tiefdMessage.Elements[0] as TIEFD; Util.ScanMessage(tiefd, reader); if (!tiefd.DraughtUponDeparture_DMT.HasValue && tiefdMessage.IsNew) messages.Remove(tiefdMessage); } #endregion #region NAME static void ScanNAME(List messages, MessageCore messageCore, ExcelReader reader) { Message nameMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.NAME); if (nameMessage.Elements.Count == 0) { NAME newNAME = new NAME(); newNAME.MessageHeader = nameMessage; nameMessage.Elements.Add(newNAME); } NAME name = nameMessage.Elements[0] as NAME; Util.ScanMessage(name, reader); if (name.NameOfMaster.IsNullOrEmpty() && name.IsNew) messages.Remove(nameMessage); } #endregion #region POBA static void ScanPOBA(List messages, MessageCore messageCore, ExcelReader reader) { Message pobaMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.POBA); if(pobaMessage.Elements.Count == 0) { POBA newPoba = new POBA(); newPoba.MessageHeader = pobaMessage; pobaMessage.Elements.Add(newPoba); } POBA poba = pobaMessage.Elements[0] as POBA; Util.ScanMessage(poba, reader); if (((poba.TotalPersonsOnBoardUponArrival ?? 0) == 0) && poba.IsNew) messages.Remove(pobaMessage); } #endregion #region POBD static void ScanPOBD(List messages, MessageCore messageCore, ExcelReader reader) { Message pobdMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.POBD); if(pobdMessage.Elements.Count == 0) { POBD newPobd = new POBD(); newPobd.MessageHeader = pobdMessage; pobdMessage.Elements.Add(newPobd); } POBD pobd = pobdMessage.Elements[0] as POBD; Util.ScanMessage(pobd, reader); if (((pobd.TotalPersonsOnBoardUponDeparture ?? 0) == 0) && pobd.IsNew) messages.Remove(pobdMessage); } #endregion #region INFO static void ScanINFO(List messages, MessageCore messageCore, ExcelReader reader) { Message infoMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.INFO); if(infoMessage.Elements.Count == 0) { INFO newINFO = new INFO(); newINFO.MessageHeader = infoMessage; infoMessage.Elements.Add(newINFO); } INFO info = infoMessage.Elements[0] as INFO; Util.ScanMessage(info, reader); info.ShippingArea = reader.ReadShippingArea(@"INFO.ShippingArea"); // enum read func // wird nicht wieder entfernt } #endregion #region STAT static void ScanSTAT(List messages, MessageCore messageCore, ExcelReader reader) { Message statMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.STAT); if(statMessage.Elements.Count == 0) { STAT newSTAT = new STAT(); newSTAT.MessageHeader = statMessage; statMessage.Elements.Add(newSTAT); } STAT stat = statMessage.Elements[0] as STAT; Util.ScanMessage(stat, reader); if (!stat.Flag.IsNullOrEmpty() && stat.Flag.Length > 2) stat.Flag = LocodeDB.CountryCodeFromName(stat.Flag); if (!stat.Flag.IsNullOrEmpty() && stat.Flag.Length == 2) { if (!stat.PortOfRegistry.IsNullOrEmpty() && stat.PortOfRegistry.Length != 5) stat.PortOfRegistry = LocodeDB.LocodeFromCity(stat.PortOfRegistry, stat.Flag); } // wird nicht wieder entfernt (core ist auch da!) } #endregion #region NOA_NOD static void ScanNOA_NOD(List messages, MessageCore messageCore, ExcelReader reader) { Message noa_nodMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.NOA_NOD); if (noa_nodMessage.Elements.Count == 0) { NOA_NOD newNoa_nod = new NOA_NOD(); newNoa_nod.MessageHeader = noa_nodMessage; noa_nodMessage.Elements.Add(newNoa_nod); } NOA_NOD noa_nod = noa_nodMessage.Elements[0] as NOA_NOD; if (messageCore.IsTransit) noa_nod.ETAToKielCanal = messageCore.ETAKielCanal; else { noa_nod.ETAToPortOfCall = messageCore.ETA; string callPurposeDescription = reader.ReadText("NOA_NOD.CallPuposeDescription"); if (!callPurposeDescription.IsNullOrEmpty()) { CallPurpose callPurpose = new CallPurpose(); callPurpose.CallPurposeCode = noa_nod.getCallPurposeCodeFromDescription(callPurposeDescription) ?? 0; callPurpose.CallPurposeDescription = callPurposeDescription; noa_nod.CallPurposes.Add(callPurpose); } } string lastPort = reader.ReadText("NOA_NOD.LastPort").Trim(); List lastPorts = LocodeDB.AllLocodesForCityName(lastPort); if (lastPorts.Count == 1) noa_nod.LastPort = lastPorts[0]; else _log.WarnFormat("{0} results in {1} possible LOCODES", lastPort, lastPorts.Count); string nextPort = reader.ReadText("NOA_NOD.NextPort").Trim(); List nextPorts = LocodeDB.AllLocodesForCityName(nextPort); if (nextPorts.Count == 1) noa_nod.NextPort = nextPorts[0]; else _log.WarnFormat("{0} results in {1} possible LOCODES", nextPort, nextPorts.Count); noa_nod.ETDFromPortOfCall = reader.ReadDateTime("NOA_NOD.ETDDateFromPortOfCall", "NOA_NOD.ETDTimeFromPortOfCall"); noa_nod.ETDFromLastPort = reader.ReadDateTime("NOA_NOD.ETDDateFromLastPort", "NOA_NOD.ETDTimeFromLastPort"); noa_nod.ETAToNextPort = reader.ReadDateTime("NOA_NOD.ETADateToNextPort", "NOA_NOD.ETATimeToNextPort"); } #endregion #region AGNT static void ScanAGNT(List messages, MessageCore messageCore, ExcelReader reader) { Message agntMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.AGNT); if(agntMessage.Elements.Count == 0) { AGNT newAgnt = new AGNT(); newAgnt.MessageHeader = agntMessage; agntMessage.Elements.Add(newAgnt); } AGNT agnt = agntMessage.Elements[0] as AGNT; Util.ScanMessage(agnt, reader); // wird nicht mehr entfernt, egal welche Felder gelesen werden } #endregion #region WAS static void ScanWAS(List messages, MessageCore messageCore, ExcelReader reader) { Message wasMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.WAS); if (wasMessage.Elements.Count == 0) { WAS newWAS = new WAS(); newWAS.MessageHeader = wasMessage; wasMessage.Elements.Add(newWAS); } WAS was = wasMessage.Elements[0] as WAS; Util.ScanMessage(was, reader); was.WasteDisposalDelivery = reader.ReadDelivery("WAS.WasteDisposalDelivery"); List deliveryLocodes = LocodeDB.AllLocodesForCityName(reader.ReadText("WAS.LastWasteDisposalPort")); if (deliveryLocodes.Count == 1) was.LastWasteDisposalPort = deliveryLocodes[0]; // Waste 1 - 9 for (int i = 1; i <= was.NumberOfExcelRows; i++) { // string wastetype = string.Format("WAS.WasteType_{0}", i); string wasteDescription = string.Format("WAS.WasteDescription_{0}", i); string wasteAmount = string.Format("WAS.WasteDisposalAmount_MTQ_{0}", i); string wasteCapacity = string.Format("WAS.WasteCapacity_MTQ_{0}", i); string wasteRetained = string.Format("WAS.WasteAmountRetained_MTQ_{0}", i); string wastePort = string.Format("WAS.WasteDisposalPort_{0}", i); string amountGen = string.Format("WAS.WasteAmountGeneratedTillNextPort_MTQ_{0}", i); Waste waste = was.GetSublistElementWithIdentifier(i.ToString()) as Waste; if(waste == null) { waste = new Waste(); waste.Identifier = i.ToString(); waste.WAS = was; was.Waste.Add(waste); } waste.WasteType = (byte)i; waste.WasteDescription = reader.ReadText(wasteDescription); waste.WasteDisposalAmount_MTQ = reader.ReadNumber(wasteAmount); waste.WasteCapacity_MTQ = reader.ReadNumber(wasteCapacity); waste.WasteAmountRetained_MTQ = reader.ReadNumber(wasteRetained); waste.WasteDisposalPort = reader.ReadText(wastePort); // TODO: check for LOCODE? waste.WasteAmountGeneratedTillNextPort_MTQ = reader.ReadNumber(amountGen); // empty wastes not removed, are required elements! } } #endregion #region MDH static void ScanMDH(List messages, MessageCore messageCore, ExcelReader reader) { Message mdhMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.MDH); if(mdhMessage.Elements.Count == 0) { MDH newMDH = new MDH(); newMDH.MessageHeader = mdhMessage; mdhMessage.Elements.Add(newMDH); } MDH mdh = mdhMessage.Elements[0] as MDH; Util.ScanMessage(mdh, reader); // POC last 30 days for (int i = 0; i < mdh.NumberOfExcelRows; i++) { string portName = string.Format("MDH.PortOfCallLast30DaysPort_{0}", i + 1); string portCountry = string.Format("MDH.PortOfCallLast30DaysCountry_{0}", i + 1); string locode = string.Format("MDH.PortOfCallLast30DaysLocode_{0}", i + 1); string crewJoined = string.Format("MDH.PortOfCallLast30DaysCrewMembersJoined_{0}", i + 1); string crewName = string.Format("MDH.PortOfCallLast30DaysCrewJoinedShipName_{0}", i + 1); string depDate = string.Format("MDH.PortOfCallLast30DaysDateOfDeparture_{0}", i + 1); PortOfCallLast30Days poc30d = mdh.GetSublistElementWithIdentifier((i + 1).ToString()) as PortOfCallLast30Days; if (poc30d == null) { poc30d = new PortOfCallLast30Days(); poc30d.Identifier = (i + 1).ToString(); poc30d.MDH = mdh; mdh.PortOfCallLast30Days.Add(poc30d); } poc30d.PortOfCallLast30DaysDateOfDeparture = reader.ReadDate(depDate); poc30d.PortOfCallLast30DaysLocode = reader.ReadTextNoWhitespace(locode); poc30d.PortOfCallLast30DaysCrewMembersJoined = reader.ReadBoolean(crewJoined); if (poc30d.PortOfCallLast30DaysCrewMembersJoined ?? false) { string crewNameString = reader.ReadText(crewName); if (!crewName.IsNullOrEmpty()) { // try different separators string[] crew = crewNameString.Split(';'); if (crew.Length == 1) crew = crewNameString.Split(','); for (int j = 0; j < crew.Length; j++) { PortOfCallLast30DaysCrewJoinedShip poc30dCrew = poc30d.GetSublistElementWithIdentifier((j + 1).ToString()) as PortOfCallLast30DaysCrewJoinedShip; if (poc30dCrew == null) { poc30dCrew = new PortOfCallLast30DaysCrewJoinedShip(); poc30dCrew.Identifier = (j + 1).ToString(); poc30dCrew.PortOfCallLast30Days = poc30d; poc30d.CrewJoinedShip.Add(poc30dCrew); } poc30dCrew.PortOfCallLast30DaysCrewJoinedShipName = crew[j]; } } } // Leer/def. Zeilen entfernen if (!poc30d.PortOfCallLast30DaysDateOfDeparture.HasValue && (poc30d.PortOfCallLast30DaysLocode == null)) mdh.PortOfCallLast30Days.Remove(poc30d); } // wird nicht wieder entfernt falls keine Daten vorliegen } #endregion #region SEC static void ScanSEC(List messages, MessageCore messageCore, ExcelReader reader) { Message secMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.SEC); if (secMessage.Elements.Count == 0) { SEC newSEC = new SEC(); newSEC.MessageHeader = secMessage; secMessage.Elements.Add(newSEC); } SEC sec = secMessage.Elements[0] as SEC; Util.ScanMessage(sec, reader); // Last10PortFacilitesCalled for (int i = 1; i <= 10; i++) { string portName = string.Format("SEC.PortFacilityPortName_{0}", i); string portCountry = string.Format("SEC.PortFacilityPortCountry_{0}", i); string portLocode = string.Format("SEC.PortFacilityPortLoCode_{0}", i); string portDateOfArrival = string.Format("SEC.PortFacilityDateOfArrival_{0}", i); string portDateOfDeparture = string.Format("SEC.PortFacilityDateOfDeparture_{0}", i); string portShipSecLevel = string.Format("SEC.PortFacilityShipSecurityLevel_{0}", i); string portGISISCode = string.Format("SEC.PortFacilityGISISCode_{0}", i); LastTenPortFacilitiesCalled l10fc = sec.GetPortFacilityWithIdentifier(i.ToString()) as LastTenPortFacilitiesCalled; if (l10fc == null) { l10fc = new LastTenPortFacilitiesCalled(); l10fc.Identifier = i.ToString(); l10fc.SEC = sec; sec.LastTenPortFacilitesCalled.Add(l10fc); } l10fc.PortFacilityPortName = reader.ReadText(portName); l10fc.PortFacilityPortCountry = reader.ReadText(portCountry); l10fc.PortFacilityPortLoCode = reader.ReadTextNoWhitespace(portLocode); l10fc.PortFacilityDateOfArrival = reader.ReadDate(portDateOfArrival); l10fc.PortFacilityDateOfDeparture = reader.ReadDate(portDateOfDeparture); l10fc.PortFacilityShipSecurityLevel = (byte) reader.ReadNumber(portShipSecLevel); l10fc.PortFacilityGISISCode = reader.ReadTextNoWhitespace(portGISISCode); } // Ship2ShipActivities for (int i = 1; i <= 10; i++) { string s2sName = string.Format("SEC.ShipToShipActivityLocationName_{0}", i); string s2sLocode = string.Format("SEC.ShipToShipActivityLocationLoCode_{0}", i); string s2sLatitude = string.Format("SEC.ShipToShipActivityLocationCoordinatesLatitude_{0}", i); string s2sLongitude = string.Format("SEC.ShipToShipActivityLocationCoordinatesLongitude_{0}", i); string s2sFromDate = string.Format("SEC.ShipToShipActivityDateFrom_{0}", i); string s2sToDate = string.Format("SEC.ShipToShipActivityDateTo_{0}", i); string s2sActivityString = string.Format("SEC.ShipToShipActivityType_{0}", i); ShipToShipActivitiesDuringLastTenPortFacilitiesCalled s2sActivity = sec.GetShipToShipWithIdentifier(i.ToString()) as ShipToShipActivitiesDuringLastTenPortFacilitiesCalled; if (s2sActivity == null) { s2sActivity = new ShipToShipActivitiesDuringLastTenPortFacilitiesCalled(); s2sActivity.Identifier = i.ToString(); s2sActivity.SEC = sec; sec.ShipToShipActivitiesDuringLastTenPortFacilitiesCalled.Add(s2sActivity); } s2sActivity.ShipToShipActivityLocationName = reader.ReadText(s2sName); s2sActivity.ShipToShipActivityLocationLoCode = reader.ReadTextNoWhitespace(s2sLocode); s2sActivity.ShipToShipActivityLocationCoordinatesLatitude = (int)reader.ReadNumber(s2sLatitude); s2sActivity.ShipToShipActivityLocationCoordinatesLongitude = (int)reader.ReadNumber(s2sLongitude); s2sActivity.ShipToShipActivityDateFrom = reader.ReadDate(s2sFromDate); s2sActivity.ShipToShipActivityDateTo = reader.ReadDate(s2sToDate); s2sActivity.ShipToShipActivityType = reader.ReadText(s2sActivityString); } } #endregion #region BKRA static void ScanBKRA(List messages, MessageCore messageCore, ExcelReader reader) { Message bkraMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.BKRA); for (int i = 0; i < bkraMessage.NumberOfExcelRows; i++) { string lnQuantity = string.Format("BKRA.BunkerFuelQuantity_TNE_{0}", i + 1); string lnType = string.Format("BKRA.BunkerFuelType_{0}", i + 1); BRKA bkra = bkraMessage.GetSublistElementWithIdentifier((i + 1).ToString()) as BRKA; if (bkra == null) { bkra = new BRKA(); bkra.Identifier = (i + 1).ToString(); bkra.MessageHeader = bkraMessage; bkraMessage.Elements.Add(bkra); } bkra.BunkerFuelQuantity_TNE = reader.ReadNumber(lnQuantity); bkra.BunkerFuelType = reader.ReadText(lnType); // dont save empty element if(bkra.IsNew && !bkra.BunkerFuelQuantity_TNE.HasValue && bkra.BunkerFuelType.IsNullOrEmpty()) bkraMessage.Elements.Remove(bkra); } } #endregion #region BKRD static void ScanBKRD(List messages, MessageCore messageCore, ExcelReader reader) { Message bkrdMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.BKRD); for (int i = 0; i < bkrdMessage.NumberOfExcelRows; i++) { string lnQuantity = string.Format("BKRD.BunkerFuelQuantity_TNE_{0}", i + 1); string lnType = string.Format("BKRD.BunkerFuelType_{0}", i + 1); BRKD bkrd = bkrdMessage.GetSublistElementWithIdentifier((i + 1).ToString()) as BRKD; if (bkrd == null) { bkrd = new BRKD(); bkrd.Identifier = (i + 1).ToString(); bkrd.MessageHeader = bkrdMessage; bkrdMessage.Elements.Add(bkrd); } bkrd.BunkerFuelQuantity_TNE = reader.ReadNumber(lnQuantity); bkrd.BunkerFuelType = reader.ReadText(lnType); // dont save empty element if(bkrd.IsNew && !bkrd.BunkerFuelQuantity_TNE.HasValue && bkrd.BunkerFuelType.IsNullOrEmpty()) bkrdMessage.Elements.Remove(bkrd); } } #endregion #region TOWA static void ScanTOWA(List messages, MessageCore messageCore, ExcelReader reader) { // TOWA ist eigentlich 1:n, es ist aber keine Liste im Sheet! Message towaMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.TOWA); string towageName = reader.ReadText("TOWA.TowageOnArrivalName"); if (!towageName.IsNullOrEmpty()) { if (towaMessage.Elements.Count == 0) { TOWA newTOWA = new TOWA(); newTOWA.MessageHeader = towaMessage; towaMessage.Elements.Add(newTOWA); } TOWA towa = towaMessage.Elements[0] as TOWA; Util.ScanMessage(towa, reader); } } #endregion #region TOWD static void ScanTOWD(List messages, MessageCore messageCore, ExcelReader reader) { // TOWD ist 1:n, es ist aber keine Liste im Sheet! Message towdMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.TOWD); string towageName = reader.ReadText("TOWD.TowageOnDepartureName"); if(!towageName.IsNullOrEmpty()) { if(towdMessage.Elements.Count == 0) { TOWD newTOWD = new TOWD(); newTOWD.MessageHeader = towdMessage; towdMessage.Elements.Add(newTOWD); } TOWD towd = towdMessage.Elements[0] as TOWD; Util.ScanMessage(towd, reader); } } #endregion #region PRE72H static void ScanPRE72H(List messages, MessageCore messageCore, ExcelReader reader) { Message pre72hMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.PRE72H); if (pre72hMessage.Elements.Count == 0) { PRE72H newPRE72H = new PRE72H(); newPRE72H.MessageHeader = pre72hMessage; pre72hMessage.Elements.Add(newPRE72H); } PRE72H pre72h = pre72hMessage.Elements[0] as PRE72H; Util.ScanMessage(pre72h, reader); // diese Nachricht bleibt auch wenn sie leer ist pre72h.ConditionCargoBallastTanks = reader.ReadConditionTanks("PRE72H.ConditionCargoBallastTanks"); pre72h.TankerHullConfiguration = reader.ReadHullConfiguration("PRE72H.TankerHullConfiguration"); } #endregion #region SERV static void ScanSERV(List messages, MessageCore messageCore, ExcelReader reader) { Message servMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.SERV); if(servMessage.Elements.Count == 0) { SERV newSERV = new SERV(); newSERV.MessageHeader = servMessage; servMessage.Elements.Add(newSERV); } SERV serv = servMessage.Elements[0] as SERV; Util.ScanMessage(serv, reader); if (serv.ServiceBeneficiary.IsNullOrEmpty() && serv.ServiceInvoiceRecipient.IsNullOrEmpty()) servMessage.Elements.Remove(serv); } #endregion #region LADG static void ScanLADG(List messages, MessageCore messageCore, ExcelReader reader) { Message ladgMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.LADG); for (int i = 0; i < ladgMessage.NumberOfExcelRows; i++) { string lnCHT = string.Format("LADG.CargoHandlingType_{0}", i + 1); string lnType = string.Format("LADG.CargoType_{0}", i + 1); string lnCNOI = string.Format("LADG.CargoNumberOfItems_{0}", i + 1); string lnCGQ = string.Format("LADG.CargoGrossQuantity_TNE_{0}", i + 1); LADG ladg = ladgMessage.GetSublistElementWithIdentifier((i + 1).ToString()) as LADG; if (ladg == null) { ladg = new LADG(); ladg.Identifier = (i + 1).ToString(); ladg.MessageHeader = ladgMessage; ladgMessage.Elements.Add(ladg); } string handlingTypeString = reader.ReadText(lnCHT); if (!handlingTypeString.IsNullOrEmpty()) { // irgendwas mit "*load*" drin wird load, alles andere discharge ladg.CargoHandlingType = handlingTypeString.Contains("load", StringComparison.InvariantCultureIgnoreCase) ? (byte) 0 : (byte) 1; } ladg.CargoCodeNST = reader.ReadText(lnType); if (ladg.CargoCodeNST.Length != 2) ladg.CargoCodeNST = null; // stupid validation ladg.CargoNumberOfItems = (int?) reader.ReadNumber(lnCNOI); ladg.CargoGrossQuantity_TNE = reader.ReadNumber(lnCGQ); // dont save empty element if (ladg.IsNew && !ladg.CargoHandlingType.HasValue) ladgMessage.Elements.Remove(ladg); } } #endregion #region CREW static void ScanCREW(List messages, MessageCore messageCore, ExcelReader reader) { Message crewMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.CREW); for (int i = 0; i < crewMessage.NumberOfExcelRows; i++) { string crewLastName = string.Format("CREW.CrewMemberLastName_{0}", i + 1); string crewFirstName = string.Format("CREW.CrewMemberFirstName_{0}", i + 1); string crewGender = string.Format("CREW.CrewMemberGender_{0}", i + 1); string crewNationality = string.Format("CREW.CrewMemberNationality_{0}", i + 1); string crewDuty = string.Format("CREW.CrewMemberDuty_{0}", i + 1); string crewPlaceOfBirth = string.Format("CREW.CrewMemberPlaceOfBirth_{0}", i + 1); string crewDateOfBirth = string.Format("CREW.CrewMemberDateOfBirth_{0}", i + 1); string crewIdentDocType = string.Format("CREW.CrewMemberIdentityDocumentType_{0}", i + 1); string crewIdentDocId = string.Format("CREW.CrewMemberIdentityDocumentId_{0}", i + 1); string crewVisaNo = string.Format("CREW.CrewMemberVisaNumber_{0}", i + 1); string lastName = reader.ReadText(crewLastName); if (!lastName.IsNullOrEmpty()) { CREW crew = crewMessage.GetSublistElementWithIdentifier((i + 1).ToString()) as CREW; if (crew == null) { crew = new CREW(); crew.Identifier = (i + 1).ToString(); crew.MessageHeader = crewMessage; crewMessage.Elements.Add(crew); } crew.CrewMemberLastName = lastName; crew.CrewMemberFirstName = reader.ReadText(crewFirstName); crew.CrewMemberGender = reader.ReadGender(crewGender); crew.CrewMemberDuty = reader.ReadText(crewDuty); crew.CrewMemberPlaceOfBirth = reader.ReadText(crewPlaceOfBirth); crew.CrewMemberDateOfBirth = reader.ReadDate(crewDateOfBirth); crew.CrewMemberIdentityDocumentType = reader.ReadIdentityDocumentType(crewIdentDocType); crew.CrewMemberIdentityDocumentId = reader.ReadText(crewIdentDocId); crew.CrewMemberVisaNumber = reader.ReadText(crewVisaNo); } } } #endregion #region PAS static void ScanPAS(List messages, MessageCore messageCore, ExcelReader reader) { Message pasMessage = Util.GetMessageWithType(messages, messageCore, Message.NotificationClass.PAS); for (int i = 0; i < pasMessage.NumberOfExcelRows; i++) { string pasLastName = string.Format("PAS.PassengerLastName_{0}", i + 1); string pasFirstName = string.Format("PAS.PassengerFirstName_{0}", i + 1); string pasGender = string.Format("PAS.PassengerGender_{0}", i + 1); string pasNationality = string.Format("PAS.PassengerNationality_{0}", i + 1); string pasEmbarkation = string.Format("PAS.PassengerPortOfEmbarkation_{0}", i + 1); string pasDebarkation = string.Format("PAS.PassengerPortOfDisembarkation_{0}", i + 1); string pasTransit = string.Format("PAS.PassengerInTransit_{0}", i + 1); string pasPlaceOfBirth = string.Format("PAS.PassengerPlaceOfBirth_{0}", i + 1); string pasDateOfBirth = string.Format("PAS.PassengerDateOfBirth_{0}", i + 1); string pasIdentDocType = string.Format("PAS.PassengerIdentityDocumentType_{0}", i + 1); string pasIdentDocId = string.Format("PAS.PassengerIdentityDocumentId_{0}", i + 1); string pasVisaNo = string.Format("PAS.PassengerVisaNumber_{0}", i + 1); string lastName = reader.ReadText(pasLastName); if (!lastName.IsNullOrEmpty()) { PAS pas = pasMessage.GetSublistElementWithIdentifier((i + 1).ToString()) as PAS; if (pas == null) { pas = new PAS(); pas.Identifier = (i + 1).ToString(); pas.MessageHeader = pasMessage; pasMessage.Elements.Add(pas); } pas.PassengerLastName = lastName; pas.PassengerFirstName = reader.ReadText(pasFirstName); pas.PassengerGender = reader.ReadGender(pasGender); pas.PassengerNationality = reader.ReadText(pasNationality); // TODO: Nicht klar ob hier LOCODEs kommen oder nicht pas.PassengerPortOfEmbarkation = reader.ReadTextNoWhitespace(pasEmbarkation); pas.PassengerPortOfDisembarkation = reader.ReadTextNoWhitespace(pasDebarkation); pas.PassengerInTransit = reader.ReadBoolean(pasTransit); pas.PassengerPlaceOfBirth = reader.ReadText(pasPlaceOfBirth); pas.PassengerDateOfBirth = reader.ReadDate(pasDateOfBirth); pas.PassengerIdentityDocumentType = reader.ReadIdentityDocumentType(pasIdentDocType); pas.PassengerIdentityDocumentId = reader.ReadText(pasIdentDocId); pas.PassengerVisaNumber = reader.ReadText(pasVisaNo); } } } #endregion #region ScanMessage (generic) private static void ScanMessage(DatabaseEntity dbEntity, ExcelReader reader) { Type objType = dbEntity.GetType(); List props = new List(); // add lookup properties to scan list props.AddRange(objType.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(LookupNameAttribute)))); foreach (PropertyInfo property in props) { object propValue = property.GetValue(dbEntity, null); string value = (propValue == null) ? string.Empty : propValue.ToString(); LookupNameAttribute lookupNameAttribute = Attribute.GetCustomAttribute(property, typeof(LookupNameAttribute)) as LookupNameAttribute; if (property.PropertyType == typeof(DateTime?)) { DateTime? sheetValue = reader.ReadDate(lookupNameAttribute.LookupName); if (sheetValue != null) property.SetValue(dbEntity, sheetValue); } else if (property.PropertyType == typeof(double?)) { double? sheetValue = reader.ReadNumber(lookupNameAttribute.LookupName); if (sheetValue != null) property.SetValue(dbEntity, sheetValue); } else if (property.PropertyType == typeof(string)) { string sheetValue = reader.ReadText(lookupNameAttribute.LookupName); if (sheetValue != null) property.SetValue(dbEntity, sheetValue); } else { } } } #endregion /// /// Check with cell values if this message core is already in our DB /// private static MessageCore LookupMessageCore(ExcelReader reader, out string message) { // lookup using field values MessageCore result = null; DateTime? eta = null; string poc = null; string imo = null; message = string.Empty; bool isTransit = false; // first check with visit/transit ID string visitTransitId = reader.ReadText("ID"); if (visitTransitId != null) { if (bsmd.database.Util.IsVisitId(visitTransitId)) { result = DBManager.Instance.GetMessageCoreByVisitId(visitTransitId); } else if (bsmd.database.Util.IsTransitId(visitTransitId)) { result = DBManager.Instance.GetMessageCoreByTransitId(visitTransitId); } } else { // lookup poc, imo, eta poc = reader.ReadText("Visit.PortOfCall"); if (poc != null) { // Prüfen auf Transit if (poc.ToUpper().Contains("CANAL")) { poc = "ZZNOK"; isTransit = true; } else { // Im Sheet könnte der Name statt des LOCODES stehen! if (!RuleEngine.IsGermanLocode(poc)) { // somehow lookup LOCODE from the port's name! poc = LocodeDB.LocodeGERFromCity(poc); } } imo = reader.ReadText("Visit.IMONumber"); // ETA eta = reader.ReadDateTime("NOA_NOD.ETADateToPortOfCall", "NOA_NOD.ETATimeToPortOfCall"); if ((imo != null) && (eta.HasValue)) { result = DBManager.Instance.GetMessageCoreByShipInfos(imo, eta.Value, poc); if (result.IsNew) result.IsTransit = isTransit; } } } if (result == null) { if (imo == null) { message = "IMO number missing or not found"; return null; } if(poc == null) { message = string.Format("Port of call missing or not found for IMO {0}", imo); return null; } if(eta == null) { message = string.Format("ETA missing or not found for IMO {0}", imo); return null; } result = new MessageCore(); result.IMO = imo; result.ReportStatus = MessageCore.ReportStatusEnum.COMPLETE; result.Portname = poc; result.ETA = eta; if (result.IMO.Length > 7) { _log.WarnFormat("IMO {0} is longer than 7 chars, truncating!", result.IMO); result.IMO = result.IMO.Substring(0, 7); } DBManager.Instance.Save(result); } return result; } private static DateTime ConstructDate(string etaDateString, string etaTime) { DateTime result = DateTime.Now; if (DateTime.TryParse(etaDateString, out result)) { TimeSpan sp; if (TimeSpan.TryParse(etaTime, out sp)) result += sp; } return result; } private static Message GetMessageWithType(List messages, MessageCore core, Message.NotificationClass type) { foreach(Message message in messages) if (message.MessageNotificationClass == type) return message; Message newMessage = new Message(); newMessage.MessageNotificationClass = type; messages.Add(newMessage); newMessage.MessageCore = core; return newMessage; } } }