949 lines
35 KiB
C#
949 lines
35 KiB
C#
// Copyright (c) 2015-present schick Informatik
|
|
// Description: Container für alle Meldeklassen
|
|
|
|
using System;
|
|
using System.Data;
|
|
using System.Data.SqlClient;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.ComponentModel;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace bsmd.database
|
|
{
|
|
/// <summary>
|
|
/// Basisklasse aller Nachrichtentypen, zentrale Klasse für die NSW App
|
|
/// </summary>
|
|
public class Message : DatabaseEntity, ISublistContainer, IComparable<Message>
|
|
{
|
|
|
|
#region Fields
|
|
|
|
private ReportingParty reportingParty;
|
|
|
|
#endregion
|
|
|
|
#region ANSWSortList
|
|
|
|
public static IList<NotificationClass> ANSWSortList = new ReadOnlyCollection<NotificationClass>(
|
|
new List<NotificationClass>{
|
|
NotificationClass.TIEFA,
|
|
NotificationClass.POBA,
|
|
NotificationClass.BKRA,
|
|
NotificationClass.TOWA,
|
|
NotificationClass.NOA_NOD,
|
|
NotificationClass.STAT,
|
|
NotificationClass.NAME,
|
|
NotificationClass.INFO,
|
|
NotificationClass.SERV,
|
|
NotificationClass.LADG,
|
|
NotificationClass.TIEFD,
|
|
NotificationClass.POBD,
|
|
NotificationClass.BKRD,
|
|
NotificationClass.TOWD,
|
|
NotificationClass.SEC,
|
|
NotificationClass.PRE72H,
|
|
NotificationClass.BPOL,
|
|
NotificationClass.CREW,
|
|
NotificationClass.PAS,
|
|
NotificationClass.MDH,
|
|
NotificationClass.HAZA,
|
|
NotificationClass.HAZD,
|
|
NotificationClass.WAS,
|
|
NotificationClass.ATA,
|
|
NotificationClass.ATD,
|
|
NotificationClass.AGNT,
|
|
NotificationClass.STO,
|
|
NotificationClass.CREWD,
|
|
NotificationClass.PASD
|
|
});
|
|
|
|
#endregion
|
|
|
|
#region Enumerations
|
|
|
|
/// <summary>
|
|
/// NSW notification class
|
|
/// </summary>
|
|
public enum NotificationClass
|
|
{
|
|
VISIT, // 0
|
|
TRANSIT, // 1
|
|
NOA_NOD, // 2
|
|
ATA,
|
|
ATD,
|
|
SEC, // 5
|
|
POBA,
|
|
POBD,
|
|
NAME,
|
|
TIEFA,
|
|
TIEFD, // 10
|
|
BKRA,
|
|
BKRD,
|
|
STAT,
|
|
LADG,
|
|
INFO, // 15
|
|
SERV,
|
|
PRE72H,
|
|
MDH,
|
|
WAS,
|
|
CREW, // 20
|
|
PAS,
|
|
BPOL,
|
|
TOWA,
|
|
TOWD,
|
|
HAZA, // 25
|
|
HAZD,
|
|
AGNT,
|
|
STO, // DK - only
|
|
CREWD,
|
|
PASD,
|
|
WAS_RCPT
|
|
}
|
|
|
|
public enum MessageStatus
|
|
{ ACCEPTED, REJECTED }
|
|
|
|
/// <summary>
|
|
/// Anhand dieses Filters und den Parametern können die Klassen das passende LoadQuery generieren
|
|
/// </summary>
|
|
public enum LoadFilter
|
|
{
|
|
ALL,
|
|
MESSAGETYPE,
|
|
REPORTINGPARTY,
|
|
MESSAGEHEADER,
|
|
BSMDSTATUS,
|
|
WETRIS_SHIP_ID,
|
|
MDH_ID,
|
|
POC30_ID,
|
|
WAS_ID,
|
|
WDSP_ID,
|
|
BPOL_ID,
|
|
SEC_ID,
|
|
HERBERG_FORMGUID,
|
|
BY_ID,
|
|
BY_CORE,
|
|
NOA_NODID,
|
|
HAZ_ID,
|
|
IMDG_ID,
|
|
REPORTSTATUS,
|
|
IMO_ETA_POC,
|
|
BY_VISITID,
|
|
BY_TRANSITID,
|
|
BY_CORE_ENI,
|
|
BY_CORE_EXCEL,
|
|
BY_CORE_HE,
|
|
CREATE_EXCEL,
|
|
SEARCH_CORE_FILTERS,
|
|
QUERY_NSW_STATUS,
|
|
NOT_DELETED,
|
|
DELETED,
|
|
IMPORTHEADER_ID,
|
|
BY_CORE_AND_CLASS,
|
|
BY_AGE,
|
|
WASRCPT_ID
|
|
}
|
|
|
|
/// <summary>
|
|
/// Message Status einer NSW Einzelnachricht
|
|
/// </summary>
|
|
public enum BSMDStatus
|
|
{
|
|
UNDEFINED = 0,
|
|
PREPARE,
|
|
TOSEND,
|
|
SENT,
|
|
SEND_FAILED,
|
|
CONFIRMED,
|
|
VIOLATION,
|
|
ERROR,
|
|
SUSPENDED = 8,
|
|
IN_USE,
|
|
UPDATED,
|
|
REPORT, // nur für diese Meldeklasse einen PDF Report erzeugen (geht danach wieder auf PREPARE)
|
|
SAVED, // veränderte Meldeklasse wird im ENI gespeichert
|
|
EXCEL // Meldeklasse wurde in Excel befüllt
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spezifiziert das gewünschte HIS zur Übertragung der Daten
|
|
/// </summary>
|
|
public enum NSWProvider
|
|
{
|
|
[Description("Unspecified")]
|
|
UNDEFINED,
|
|
|
|
DBH,
|
|
|
|
DAKOSY,
|
|
|
|
[Description("HIS-Nord")]
|
|
DUDR,
|
|
|
|
}
|
|
|
|
// Late to the party: generic flags Enum/Field
|
|
[Flags]
|
|
public enum MessageFlags : int
|
|
{
|
|
NONE = 0,
|
|
UNSENT_WARNING_SHOWN = 1,
|
|
UNCONFIRMED_WARNING_SHOWN = 2
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
public Message()
|
|
{
|
|
this.tablename = "[dbo].[MessageHeader]";
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// Dieser Wert wird vom NSW / HIS vergeben
|
|
/// </summary>
|
|
public string ClientRequestId { set; get; }
|
|
|
|
public Guid? MessageId { get; set; }
|
|
|
|
public Guid? MessageCoreId { get; set; }
|
|
|
|
public DateTime? SentAt { get; set; }
|
|
|
|
public string SentBy { get; set; }
|
|
|
|
public DateTime? ReceivedAt { get; set; }
|
|
|
|
public DateTime? RequestedAt { get; set; }
|
|
|
|
public bool Reset { get; set; }
|
|
|
|
public bool Cancel { get; set; }
|
|
|
|
public MessageStatus? Status { get; set; }
|
|
|
|
[ShowReport]
|
|
public DateTime? Created { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Vorwärts-Referenzen auf die von diesem Header-Element abhängigen speziellen Nachrichten-Datensätzen
|
|
/// Folgende Objekte können pro Nachricht n-fach vorkommen
|
|
/// BRKA, BRKD, LADG, CREW, PAS, SERV, TOWA, TOWD, STO, CREWD, PASD
|
|
/// sonst hat die Liste immer ein Element
|
|
/// </summary>
|
|
public ObservableCollection<DatabaseEntity> Elements { get; } = new ObservableCollection<DatabaseEntity>();
|
|
|
|
/// <summary>
|
|
/// Der Meldende
|
|
/// </summary>
|
|
public ReportingParty ReportingParty
|
|
{
|
|
get { return this.reportingParty; }
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
this.ReportingPartyId = null;
|
|
}
|
|
else
|
|
{
|
|
this.ReportingPartyId = value.Id;
|
|
}
|
|
this.reportingParty = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Status für Services
|
|
/// </summary>
|
|
public BSMDStatus InternalStatus { get; set; }
|
|
|
|
/// <summary>
|
|
/// Vorheriger Status (z.B. für nach der Report-Generierung), wird nicht immer gesetzt
|
|
/// </summary>
|
|
public BSMDStatus? LastStatus { get; set; }
|
|
|
|
/// <summary>
|
|
/// Erweiterte Erläuterung für Status(-wechsel) zur Darstellung im ENI
|
|
/// </summary>
|
|
public string StatusInfo { get; set; }
|
|
|
|
/// <summary>
|
|
/// die zur Kommunikation zu verwendende HIS Schnittstelle
|
|
/// </summary>
|
|
public NSWProvider HIS { get; set; }
|
|
|
|
/// <summary>
|
|
/// Fehlerliste (Rückgabe vom NSW)
|
|
/// </summary>
|
|
public List<MessageError> ErrorList { get; } = new List<MessageError>();
|
|
|
|
/// <summary>
|
|
/// Violation-Liste (Rückgabe vom NSW)
|
|
/// </summary>
|
|
public List<MessageViolation> ViolationList { get; } = new List<MessageViolation>();
|
|
|
|
/// <summary>
|
|
/// Liste mit "System"-Errors (HIS-Nord)
|
|
/// </summary>
|
|
public List<SystemError> SystemErrorList { get; } = new List<SystemError>();
|
|
|
|
/// <summary>
|
|
/// Property to overwrite reporting party in certain circumstances (other melder meldet)
|
|
/// </summary>
|
|
public Guid? ReportingPartyId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Urheber der Nachricht (Excel oder HE)
|
|
/// </summary>
|
|
public string CreatedBy { get; set; }
|
|
|
|
/// <summary>
|
|
/// Bearbeiter für Änderungshistorie (=Name des angemeldeten Melders), wird vom ENI-2 Speicherprozess befüllt
|
|
/// </summary>
|
|
public string ChangedBy { get; set; }
|
|
|
|
/// <summary>
|
|
/// Database last "Changed" date display
|
|
/// </summary>
|
|
public DateTime? Changed { get; private set; }
|
|
|
|
/// <summary>
|
|
/// ENI-2 detail group text
|
|
/// </summary>
|
|
public string ENINotificationDetailGroup { get; set; }
|
|
|
|
/// <summary>
|
|
/// Hilfsproperty zum schnellen Auffinden der passenden Gruppe
|
|
/// </summary>
|
|
public int ENINotificationDetailIndex { get; set; }
|
|
|
|
/// <summary>
|
|
/// Hilfsproperty zum Speichern des Icon-Pfads in ENI-2
|
|
/// </summary>
|
|
public string ENINotificationIconString { get; set; }
|
|
|
|
/// <summary>
|
|
/// ENI Display flag
|
|
/// </summary>
|
|
public bool HasErrors { get { return !this.ErrorList.IsNullOrEmpty(); } }
|
|
|
|
/// <summary>
|
|
/// ENI Display flag
|
|
/// </summary>
|
|
public bool HasViolations { get { return !this.ViolationList.IsNullOrEmpty(); } }
|
|
|
|
/// <summary>
|
|
/// Flag zeigt an ob unbearbeitete ImportValues für die Meldeklasse vorhanden sind
|
|
/// </summary>
|
|
public bool HasUpdates { get; set; }
|
|
|
|
/// <summary>
|
|
/// ENI Display flag
|
|
/// </summary>
|
|
public bool HasSystemErrors { get { return !this.SystemErrorList.IsNullOrEmpty(); } }
|
|
|
|
/// <summary>
|
|
/// Flag zeigt an ob ein Benutzer einen Reminder für ein Feld der Meldeklasse gesetzt hat
|
|
/// </summary>
|
|
public bool HasReminder { get; set; }
|
|
|
|
/// <summary>
|
|
/// ENI display flag: send complete
|
|
/// </summary>
|
|
public bool SuccessfullySent
|
|
{
|
|
get
|
|
{
|
|
return this.SystemErrorList.IsNullOrEmpty() &&
|
|
this.ViolationList.IsNullOrEmpty() &&
|
|
this.ErrorList.IsNullOrEmpty() &&
|
|
this.Status.HasValue &&
|
|
!this.Reset &&
|
|
(this.Status.Value == MessageStatus.ACCEPTED);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dieses Flag wird gesetzt, sobald die Meldeklasse *einmal* erfolgreich gesendet wurde. Es bleibt bestehen, auch
|
|
/// wenn ein nachfolgender Sendevorgang auf einen Fehler läuft. Neue Interpretation (10.11.17):
|
|
/// Das Flag bedeutet, dass beim NSW Inhalte hinterlegt sind
|
|
/// -> bei einem erfolgreichen Reset muss das Flag wieder zurück gesetzt werden
|
|
/// </summary>
|
|
public bool? SendSuccess { get; set; }
|
|
|
|
public bool UnsentMessageWarningShown
|
|
{
|
|
get { return this.IsFlagSet(MessageFlags.UNSENT_WARNING_SHOWN); }
|
|
set { this.SetFlag(value, MessageFlags.UNSENT_WARNING_SHOWN); }
|
|
}
|
|
|
|
public bool UnconfirmedMessageWarningShown
|
|
{
|
|
get { return this.IsFlagSet(MessageFlags.UNCONFIRMED_WARNING_SHOWN); }
|
|
set { this.SetFlag(value, MessageFlags.UNCONFIRMED_WARNING_SHOWN); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Speicher-Int für generische Flags
|
|
/// </summary>
|
|
public int Flags { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region IDatabaseEntity implementation
|
|
|
|
public override void PrepareSave(IDbCommand dbCommand)
|
|
{
|
|
SqlCommand cmd = dbCommand as SqlCommand;
|
|
|
|
if (this.ClientRequestId != null)
|
|
cmd.Parameters.AddWithValue("@CLIENTREQUESTID", Guid.Parse(this.ClientRequestId));
|
|
else
|
|
cmd.Parameters.AddWithValue("@CLIENTREQUESTID", DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@MESSAGECOREID", this.MessageCore.Id);
|
|
if (this.MessageId.HasValue)
|
|
cmd.Parameters.AddWithValue("@MESSAGEID", this.MessageId.Value);
|
|
else
|
|
cmd.Parameters.AddWithValue("@MESSAGEID", DBNull.Value);
|
|
if (this.SentAt.HasValue)
|
|
cmd.Parameters.AddWithValue("@SENTAT", this.SentAt.Value);
|
|
else
|
|
cmd.Parameters.AddWithValue("@SENTAT", DBNull.Value);
|
|
if (this.ReceivedAt.HasValue)
|
|
cmd.Parameters.AddWithValue("@RECEIVEDAT", this.ReceivedAt.Value);
|
|
else
|
|
cmd.Parameters.AddWithValue("@RECEIVEDAT", DBNull.Value);
|
|
if (this.RequestedAt.HasValue)
|
|
cmd.Parameters.AddWithValue("@REQUESTEDAT", this.RequestedAt.Value);
|
|
else
|
|
cmd.Parameters.AddWithValue("@REQUESTEDAT", DBNull.Value);
|
|
cmd.Parameters.AddWithValue("@NOTIFICATIONCLASS", (int)this.MessageNotificationClass);
|
|
cmd.Parameters.AddWithValue("@RESET", this.Reset);
|
|
cmd.Parameters.AddWithValue("@CANCEL", this.Cancel);
|
|
if (this.Status.HasValue)
|
|
cmd.Parameters.AddWithValue("@STATUS", (int)this.Status.Value);
|
|
else
|
|
cmd.Parameters.AddWithValue("@STATUS", DBNull.Value);
|
|
|
|
cmd.Parameters.AddWithNullableValue("@REPORTINGPARTYID", this.ReportingPartyId);
|
|
cmd.Parameters.AddWithValue("@BSMDSTATUS", this.InternalStatus);
|
|
cmd.Parameters.AddWithNullableValue("@LASTSTATUS", this.LastStatus);
|
|
cmd.Parameters.AddWithValue("@HIS", this.HIS);
|
|
cmd.Parameters.AddWithNullableValue("@CREATEDBY", this.CreatedBy);
|
|
cmd.Parameters.AddWithNullableValue("@CHANGEDBY", this.ChangedBy);
|
|
cmd.Parameters.AddWithNullableValue("@STATUSINFO", this.StatusInfo);
|
|
cmd.Parameters.AddWithNullableValue("@SENDSUCCESS", this.SendSuccess);
|
|
cmd.Parameters.AddWithNullableValue("@SENTBY", this.SentBy);
|
|
cmd.Parameters.AddWithValue("@FLAGS", this.Flags);
|
|
|
|
if (this.IsNew)
|
|
{
|
|
this.CreateId();
|
|
cmd.Parameters.AddWithValue("@ID", this.Id);
|
|
string query = string.Format("INSERT INTO {0} (Id, ClientRequestId, MessageCoreId, MessageId, SentAt, ReceivedAt, RequestedAt, NotificationClass, Reset, Cancel, Status, ReportingPartyId, BSMDStatus, LastStatus, HIS, CreatedBy, ChangedBy, StatusInfo, SendSuccess, SentBy, Flags) " +
|
|
"VALUES (@ID, @CLIENTREQUESTID, @MESSAGECOREID, @MESSAGEID, @SENTAT, @RECEIVEDAT, @REQUESTEDAT, @NOTIFICATIONCLASS, @RESET, @CANCEL, @STATUS, @REPORTINGPARTYID, @BSMDSTATUS, @LASTSTATUS, @HIS, @CREATEDBY, @CHANGEDBY, @STATUSINFO, @SENDSUCCESS, @SENTBY, @FLAGS)",
|
|
this.Tablename);
|
|
cmd.CommandText = query;
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue("@ID", this.Id);
|
|
cmd.CommandText = string.Format("UPDATE {0} SET ClientRequestId = @CLIENTREQUESTID, MessageId = @MESSAGEID, SentAt = @SENTAT, ReceivedAt = @RECEIVEDAT, RequestedAt = @REQUESTEDAT, " +
|
|
"NotificationClass = @NOTIFICATIONCLASS, Reset = @RESET, Cancel = @CANCEL, Status = @STATUS, ReportingPartyId = @REPORTINGPARTYID, BSMDStatus = @BSMDSTATUS, LastStatus = @LASTSTATUS, HIS = @HIS, " +
|
|
"CreatedBy = @CREATEDBY, ChangedBy = @CHANGEDBY, StatusInfo = @STATUSINFO, SendSuccess = @SENDSUCCESS, SentBy = @SENTBY, Flags = @FLAGS WHERE Id = @ID", this.Tablename);
|
|
}
|
|
}
|
|
|
|
|
|
public override void PrepareLoadCommand(IDbCommand cmd, LoadFilter filter, params object[] criteria )
|
|
{
|
|
string query = string.Format("SELECT Id, ClientRequestId, MessageCoreId, MessageId, SentAt, ReceivedAt, RequestedAt, NotificationClass, " +
|
|
"Reset, Cancel, Status, ReportingPartyId, BSMDStatus, LastStatus, HIS, Created, CreatedBy, ChangedBy, Changed, StatusInfo, SendSuccess, SentBy, Flags FROM {0} ",
|
|
this.Tablename);
|
|
|
|
switch (filter)
|
|
{
|
|
case LoadFilter.REPORTINGPARTY:
|
|
{
|
|
query += "WHERE ReportingPartyId = @RPID";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("RPID", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BSMDSTATUS:
|
|
{
|
|
query += "WHERE BSMDStatus = @BSMDSTATUS";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@BSMDSTATUS", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BY_ID:
|
|
{
|
|
query += "WHERE Id = @ID";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@ID", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BY_CORE:
|
|
{
|
|
query += "WHERE MessageCoreId = @COREID";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@COREID", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BY_CORE_ENI:
|
|
{
|
|
query += "WHERE MessageCoreId = @COREID AND ChangedBy IS NOT NULL";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@COREID", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BY_CORE_EXCEL:
|
|
{
|
|
query += "WHERE MessageCoreId = @COREID AND CreatedBy = 'EXCEL'";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@COREID", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BY_CORE_HE:
|
|
{
|
|
query += "WHERE MessageCoreId = @COREID AND (CreatedBy = 'HE' OR CreatedBy IS NULL)"; // TODO: letzte Bedingung nach Übergangsphase entfernen
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@COREID", criteria[0]);
|
|
break;
|
|
}
|
|
case LoadFilter.BY_CORE_AND_CLASS:
|
|
{
|
|
query += "WHERE MessageCoreId = @COREID AND NotificationClass = @CLASS";
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@COREID", criteria[0]);
|
|
((SqlCommand)cmd).Parameters.AddWithValue("@CLASS", criteria[1]);
|
|
break;
|
|
}
|
|
case LoadFilter.ALL:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
cmd.CommandText = query;
|
|
}
|
|
|
|
public override List<DatabaseEntity> LoadList(IDataReader reader)
|
|
{
|
|
List<DatabaseEntity> result = new List<DatabaseEntity>();
|
|
while (reader.Read())
|
|
{
|
|
Message msg = new Message();
|
|
msg.id = reader.GetGuid(0);
|
|
if (!reader.IsDBNull(1)) msg.ClientRequestId = reader.GetGuid(1).ToString();
|
|
msg.MessageCoreId = reader.GetGuid(2);
|
|
if(!reader.IsDBNull(3)) msg.MessageId = reader.GetGuid(3);
|
|
if (!reader.IsDBNull(4)) msg.SentAt = reader.GetDateTime(4);
|
|
if (!reader.IsDBNull(5)) msg.ReceivedAt = reader.GetDateTime(5);
|
|
if (!reader.IsDBNull(6)) msg.RequestedAt = reader.GetDateTime(6);
|
|
if (!reader.IsDBNull(7)) msg.MessageNotificationClass = (NotificationClass) Enum.ToObject(typeof(NotificationClass), reader.GetByte(7));
|
|
if (!reader.IsDBNull(8)) msg.Reset = reader.GetBoolean(8);
|
|
if (!reader.IsDBNull(9)) msg.Cancel = reader.GetBoolean(9);
|
|
if (!reader.IsDBNull(10)) msg.Status = (MessageStatus)Enum.ToObject(typeof(MessageStatus), reader.GetByte(10));
|
|
if (!reader.IsDBNull(11)) msg.ReportingPartyId = reader.GetGuid(11);
|
|
if (!reader.IsDBNull(12)) msg.InternalStatus = (BSMDStatus)Enum.ToObject(typeof(BSMDStatus), reader.GetByte(12));
|
|
if (!reader.IsDBNull(13)) msg.LastStatus = (BSMDStatus)Enum.ToObject(typeof(BSMDStatus), reader.GetByte(13));
|
|
if (!reader.IsDBNull(14)) msg.HIS = (NSWProvider)Enum.ToObject(typeof(NSWProvider), reader.GetByte(14));
|
|
if (!reader.IsDBNull(15)) msg.Created = reader.GetDateTime(15);
|
|
if (!reader.IsDBNull(16)) msg.CreatedBy = reader.GetString(16);
|
|
if (!reader.IsDBNull(17)) msg.ChangedBy = reader.GetString(17);
|
|
if (!reader.IsDBNull(18)) msg.Changed = reader.GetDateTime(18);
|
|
if (!reader.IsDBNull(19)) msg.StatusInfo = reader.GetString(19);
|
|
if (!reader.IsDBNull(20)) msg.SendSuccess = reader.GetBoolean(20);
|
|
if (!reader.IsDBNull(21)) msg.SentBy = reader.GetString(21);
|
|
if (!reader.IsDBNull(22)) msg.Flags = reader.GetInt32(22);
|
|
result.Add(msg);
|
|
}
|
|
reader.Close();
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public static helpers
|
|
|
|
public static void AssignReportingParties(List<Message> messages, Dictionary<Guid, ReportingParty> reportingParties)
|
|
{
|
|
foreach (Message message in messages)
|
|
{
|
|
if (message.ReportingPartyId.HasValue && reportingParties.ContainsKey(message.ReportingPartyId.Value))
|
|
message.reportingParty = reportingParties[message.ReportingPartyId.Value];
|
|
}
|
|
}
|
|
|
|
public static void AssignMessageCores(List<Message> messages, Dictionary<Guid, MessageCore> messageCores)
|
|
{
|
|
foreach (Message message in messages)
|
|
{
|
|
if (message.MessageCoreId.HasValue && messageCores.ContainsKey(message.MessageCoreId.Value))
|
|
message.MessageCore = messageCores[message.MessageCoreId.Value];
|
|
}
|
|
}
|
|
|
|
public static bool IsListClass(NotificationClass notificationClass)
|
|
{
|
|
|
|
switch(notificationClass)
|
|
{
|
|
case NotificationClass.BKRA:
|
|
case NotificationClass.BKRD:
|
|
case NotificationClass.CREW:
|
|
case NotificationClass.CREWD:
|
|
case NotificationClass.LADG:
|
|
case NotificationClass.PAS:
|
|
case NotificationClass.PASD:
|
|
case NotificationClass.SERV:
|
|
case NotificationClass.STO:
|
|
case NotificationClass.TOWA:
|
|
case NotificationClass.TOWD:
|
|
case NotificationClass.WAS_RCPT:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Some message classes are (currently) skipped for validation
|
|
/// </summary>
|
|
public bool EvaluateForValidation(bool isTransit)
|
|
{
|
|
|
|
bool result = true;
|
|
switch (this.MessageNotificationClass)
|
|
{
|
|
case NotificationClass.BKRD:
|
|
case NotificationClass.PRE72H:
|
|
case NotificationClass.TIEFD:
|
|
case NotificationClass.NAME:
|
|
case NotificationClass.INFO:
|
|
case NotificationClass.ATA:
|
|
case NotificationClass.ATD:
|
|
case NotificationClass.LADG:
|
|
case NotificationClass.SERV:
|
|
case NotificationClass.WAS:
|
|
case NotificationClass.TOWD:
|
|
case NotificationClass.HAZD:
|
|
case NotificationClass.WAS_RCPT:
|
|
if (isTransit) result = false;
|
|
break;
|
|
case NotificationClass.VISIT:
|
|
case NotificationClass.TRANSIT:
|
|
case NotificationClass.CREWD:
|
|
case NotificationClass.PASD:
|
|
case NotificationClass.STO:
|
|
result = false;
|
|
break;
|
|
default: break;
|
|
}
|
|
return result;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ISublistContainer implementation
|
|
|
|
public ISublistElement GetSublistElementWithIdentifier(string identifier)
|
|
{
|
|
foreach (DatabaseEntity entity in this.Elements)
|
|
{
|
|
ISublistElement sublistElement = entity as ISublistElement;
|
|
if (sublistElement?.Identifier != null)
|
|
{
|
|
if (((ISublistElement)entity).Identifier.Equals(identifier))
|
|
return entity as ISublistElement;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
[Browsable(false)]
|
|
[JsonIgnore]
|
|
public int NumberOfExcelRows
|
|
{
|
|
get
|
|
{
|
|
switch (this.MessageNotificationClass)
|
|
{
|
|
case NotificationClass.BKRA: return 5;
|
|
case NotificationClass.BKRD: return 5;
|
|
case NotificationClass.LADG: return 36;
|
|
case NotificationClass.CREW: return 40;
|
|
case NotificationClass.CREWD: return 40;
|
|
case NotificationClass.PAS: return 40;
|
|
case NotificationClass.PASD: return 40;
|
|
case NotificationClass.TOWA: return 5;
|
|
case NotificationClass.TOWD: return 5;
|
|
case NotificationClass.STO: return 10;
|
|
case NotificationClass.WAS_RCPT: return 5;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SaveElements()
|
|
{
|
|
if (CanDoBulkSave())
|
|
{
|
|
this.BulkSaveElements();
|
|
}
|
|
else
|
|
{
|
|
foreach (DatabaseEntity dbEntity in this.Elements)
|
|
{
|
|
DBManager.Instance.Save(dbEntity);
|
|
if (dbEntity is ISublistContainer sublistContainer)
|
|
{
|
|
sublistContainer.SaveElements();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DeleteElements()
|
|
{
|
|
foreach (MessageError me in ErrorList)
|
|
DBManager.Instance.Delete(me);
|
|
foreach (MessageViolation mv in ViolationList)
|
|
DBManager.Instance.Delete(mv);
|
|
foreach (SystemError se in SystemErrorList)
|
|
DBManager.Instance.Delete(se);
|
|
|
|
foreach (DatabaseEntity dbEntity in this.Elements)
|
|
{
|
|
if (dbEntity is ISublistContainer sublistContainer)
|
|
{
|
|
(sublistContainer).DeleteElements();
|
|
}
|
|
DBManager.Instance.Delete(dbEntity);
|
|
}
|
|
this.Elements.Clear();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IMessageParagraph implementation
|
|
|
|
public override string Title
|
|
{
|
|
get
|
|
{
|
|
if (this.Elements.Count > 0)
|
|
{
|
|
return this.Elements[0].Title;
|
|
}
|
|
else
|
|
{
|
|
return MessageNotificationClassDisplay;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override string Subtitle
|
|
{
|
|
get
|
|
{
|
|
if (this.Elements.Count > 0)
|
|
return this.Elements[0].Subtitle;
|
|
else
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
public override List<KeyValuePair<string, string>> MessageText
|
|
{
|
|
get
|
|
{
|
|
switch (this.MessageNotificationClass)
|
|
{
|
|
case NotificationClass.VISIT:
|
|
case NotificationClass.TRANSIT:
|
|
return base.MessageText;
|
|
|
|
case NotificationClass.ATA:
|
|
case NotificationClass.ATD:
|
|
case NotificationClass.BPOL:
|
|
case NotificationClass.HAZA:
|
|
case NotificationClass.HAZD:
|
|
case NotificationClass.INFO:
|
|
case NotificationClass.MDH:
|
|
case NotificationClass.NAME:
|
|
case NotificationClass.NOA_NOD:
|
|
case NotificationClass.POBA:
|
|
case NotificationClass.POBD:
|
|
case NotificationClass.PRE72H:
|
|
case NotificationClass.SEC:
|
|
case NotificationClass.STAT:
|
|
case NotificationClass.AGNT:
|
|
case NotificationClass.TIEFA:
|
|
case NotificationClass.TIEFD:
|
|
case NotificationClass.WAS:
|
|
if (this.Elements.Count > 0)
|
|
{
|
|
return this.Elements[0].MessageText;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool ShowChildrenAsTable
|
|
{
|
|
get
|
|
{
|
|
switch (this.MessageNotificationClass)
|
|
{
|
|
case NotificationClass.CREW:
|
|
case NotificationClass.PAS:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override List<IMessageParagraph> ChildParagraphs
|
|
{
|
|
get
|
|
{
|
|
switch (this.MessageNotificationClass)
|
|
{
|
|
case NotificationClass.VISIT:
|
|
case NotificationClass.TRANSIT:
|
|
return null;
|
|
|
|
case NotificationClass.ATA:
|
|
case NotificationClass.ATD:
|
|
case NotificationClass.BPOL:
|
|
case NotificationClass.HAZA:
|
|
case NotificationClass.HAZD:
|
|
case NotificationClass.INFO:
|
|
case NotificationClass.MDH:
|
|
case NotificationClass.NAME:
|
|
case NotificationClass.NOA_NOD:
|
|
case NotificationClass.POBA:
|
|
case NotificationClass.POBD:
|
|
case NotificationClass.PRE72H:
|
|
case NotificationClass.SEC:
|
|
case NotificationClass.STAT:
|
|
case NotificationClass.AGNT:
|
|
case NotificationClass.TIEFA:
|
|
case NotificationClass.TIEFD:
|
|
case NotificationClass.WAS:
|
|
if (this.Elements.Count > 0)
|
|
{
|
|
return this.Elements[0].ChildParagraphs;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
default:
|
|
List<IMessageParagraph> result = new List<IMessageParagraph>();
|
|
foreach (DatabaseEntity element in this.Elements)
|
|
result.Add(element);
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IComparable implementation
|
|
|
|
/// <summary>
|
|
/// Sort messages by notification class
|
|
/// </summary>
|
|
public int CompareTo(Message other)
|
|
{
|
|
return this.MessageNotificationClass.CompareTo(other.MessageNotificationClass);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IClonable implementation
|
|
|
|
public override object Clone()
|
|
{
|
|
// hier gibt es kein Memberwise Clone, weil die meisten Felder zurück gesetzt werden
|
|
|
|
Message root = new Message();
|
|
root.MessageNotificationClass = this.MessageNotificationClass;
|
|
root.InternalStatus = BSMDStatus.PREPARE;
|
|
foreach (DatabaseEntity databaseEntity in this.Elements)
|
|
{
|
|
DatabaseEntity clonedElement = databaseEntity.Clone() as DatabaseEntity;
|
|
clonedElement.MessageHeader = root;
|
|
root.Elements.Add(clonedElement);
|
|
}
|
|
return root;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region private methods
|
|
|
|
private bool IsFlagSet(MessageFlags flag)
|
|
{
|
|
return (this.Flags & (int)flag) != 0;
|
|
}
|
|
|
|
private void SetFlag(bool value, MessageFlags flag)
|
|
{
|
|
if (value) this.Flags |= (int)flag;
|
|
else this.Flags &= (int)~flag;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulk save is actually bulk insert and can only be done for certain
|
|
/// message classes where bulk save is implemented
|
|
/// </summary>
|
|
private bool CanDoBulkSave()
|
|
{
|
|
if(this.MessageNotificationClass == NotificationClass.CREW ||
|
|
this.MessageNotificationClass == NotificationClass.CREWD ||
|
|
this.MessageNotificationClass == NotificationClass.PAS ||
|
|
this.MessageNotificationClass == NotificationClass.PASD)
|
|
{
|
|
foreach (DatabaseEntity subEntity in this.Elements)
|
|
if (!subEntity.IsNew)
|
|
return false;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void BulkSaveElements()
|
|
{
|
|
if (this.Elements.Count == 0) return; // NOP
|
|
if(this.Elements[0] is IBulkSaver ibs)
|
|
{
|
|
DataTable dt = ibs.PrepareBulkInsert(new List<DatabaseEntity>(this.Elements));
|
|
DBManager.Instance.PerformBulkInsert(dt);
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("bulk save called on classes that do not support it");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|