diff --git a/ENI2/DetailRootControl.xaml.cs b/ENI2/DetailRootControl.xaml.cs index ee6bf533..6e50b0b8 100644 --- a/ENI2/DetailRootControl.xaml.cs +++ b/ENI2/DetailRootControl.xaml.cs @@ -837,8 +837,7 @@ namespace ENI2 private ValidationResult ValidateCore(List messagesSnapshot) { List vViolations = new List(); - List vErrors = new List(); - Dictionary counts = new Dictionary(); + List vErrors = new List(); RuleEngine ruleEngine = new RuleEngine(); foreach (Message aMessage in messagesSnapshot) @@ -847,15 +846,7 @@ namespace ENI2 List errors = new List(); List violations = new List(); - ruleEngine.ValidateMessage(aMessage, out errors, out violations); - - MessageValidationCounts messageCounts = new MessageValidationCounts - { - ErrorCount = errors.Count > 0 ? (int?)errors.Count : null, - ViolationCount = violations.Count > 0 ? (int?)violations.Count : null, - PositionViolationCount = violations.Count > 0 ? (int?)violations.Count(v => !v.Identifier.IsNullOrEmpty()) : null - }; - counts[aMessage] = messageCounts; + ruleEngine.ValidateMessage(aMessage, out errors, out violations); string messageGroup = this.MessageGroupForMessage(aMessage); @@ -1267,7 +1258,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1285,7 +1276,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1294,7 +1285,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1315,7 +1306,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1323,7 +1314,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1341,7 +1332,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1350,7 +1341,7 @@ namespace ENI2 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"); + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "Acc. to EU Regulation 2022/89 the amount retained on board is noticeably", null, "Waste", waste.Identifier, was.Tablename); mv.MessageGroupName = wasMessageGroup; vViolations.Add(mv); } @@ -1393,9 +1384,70 @@ namespace ENI2 } } + + // Recompute per-message counts after all global validations + Dictionary counts = new Dictionary(); + + int assignViolationCounter = 0; + int assignErrorCounter = 0; + + List tmpVList = new List(vViolations); + List tmpEList = new List(vErrors); + + foreach (Message aMessage in messagesSnapshot) + { + counts[aMessage] = new MessageValidationCounts(); + counts[aMessage].ErrorCount = tmpEList.Count(me => me.NotificationClass == aMessage.MessageNotificationClassDisplay); // generic + // special cases + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.WAS_RCPT) && (me.NotificationClass == "WasteReceived")); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IMDGPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IGCPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IBCPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IMSBCPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "MARPOL_Annex_I_Position") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IMDGPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IGCPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IBCPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IMSBCPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "MARPOL_Annex_I_Position") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.WAS) && (me.NotificationClass == "Waste")); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.SEC) && (me.NotificationClass == "LastTenPortFacilitiesCalled")); + counts[aMessage].ErrorCount += tmpEList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.SEC) && (me.NotificationClass == "ShipToShipActivitiesDuringLastTenPortFacilitiesCalled")); + + if (counts[aMessage].ErrorCount == 0) counts[aMessage].ErrorCount = null; // set to empty if nothing counted + assignErrorCounter += counts[aMessage].ErrorCount ?? 0; + + counts[aMessage].ViolationCount = vViolations.Count(mv => mv.NotificationClass == aMessage.MessageNotificationClassDisplay); // generic + // special cases + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.WAS_RCPT) && (me.NotificationClass == "WasteReceived")); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IMDGPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IGCPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IBCPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "IMSBCPosition") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZA) && (me.NotificationClass == "MARPOL_Annex_I_Position") && me.MessageGroupName.Contains("arrival", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IMDGPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IGCPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IBCPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "IMSBCPosition") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.HAZD) && (me.NotificationClass == "MARPOL_Annex_I_Position") && me.MessageGroupName.Contains("departure", StringComparison.OrdinalIgnoreCase)); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.WAS) && (me.NotificationClass == "Waste")); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.SEC) && (me.NotificationClass == "LastTenPortFacilitiesCalled")); + counts[aMessage].ViolationCount += tmpVList.Count(me => (aMessage.MessageNotificationClass == Message.NotificationClass.SEC) && (me.NotificationClass == "ShipToShipActivitiesDuringLastTenPortFacilitiesCalled")); + + if (counts[aMessage].ViolationCount == 0) counts[aMessage].ViolationCount = null; + + assignViolationCounter += counts[aMessage].ViolationCount ?? 0; + } + + + Trace.WriteLine(string.Format("Unassigned errors: {0}, unassigned violations: {1}", vErrors.Count - assignErrorCounter, vViolations.Count - assignViolationCounter)); + + return new ValidationResult(vViolations, vErrors, counts); } + + private void ApplyValidationResult(ValidationResult result, bool showMessages) { // TODO: clear highlighting @@ -1404,8 +1456,7 @@ namespace ENI2 Message aMessage = entry.Key; MessageValidationCounts messageCounts = entry.Value; aMessage.ErrorCount = messageCounts.ErrorCount; - aMessage.ViolationCount = messageCounts.ViolationCount; - aMessage.PositionViolationCount = messageCounts.PositionViolationCount; + aMessage.ViolationCount = messageCounts.ViolationCount; } foreach (MessageError me in result.Errors) diff --git a/ENI2/DetailViewControls/OverViewDetailControl.xaml.cs b/ENI2/DetailViewControls/OverViewDetailControl.xaml.cs index cc97db5f..98f3422f 100644 --- a/ENI2/DetailViewControls/OverViewDetailControl.xaml.cs +++ b/ENI2/DetailViewControls/OverViewDetailControl.xaml.cs @@ -341,8 +341,8 @@ namespace ENI2.DetailViewControls } } - public void UpdateCore() - { + public void UpdateCore() + { this.UnregisterTextboxChange(this.textBoxDisplayId); this.textBoxDisplayId.DataContext = null; @@ -367,13 +367,13 @@ namespace ENI2.DetailViewControls //}; //sid.UpdateId(this.Core.DisplayId); //sid.Show(); - this.Core.IsDirty = false; // ist ja schon gespeichert.. - } - - internal void RefreshMessageGrid() - { - this.dataGridMessages?.Items?.Refresh(); - } + this.Core.IsDirty = false; // ist ja schon gespeichert.. + } + + internal void RefreshMessageGrid() + { + this.dataGridMessages?.Items?.Refresh(); + } #endregion diff --git a/bsmd.database/Message.cs b/bsmd.database/Message.cs index 8f32a139..c95fb682 100644 --- a/bsmd.database/Message.cs +++ b/bsmd.database/Message.cs @@ -431,11 +431,6 @@ namespace bsmd.database /// public int? ViolationCount { get; set; } - /// - /// Number of violations during last validation that have the "identifier" set and are thus detected violations - /// from underlying list elements - /// - public int? PositionViolationCount { get; set; } /// /// Number of errors during last validation diff --git a/bsmd.database/WasteReceived.cs b/bsmd.database/WasteReceived.cs index e7d6dd40..1b4d8b14 100644 --- a/bsmd.database/WasteReceived.cs +++ b/bsmd.database/WasteReceived.cs @@ -76,7 +76,7 @@ namespace bsmd.database wasteReceived.id = reader.GetGuid(0); if (!reader.IsDBNull(1)) wasteReceived.WasteCode = reader.GetString(1); if (!reader.IsDBNull(2)) wasteReceived.WasteDescription = reader.GetString(2); - if (!reader.IsDBNull(3)) wasteReceived.AmountWasteReceived_MTQ = (float)reader.GetDouble(3); + if (!reader.IsDBNull(3)) wasteReceived.AmountWasteReceived_MTQ = (float)reader.GetDouble(3); if (!reader.IsDBNull(4)) wasteReceived.Identifier = reader.GetString(4); result.Add(wasteReceived); } @@ -111,7 +111,7 @@ namespace bsmd.database scmd.Parameters.AddWithValue("@P1", this.WAS_RCPT.Id); scmd.Parameters.AddWithNullableValue("@P2", this.WasteCode); scmd.Parameters.AddWithNullableValue("@P3", this.WasteDescription); - scmd.Parameters.AddWithNullableValue("@P4", this.AmountWasteReceived_MTQ); + scmd.Parameters.AddWithNullableValue("@P4", this.AmountWasteReceived_MTQ); scmd.Parameters.AddWithNullableValue("@P5", this.Identifier); if (this.IsNew)