git_bsmd/nsw/Source/bsmd.database/Util.cs

285 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Class: Util
// Current CLR: 4.0.30319.34209
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 3/21/2015 10:36:56 AM
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using log4net;
namespace bsmd.database
{
public static class Util
{
private static readonly Regex regexVisit = new Regex("^(DE)([A-Z]{3})-([0-9]{4})-([A-Z]{6})$", RegexOptions.IgnoreCase);
private static readonly Regex regexTransit = new Regex("^(ZZNOK)-([0-9]{4})-([A-Z]{6})$", RegexOptions.IgnoreCase);
private static readonly ILog _log = LogManager.GetLogger(typeof(Util));
/// <summary>
/// Extension helper to add values that can be null:
/// http://stackoverflow.com/questions/13451085/exception-when-addwithvalue-parameter-is-null
/// </summary>
public static SqlParameter AddWithNullableValue(this SqlParameterCollection collection, string parameterName, object value)
{
if (value == null)
return collection.AddWithValue(parameterName, DBNull.Value);
else
return collection.AddWithValue(parameterName, value);
}
public static string GetGenderDisplay(byte? val)
{
if (val.HasValue)
{
switch (val)
{
case 0: return "Male";
case 1: return "Female";
default: return "Other";
}
}
else
{
return "Unknown";
}
}
public static string GetIdentityDocumentTypeDisplay(byte? val)
{
if(val.HasValue)
{
switch (val)
{
case 0: return "Identity card";
case 1: return "Passport";
case 2: return "Muster book";
case 3: return "Picture ID";
case 4: return "Residantal permit";
default: return "Other legal identity document";
}
}
else
{
return "Unknown";
}
}
public static string GetISSCTypeDisplay(byte? val)
{
if (val.HasValue)
{
switch(val)
{
case 0: return "FULL";
case 1: return "INTERIM";
default:
return "UNKNOWN";
}
}
else
{
return "Unknown";
}
}
public static string GetISSCIssuerTypeDisplay(byte? val)
{
if (val.HasValue)
{
switch (val)
{
case 0: return "ADMINISTRATION";
case 1: return "RSO";
default:
return "UNKNOWN";
}
}
else
{
return "Unknown";
}
}
public static bool IsVisitId(string val)
{
if (val.IsNullOrEmpty()) return false;
return regexVisit.IsMatch(val);
}
public static bool IsTransitId(string val)
{
if (val.IsNullOrEmpty()) return false;
return regexTransit.IsMatch(val);
}
/// <summary>
/// Hilfsfunktion für "manuelle" Anlage eines Schiffsanlaufs. Die Objekte sind bereits gespeichert.
/// Es werden nur noch nicht vorhandene Meldeklassen erzeugt
/// </summary>
public static List<Message> CreateMessagesForCore(MessageCore core, List<Message> existingMessages, ReportingParty user = null)
{
List<Message> result = new List<Message>();
Dictionary<Message.NotificationClass, Message> messageDict = new Dictionary<Message.NotificationClass, Message>();
if(!existingMessages.IsNullOrEmpty())
{
foreach (Message aMessage in existingMessages)
{
if(messageDict.ContainsKey(aMessage.MessageNotificationClass))
{
_log.WarnFormat("Core {0} [{1}] has more than one message class for {2}", core.Id, core.DisplayId, aMessage.MessageNotificationClassDisplay);
}
messageDict[aMessage.MessageNotificationClass] = aMessage;
}
}
bool isDE, isDK;
if(core?.PoC != null)
{
isDE = core.PoC.Equals("ZZNOK") || core.PoC.StartsWith("DE");
isDK = core.PoC.StartsWith("DK");
foreach (Message.NotificationClass notificationClass in Enum.GetValues(typeof(Message.NotificationClass)))
{
if(isDE)
{
if ((notificationClass == Message.NotificationClass.CREWD) ||
(notificationClass == Message.NotificationClass.PASD) ||
(notificationClass == Message.NotificationClass.STO)) continue;
}
if(isDK)
{
// gibt es hier etwas, das nicht gebraucht wird? (siehe Mail von Christin, 29.5.17
if ((notificationClass == Message.NotificationClass.MDH) ||
(notificationClass == Message.NotificationClass.BKRA) ||
(notificationClass == Message.NotificationClass.BKRD) ||
(notificationClass == Message.NotificationClass.TOWA) ||
(notificationClass == Message.NotificationClass.TOWD)) continue;
}
if (core.IsTransit && (notificationClass == Message.NotificationClass.VISIT)) continue;
if (!core.IsTransit && (notificationClass == Message.NotificationClass.TRANSIT)) continue;
Message message = null;
if (!messageDict.ContainsKey(notificationClass))
{
message = new Message();
if (user != null)
message.CreatedBy = string.Format("ENI-2: {0}", user.Logon);
message.MessageCore = core;
message.MessageCoreId = core.Id;
message.MessageNotificationClass = notificationClass;
DBManager.Instance.Save(message);
result.Add(message);
}
else
{
message = messageDict[notificationClass];
}
// abgesehen von "Listen" für die Nachrichtenklassen auch untergeordnete Elemente erzeugen, falls nicht vorhanden!
DatabaseEntity classElement = null;
if (!Message.IsListClass(notificationClass) && (message.Elements.Count == 0))
{
classElement = DBManager.CreateMessage(notificationClass);
// CH: 6.10.17: Für die manuelle Eingabe (wird leider nicht ganz auszuschließen sein) wäre es hilfreich, wenn alle Checkboxen nicht leer sind, sondern False beinhalten.
if(notificationClass == Message.NotificationClass.MDH)
{
((MDH)classElement).SetBoolsToFalse();
}
if(notificationClass == Message.NotificationClass.BPOL)
{
// Vorbelegung, Spezialwunsch aus BRV 5.2.18
((BPOL)classElement).CruiseShip = false;
((BPOL)classElement).StowawaysOnBoard = false;
}
if (classElement != null) // null für Visit/Transit
{
classElement.MessageHeader = message;
DBManager.Instance.Save(classElement);
message.Elements.Add(classElement);
}
}
}
}
return result;
}
public static int? GetNumericIdentifier(ISublistElement element)
{
if (element != null)
{
string stringIdentifier = element.Identifier;
Regex re = new Regex(@"\d+");
Match m = re.Match(stringIdentifier);
if (m.Success)
{
return Int32.Parse(m.Value);
}
}
return null;
}
public static bool IsIMOValid(string imoAsString)
{
if (imoAsString.IsNullOrEmpty()) return false;
string actualIMO = null;
if(imoAsString.Length == 10)
{
if (imoAsString.Substring(0, 3).Equals("imo", StringComparison.OrdinalIgnoreCase))
actualIMO = imoAsString.Substring(3);
}
if (imoAsString.Length == 7)
actualIMO = imoAsString;
if ((actualIMO != null) && Int32.TryParse(actualIMO, out int _))
{
/* The integrity of an IMO number can be verified using its check digit. This is done by multiplying
* each of the first six digits by a factor of 2 to 7 corresponding to their position from right
* to left. The rightmost digit of this sum is the check digit.
* For example, for IMO 9074729: (9×7) + (0×6) + (7×5) + (4×4) + (7×3) + (2×2) = 139
*/
int sum = 0;
for (int i = 0, multiplier = 7; i < 6; i++, multiplier--)
{
sum += (Convert.ToInt32(actualIMO.Substring(i,1)) * multiplier);
}
int lastdigit = sum % 10; // letzte Stelle
if (Convert.ToInt32(actualIMO.Substring(6,1)) == lastdigit)
return true;
}
return false;
}
#region CoordinateTransformation
public static double NSWToDecimalDegrees(int nswCoordinate)
{
double result = Math.Floor(nswCoordinate / 600000.0);
result += (double) (nswCoordinate % 600000.0) / 600000.0;
return result;
}
public static int DecimalDegreesToNSW(double decimalDegree)
{
int result = ((int)decimalDegree) * 600000;
result += (int) ((decimalDegree - (int)decimalDegree) * 600000);
return result;
}
#endregion
}
}