From dd2c8723b0654dd5b3a87ae121bf07a69b66ef91 Mon Sep 17 00:00:00 2001 From: Daniel Schick Date: Fri, 11 Feb 2022 09:50:44 +0100 Subject: [PATCH] Validation rules implemented --- ENI2/App.config | 6 +- ENI2/DetailRootControl.xaml.cs | 186 +++++++++++++++++- .../BorderPoliceDetailControl.xaml.cs | 23 +++ SQL/Update_6.x_To_7.0.sql | 10 + bsmd.database/CREW.cs | 44 +++++ bsmd.database/DBManager.cs | 20 +- bsmd.database/PAS.cs | 58 ++++++ bsmd.database/ValidationAttribute.cs | 7 + 8 files changed, 334 insertions(+), 20 deletions(-) diff --git a/ENI2/App.config b/ENI2/App.config index 4c7c4bc1..234c2e31 100644 --- a/ENI2/App.config +++ b/ENI2/App.config @@ -26,11 +26,11 @@ 1000 - http://192.168.2.24/LockingService/LockingService.svc + http://heupferd/bsmd.LockingService/LockingService.svc - Initial Catalog=nsw;Data Source=192.168.2.24\SQLEXPRESS;Uid=dfuser;pwd=dfpasswd;Persist Security Info=False;Connection Reset=false - + Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=E:\DATA\DB\NSW.MDF;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False + diff --git a/ENI2/DetailRootControl.xaml.cs b/ENI2/DetailRootControl.xaml.cs index 59be03ad..00e93963 100644 --- a/ENI2/DetailRootControl.xaml.cs +++ b/ENI2/DetailRootControl.xaml.cs @@ -686,12 +686,15 @@ namespace ENI2 } #region 12.11.18 / 6.3.21: globale Plausi-Prüfungen - Message crewMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.CREW); - Message pasMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.PAS); + Message crewaMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.CREW); + Message crewdMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.CREWD); + Message pasaMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.PAS); + Message pasdMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.PASD); Message pobaMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.POBA); Message secMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.SEC); Message noanodMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.NOA_NOD); Message mdhMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.MDH); + Message was_rcptMessage = _messages.Find(message => message.MessageNotificationClass == Message.NotificationClass.WAS_RCPT); #region CREW / PAS Count Plausibility @@ -699,14 +702,14 @@ namespace ENI2 { POBA poba = pobaMessage.Elements[0] as POBA; - if (crewMessage.Elements.Count != poba.TotalCrewMembersOnBoardUponArrival) + if (crewaMessage.Elements.Count != poba.TotalCrewMembersOnBoardUponArrival) { MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "POBA crew member count different from CREW count!", null, "Crew count mismatch", null, "CREW"); mv.MessageGroupName = Properties.Resources.textOverview; vViolations.Add(mv); } - if(pasMessage.Elements.Count != poba.TotalPassengersOnBoardUponArrival) + if(pasaMessage.Elements.Count != poba.TotalPassengersOnBoardUponArrival) { MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.IMPLAUSIBLE, "POBA passenger count different from PAS count!", null, "Passenger count mismatch", null, "PAS"); mv.MessageGroupName = Properties.Resources.textOverview; @@ -716,9 +719,175 @@ namespace ENI2 #endregion + #region CREW/PAS Schengen Plausibility + + // Wir können davon ausgehen, dass bei allen Unterelementen die Flags gleich gesetzt sind. Das wird im Import und BorderPoliceDetailControl sichergestellt. + + if(crewaMessage.Elements.Count > 0) + { + CREW crewaFirst = crewaMessage.Elements[0] as CREW; + bool crewaIsSchengen = crewaFirst.NotificationSchengen ?? false; + if (!((crewaFirst.NotificationPAX ?? false) || crewaIsSchengen)) // mindestens eins der beiden + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V181, "Wrong selection", null, "CREWA", null, "CREWA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + + foreach(CREW crewa in crewaMessage.Elements) + { + if(crewaIsSchengen && !crewa.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V182, "No Schengen details", null, "CREWA", crewa.Identifier, "CREWA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if(!crewaIsSchengen && crewa.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V182, "Schengen details but checkbox not set", null, "CREWA", crewa.Identifier, "CREWA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + } + } + + if (crewdMessage.Elements.Count > 0) + { + CREWD crewdFirst = crewdMessage.Elements[0] as CREWD; + bool crewdIsSchengen = crewdFirst.NotificationSchengen ?? false; + if (!((crewdFirst.NotificationPAX ?? false) || crewdIsSchengen)) // mindestens eins der beiden + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V181, "Wrong selection", null, "CREWD", null, "CREWD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + + foreach (CREWD crewd in crewdMessage.Elements) + { + if (crewdIsSchengen && !crewd.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V182, "No Schengen details", null, "CREWD", crewd.Identifier, "CREWD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if (!crewdIsSchengen && crewd.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V182, "Schengen details but checkbox not set", null, "CREWD", crewd.Identifier, "CREWD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + } + } + + if(pasaMessage.Elements.Count > 0) + { + PAS pasFirst = pasaMessage.Elements[0] as PAS; + bool pasIsSchengen = pasFirst.NotificationSchengen ?? false; + bool pasIsPAX = pasFirst.NotificationPAX ?? false; + if (!((pasFirst.NotificationPAX ?? false) || pasIsSchengen)) // mindestens eins der beiden + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V201, "Wrong selection", null, "PASA", null, "PASA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + + foreach (PAS pasa in pasaMessage.Elements) + { + if (pasIsSchengen && !pasa.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V202, "No Schengen details", null, "PASA", pasa.Identifier, "PASA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if (!pasIsSchengen && pasa.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V202, "Schengen details but checkbox not set", null, "PASA", pasa.Identifier, "PASA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if(pasIsPAX && !pasa.HasPAXDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V203, "No PAX details", null, "PASA", pasa.Identifier, "PASA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if(!pasIsPAX && pasa.HasPAXDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V203, "PAX details but checkbox not set", null, "PASA", pasa.Identifier, "PASA"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + } + } + + if (pasdMessage.Elements.Count > 0) + { + PASD pasdFirst = pasdMessage.Elements[0] as PASD; + bool pasdIsSchengen = pasdFirst.NotificationSchengen ?? false; + bool pasdIsPAX = pasdFirst.NotificationPAX ?? false; + if (!((pasdFirst.NotificationPAX ?? false) || pasdIsSchengen)) // mindestens eins der beiden + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V201, "Wrong selection", null, "PASD", null, "PASD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + + foreach (PASD pasd in pasdMessage.Elements) + { + if (pasdIsSchengen && !pasd.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V202, "No Schengen details", null, "PASD", pasd.Identifier, "PASD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if (!pasdIsSchengen && pasd.HasSchengenDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V202, "Schengen details but checkbox not set", null, "PASD", pasd.Identifier, "PASD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if (pasdIsPAX && !pasd.HasPAXDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V203, "No PAX details", null, "PASD", pasd.Identifier, "PASD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + if (!pasdIsPAX && pasd.HasPAXDetails) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V203, "PAX details but checkbox not set", null, "PASD", pasd.Identifier, "PASD"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + } + } + } + + #endregion + + #region WAS_RCPT double numbers + + Dictionary identDict = new Dictionary(); + + foreach (WAS_RCPT was_rcpt in was_rcptMessage.Elements) + { + + if (identDict.ContainsKey(was_rcpt.IdentificationNumber)) + { + MessageViolation mv = RuleEngine.CreateViolation(ValidationCode.V221, "Identification number", null, "WAS_RCPT", was_rcpt.Identifier, "WAS_RCPT"); + mv.MessageGroupName = Properties.Resources.textOverview; + vViolations.Add(mv); + break; + } + else + { + identDict.Add(was_rcpt.IdentificationNumber, ""); + } + } + + #endregion + #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; NOA_NOD noa_nod = noanodMessage.Elements[0] as NOA_NOD; @@ -980,8 +1149,11 @@ namespace ENI2 private DependencyObject GetContainerForMessageGroupName(string messageGroupName) { - if (controlCache.ContainsKey(messageGroupName)) - return controlCache[messageGroupName]; + if (messageGroupName != null) + { + if (controlCache.ContainsKey(messageGroupName)) + return controlCache[messageGroupName]; + } return null; } diff --git a/ENI2/DetailViewControls/BorderPoliceDetailControl.xaml.cs b/ENI2/DetailViewControls/BorderPoliceDetailControl.xaml.cs index 0ae08f4f..47032166 100644 --- a/ENI2/DetailViewControls/BorderPoliceDetailControl.xaml.cs +++ b/ENI2/DetailViewControls/BorderPoliceDetailControl.xaml.cs @@ -112,6 +112,11 @@ namespace ENI2.DetailViewControls this.dataGridCrewList.DeleteRequested += DataGridCrewList_DeleteRequested; this.dataGridCrewList.CreateRequested += DataGridCrewList_CreateRequested; this.dataGridCrewList.RefreshGrid += DataGridCrewList_RefreshGrid; + if(this._crewMessage.Elements.Count > 0) + { + this.checkBoxCrewNotificationSchengen.IsChecked = ((CREW)this._crewMessage.Elements[0]).NotificationSchengen; + this.checkBoxCrewNotificationPAX.IsChecked = ((CREW)this._crewMessage.Elements[0]).NotificationPAX; + } #endregion @@ -133,6 +138,12 @@ namespace ENI2.DetailViewControls this.dataGridCrewListDeparture.CreateRequested += DataGridCrewListDeparture_CreateRequested; this.dataGridCrewListDeparture.RefreshGrid += DataGridCrewListDeparture_RefreshGrid; + if (this._crewdMessage.Elements.Count > 0) + { + this.checkBoxCrewNotificationSchengenDeparture.IsChecked = ((CREWD)this._crewdMessage.Elements[0]).NotificationSchengen; + this.checkBoxCrewNotificationPAXDeparture.IsChecked = ((CREWD)this._crewdMessage.Elements[0]).NotificationPAX; + } + #endregion #region init PASA @@ -153,6 +164,12 @@ namespace ENI2.DetailViewControls this.dataGridPassengerList.CreateRequested += DataGridPassengerList_CreateRequested; this.dataGridPassengerList.RefreshGrid += DataGridPassengerList_RefreshGrid; + if (this._pasMessage.Elements.Count > 0) + { + this.checkBoxPasNotificationSchengen.IsChecked = ((PAS)this._pasMessage.Elements[0]).NotificationSchengen; + this.checkBoxPasNotificationPAX.IsChecked = ((PAS)this._pasMessage.Elements[0]).NotificationPAX; + } + #endregion #region init PASD @@ -173,6 +190,12 @@ namespace ENI2.DetailViewControls this.dataGridPassengerListDeparture.CreateRequested += DataGridPassengerListDeparture_CreateRequested; this.dataGridPassengerListDeparture.RefreshGrid += DataGridPassengerListDeparture_RefreshGrid; + if (this._pasdMessage.Elements.Count > 0) + { + this.checkBoxPasNotificationSchengenDeparture.IsChecked = ((PASD)this._pasdMessage.Elements[0]).NotificationSchengen; + this.checkBoxPasNotificationPAXDeparture.IsChecked = ((PASD)this._pasdMessage.Elements[0]).NotificationPAX; + } + #endregion } diff --git a/SQL/Update_6.x_To_7.0.sql b/SQL/Update_6.x_To_7.0.sql index a9f5e301..483e810a 100644 --- a/SQL/Update_6.x_To_7.0.sql +++ b/SQL/Update_6.x_To_7.0.sql @@ -113,4 +113,14 @@ GO INSERT INTO ViolationText(ViolationCode, ViolationText) VALUES (33, 'Value is too large') +GO + +Insert into ViolationText(ViolationCode, ViolationText) values (181, 'A notification for crew has to contain at least one of the two options for PAX or Schengen.') +Insert into ViolationText(ViolationCode, ViolationText) values (182, 'If a crew notification is for Schengen, then Schengen Details have to be provided, if a crew notification is not for Schengen, Schengen Details must not be provided.') +Insert into ViolationText(ViolationCode, ViolationText) values (201, 'A notification for passengers has to contain at least one of the two options for PAX or Schengen.') +Insert into ViolationText(ViolationCode, ViolationText) values (202, 'If a passenger notification is for Schengen, then Schengen Details have to be provided, if a passenger notification is not for Schengen, Schengen Details must not be provided.') +Insert into ViolationText(ViolationCode, ViolationText) values (203, 'If a passenger notification is for PAX, then PAX Details have to be provided, if a passenger notification is not for PAX, PAX Details must not be provided.') +Insert into ViolationText(ViolationCode, ViolationText) values (221, 'The identification number has to be unique per ship call.') +Insert into ViolationText(ViolationCode, ViolationText) values (786, 'The provided LOCODE is not accepted by SafeSeaNet.') + GO \ No newline at end of file diff --git a/bsmd.database/CREW.cs b/bsmd.database/CREW.cs index 3e7ae4b5..cbff4638 100644 --- a/bsmd.database/CREW.cs +++ b/bsmd.database/CREW.cs @@ -125,6 +125,17 @@ namespace bsmd.database [ENI2Validation] public bool? NotificationPAX { get; set; } + /// + /// Helper property for validation + /// + public bool HasSchengenDetails + { + get + { + return CrewMemberIdentityDocumentType.HasValue && !CrewMemberIdentityDocumentId.IsNullOrEmpty() && CrewMemberIdentityDocumentExpiryDate.HasValue; + } + } + public string Identifier { get; set; } public string SublistCollectionKey { get { return "crew"; } } @@ -277,6 +288,39 @@ namespace bsmd.database cmd.CommandText = query; } + + public override List LoadList(System.Data.IDataReader reader) + { + List result = new List(); + + while (reader.Read()) + { + CREWD crew = new CREWD(); + + crew.id = reader.GetGuid(0); + if (!reader.IsDBNull(1)) crew.CrewMemberLastName = reader.GetString(1); + if (!reader.IsDBNull(2)) crew.CrewMemberFirstName = reader.GetString(2); + if (!reader.IsDBNull(3)) crew.CrewMemberPlaceOfBirth = reader.GetString(3); + if (!reader.IsDBNull(4)) crew.CrewMemberDateOfBirth = reader.GetDateTime(4); + if (!reader.IsDBNull(5)) crew.CrewMemberGender = reader.GetByte(5); + if (!reader.IsDBNull(6)) crew.CrewMemberNationality = reader.GetString(6); + if (!reader.IsDBNull(7)) crew.CrewMemberIdentityDocumentType = reader.GetByte(7); + if (!reader.IsDBNull(8)) crew.CrewMemberIdentityDocumentId = reader.GetString(8); + if (!reader.IsDBNull(9)) crew.CrewMemberVisaNumber = reader.GetString(9); + if (!reader.IsDBNull(10)) crew.CrewMemberDuty = reader.GetString(10); + if (!reader.IsDBNull(11)) crew.Identifier = reader.GetString(11); + if (!reader.IsDBNull(12)) crew.IsDeparture = reader.GetBoolean(12); + if (!reader.IsDBNull(13)) crew.CrewMemberIdentityDocumentIssuingState = reader.GetString(13); + if (!reader.IsDBNull(14)) crew.CrewMemberIdentityDocumentExpiryDate = reader.GetDateTime(14); + if (!reader.IsDBNull(15)) crew.NotificationSchengen = reader.GetBoolean(15); + if (!reader.IsDBNull(16)) crew.NotificationPAX = reader.GetBoolean(16); + + result.Add(crew); + } + reader.Close(); + return result; + } + } #endregion diff --git a/bsmd.database/DBManager.cs b/bsmd.database/DBManager.cs index 9b8ef992..9b2aaee3 100644 --- a/bsmd.database/DBManager.cs +++ b/bsmd.database/DBManager.cs @@ -320,10 +320,10 @@ namespace bsmd.database } public List GetMessagesForCore(MessageCore core, MessageLoad loadType) - { + { Message aMessage = new Message(); SqlCommand cmd = new SqlCommand(); - + Message.LoadFilter loadFilter = Message.LoadFilter.BY_CORE; switch(loadType) { @@ -335,14 +335,14 @@ namespace bsmd.database aMessage.PrepareLoadCommand(cmd, loadFilter, core.Id); IDataReader reader = this.PerformCommand(cmd); - List messages = aMessage.LoadList(reader); - - List messageList = new List(); + List messages = aMessage.LoadList(reader); + + List messageList = new List(); foreach (Message message in messages) - { + { message.MessageCore = core; messageList.Add(message); - } + } this.LoadMessageDependencies(messageList); if (this._closeConnectionAfterUse) this.Disconnect(); @@ -764,7 +764,7 @@ namespace bsmd.database // Message.AssignMessageCores(messageList, messageCoreDict); foreach (Message message in messageList) - { + { this.LoadErrorList(message); this.LoadViolationList(message); this.LoadSystemErrorList(message); @@ -793,8 +793,8 @@ namespace bsmd.database } } } - } - } + } + } } #region MessageHistory diff --git a/bsmd.database/PAS.cs b/bsmd.database/PAS.cs index 41e3f898..88047a1d 100644 --- a/bsmd.database/PAS.cs +++ b/bsmd.database/PAS.cs @@ -144,6 +144,28 @@ namespace bsmd.database [MaxLength(99)] public string EmergencyContactNumber { get; set; } + /// + /// Helper property for validation + /// + public bool HasSchengenDetails + { + get + { + return PassengerIdentityDocumentType.HasValue && !PassengerIdentityDocumentId.IsNullOrEmpty() && + PassengerIdentityDocumentExpiryDate.HasValue && !PassengerPortOfEmbarkation.IsNullOrEmpty() && !PassengerPortOfDisembarkation.IsNullOrEmpty(); + } + } + + /// + /// Helper property for validation + /// + public bool HasPAXDetails + { + get + { + return !EmergencyCare.IsNullOrEmpty() && !EmergencyContactNumber.IsNullOrEmpty(); + } + } public string Identifier { get; set; } @@ -332,6 +354,42 @@ namespace bsmd.database cmd.CommandText = query; } + + public override List LoadList(System.Data.IDataReader reader) + { + List result = new List(); + + while (reader.Read()) + { + PASD pas = new PASD(); + + pas.id = reader.GetGuid(0); + if (!reader.IsDBNull(1)) pas.PassengerLastName = reader.GetString(1); + if (!reader.IsDBNull(2)) pas.PassengerFirstName = reader.GetString(2); + if (!reader.IsDBNull(3)) pas.PassengerPlaceOfBirth = reader.GetString(3); + if (!reader.IsDBNull(4)) pas.PassengerDateOfBirth = reader.GetDateTime(4); + if (!reader.IsDBNull(5)) pas.PassengerGender = reader.GetByte(5); + if (!reader.IsDBNull(6)) pas.PassengerNationality = reader.GetString(6); + if (!reader.IsDBNull(7)) pas.PassengerIdentityDocumentType = reader.GetByte(7); + if (!reader.IsDBNull(8)) pas.PassengerIdentityDocumentId = reader.GetString(8); + if (!reader.IsDBNull(9)) pas.PassengerVisaNumber = reader.GetString(9); + if (!reader.IsDBNull(10)) pas.PassengerPortOfEmbarkation = reader.GetString(10); + if (!reader.IsDBNull(11)) pas.PassengerPortOfDisembarkation = reader.GetString(11); + if (!reader.IsDBNull(12)) pas.PassengerInTransit = reader.GetBoolean(12); + if (!reader.IsDBNull(13)) pas.Identifier = reader.GetString(13); + if (!reader.IsDBNull(14)) pas.IsDeparture = reader.GetBoolean(14); + if (!reader.IsDBNull(15)) pas.PassengerIdentityDocumentIssuingState = reader.GetString(15); + if (!reader.IsDBNull(16)) pas.PassengerIdentityDocumentExpiryDate = reader.GetDateTime(16); + if (!reader.IsDBNull(17)) pas.NotificationSchengen = reader.GetBoolean(17); + if (!reader.IsDBNull(18)) pas.NotificationPAX = reader.GetBoolean(18); + if (!reader.IsDBNull(19)) pas.EmergencyCare = reader.GetString(19); + if (!reader.IsDBNull(20)) pas.EmergencyContactNumber = reader.GetString(20); + result.Add(pas); + } + reader.Close(); + return result; + } + } #endregion diff --git a/bsmd.database/ValidationAttribute.cs b/bsmd.database/ValidationAttribute.cs index 0e29ac26..dabe029e 100644 --- a/bsmd.database/ValidationAttribute.cs +++ b/bsmd.database/ValidationAttribute.cs @@ -50,11 +50,17 @@ namespace bsmd.database OPTIONAL_FLAG_CODE, WORDOVERFLOW, VALUE_TOO_LARGE, + V181 = 181, + V182, E121 = 121, E122 = 122, E123 = 123, E124 = 124, E125 = 125, + V201 = 201, + V202, + V203, + V221 = 221, V701 = 701, V702 = 702, V703 = 703, @@ -75,6 +81,7 @@ namespace bsmd.database V782 = 782, V783 = 783, V784 = 784, + V786 = 786, V801 = 801, V802 = 802, V803 = 803,