Changed validation rules for WAS elements (Waste)

This commit is contained in:
Daniel Schick 2026-01-26 18:56:24 +01:00
parent 77c0491aa1
commit a1f6e6c113
4 changed files with 181 additions and 26 deletions

View File

@ -1027,6 +1027,7 @@ namespace ENI2
#region Kiel Canal Timing Plausibility #region Kiel Canal Timing Plausibility
{
if (!this.Core.IsTransit && (secMessage?.Elements.Count > 0) && (noanodMessage?.Elements.Count > 0)) if (!this.Core.IsTransit && (secMessage?.Elements.Count > 0) && (noanodMessage?.Elements.Count > 0))
{ {
SEC sec = secMessage.Elements[0] as SEC; SEC sec = secMessage.Elements[0] as SEC;
@ -1039,7 +1040,7 @@ namespace ENI2
(sec.KielCanalPassagePlannedIncomming < noa_nod.ETAToPortOfCall); (sec.KielCanalPassagePlannedIncomming < noa_nod.ETAToPortOfCall);
if (!sec.KielCanalPassagePlannedIncomming.HasValue) isValidIncoming = true; if (!sec.KielCanalPassagePlannedIncomming.HasValue) isValidIncoming = true;
if(!isValidIncoming) if (!isValidIncoming)
{ {
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Kiel Canal incoming implausible (ETD / ETA ports)!", null, "Kiel Canal timing", null, "SEC"); MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Kiel Canal incoming implausible (ETD / ETA ports)!", null, "Kiel Canal timing", null, "SEC");
mv.MessageGroupName = Properties.Resources.textOverview; mv.MessageGroupName = Properties.Resources.textOverview;
@ -1051,7 +1052,7 @@ namespace ENI2
((noa_nod.NextPort == "ZZUKN") || (sec.KielCanalPassagePlannedOutgoing < noa_nod.ETAToNextPort)); ((noa_nod.NextPort == "ZZUKN") || (sec.KielCanalPassagePlannedOutgoing < noa_nod.ETAToNextPort));
if (!sec.KielCanalPassagePlannedOutgoing.HasValue) isValidOutgoing = true; if (!sec.KielCanalPassagePlannedOutgoing.HasValue) isValidOutgoing = true;
if(!isValidOutgoing) if (!isValidOutgoing)
{ {
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Kiel Canal outgoing implausible (ETD / ETA ports)!", null, "Kiel Canal timing", null, "SEC"); MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Kiel Canal outgoing implausible (ETD / ETA ports)!", null, "Kiel Canal timing", null, "SEC");
mv.MessageGroupName = Properties.Resources.textOverview; mv.MessageGroupName = Properties.Resources.textOverview;
@ -1059,6 +1060,7 @@ namespace ENI2
} }
} }
} }
}
#endregion #endregion
@ -1212,6 +1214,127 @@ namespace ENI2
#endregion #endregion
#region WAS special max capa rules regarding next port
{
// see WAS-Regulation.docx in parent projects misc folder
if ((noanodMessage?.Elements.Count > 0) && wasMessage?.Elements.Count > 0)
{
NOA_NOD noa_nod = noanodMessage.Elements[0] as NOA_NOD;
WAS was = wasMessage.Elements[0] as WAS;
bool isSpecialNextPort = RuleEngine.IsSpecialNextPort(noa_nod.NextPort);
if (isSpecialNextPort)
{
foreach (Waste waste in was.Waste)
{
switch (waste.WasteType)
{
case 101:
case 102:
case 103:
case 104:
case 105:
case 401:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.5)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
case 501:
case 502:
case 503:
case 504:
case 505:
case 506:
case 507:
case 508:
case 509:
case 510:
case 511:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.25)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
case 601:
case 602:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.75)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
}
}
}
else
{
foreach (Waste waste in was.Waste)
{
switch (waste.WasteType)
{
case 101:
case 102:
case 103:
case 104:
case 105:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.25)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
case 401:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.5)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
case 501:
case 502:
case 503:
case 504:
case 505:
case 506:
case 507:
case 508:
case 509:
case 510:
case 511:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.2)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
case 601:
case 602:
if (waste.WasteAmountRetained_MTQ > waste.WasteCapacity_MTQ * 0.25)
{
MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "WAS", waste.Identifier, "WAS");
mv.MessageGroupName = Properties.Resources.textPortNotification;
vViolations.Add(mv);
}
break;
}
}
}
}
}
#endregion
#endregion #endregion
foreach (MessageError me in vErrors) foreach (MessageError me in vErrors)

View File

@ -97,6 +97,22 @@ namespace bsmd.database
#endregion #endregion
#region for extra waste validation
private static readonly HashSet<string> SpecialNextPortPrefixes = new HashSet<string>
{
"BE", "BG", "DK", "DE", "EE", "FI", "FR", "GR", "IR", "IT",
"HR", "LV", "LT", "LU", "MT", "NL", "AT", "PL", "PT", "RO",
"SE", "SK", "SL", "ES", "CZ", "HU", "CY", "NO", "IS", "GB", "GI"
};
private static readonly HashSet<string> SpecialNextPortExact = new HashSet<string>
{
"RUPRI", "RUULU", "RULED", "RUBLT", "RUKGD", "RUVYS"
};
#endregion
public enum LocodeMode public enum LocodeMode
{ {
STANDARD, STANDARD,
@ -131,6 +147,20 @@ namespace bsmd.database
public static LocodeValidHandler LocodeChecker { get { return _locodeChecker; } } public static LocodeValidHandler LocodeChecker { get { return _locodeChecker; } }
public static NationalityValidHandler NationalityChecker { get { return _nationalityChecker; } } public static NationalityValidHandler NationalityChecker { get { return _nationalityChecker; } }
/// <summary>
/// Used to test for special next port values for waste messages
/// </summary>
/// <param name="nextPort">a locode</param>
/// <returns>true if the next port is a special waste port</returns>
public static bool IsSpecialNextPort(string nextPort)
{
if (string.IsNullOrEmpty(nextPort) || nextPort.Length < 2)
return false;
return SpecialNextPortExact.Contains(nextPort) ||
SpecialNextPortPrefixes.Contains(nextPort.Substring(0, 2));
}
#region public static property validation #region public static property validation
public static void RegisterLocodeChecker(LocodeValidHandler handler) { _locodeChecker = handler; } public static void RegisterLocodeChecker(LocodeValidHandler handler) { _locodeChecker = handler; }

View File

@ -266,11 +266,13 @@ namespace bsmd.database
if (this.WasteAmountGeneratedTillNextPort_MTQ >= 10000) if (this.WasteAmountGeneratedTillNextPort_MTQ >= 10000)
errors.Add(RuleEngine.CreateError(ValidationCode.IMPLAUSIBLE, "Waste generated till next port too high", null, this.Title, this.Identifier, this.Tablename)); errors.Add(RuleEngine.CreateError(ValidationCode.IMPLAUSIBLE, "Waste generated till next port too high", null, this.Title, this.Identifier, this.Tablename));
if(this.WasteDisposalAmount_MTQ > this.WasteCapacity_MTQ) // Removed this for version 7.2.14 (new rules depending on next port implemented in ENI / DetailRootControl.cs)
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Disposal greater than capacity!", null, this.Title, this.Identifier, this.Tablename));
if((this.WasteAmountGeneratedTillNextPort_MTQ + this.WasteAmountRetained_MTQ) > this.WasteCapacity_MTQ) // if(this.WasteDisposalAmount_MTQ > this.WasteCapacity_MTQ)
violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Waste generated+retained greater than capacity!", null, this.Title, this.Identifier, this.Tablename)); // violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Disposal greater than capacity!", null, this.Title, this.Identifier, this.Tablename));
// if((this.WasteAmountGeneratedTillNextPort_MTQ + this.WasteAmountRetained_MTQ) > this.WasteCapacity_MTQ)
// violations.Add(RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Waste generated+retained greater than capacity!", null, this.Title, this.Identifier, this.Tablename));
} }
#endregion #endregion

BIN
misc/WAS-Regulation.docx Normal file

Binary file not shown.