How to implement HIPAA situational rules validation
HIPAA situational validation is part of HIPAA SNIP Level 4 and is considered cross-segment type validation, where if a data element in a certain position exists or is of a certain value, then another data element in that segment needs to conform to certain rules.
How to validate HIPAA SNIP levels with EDI Tools for .NET
HIPAA Situational Usage is defined as: Use of this loop/segment/element varies, depending on data content and business context as described in the defining rule. The defining rule is documented in a Situational Rule attached to the item.
There are two forms of Situational Rules.
- The first form is “Required when <explicit condition statement>. If not required by this implementation guide, may be provided at the sender’s discretion, but cannot be required by the receiver.” The data qualified by such a situational rule cannot be required or requested by the receiver, transmission of this data is solely at the sender’s discretion.
- The alternative form is “Required when <explicit condition statement>. If not required by this implementation guide, do not send.” The data qualified by such a situational rule cannot be sent except as described in the explicit condition statement.
EDI Tools for .NET does not validate situational rules but provides several options to implement these manually.
Given that you need to validate HIPAA SNIP Level 4, the following options are available:
-
Add the situational validation logic in a custom attribute that derives from ValidationAttribute. This ensures that the logic will be executed as part of both IsValid() and AckMan. Set the IsSituational property of DataElementErrorContext to true - this will ensure that a CTX segment will be automatically generated by AckMan for 999 implementation acknowledgments.
-
[AttributeUsage(AttributeTargets.Property)] public class N4PostCodeValidationAttribute : ValidationAttribute { public N4PostCodeValidationAttribute() : base(10) { } public override SegmentErrorContext ValidateEdi(ValidationContext validationContext) { var n4 = validationContext.InstanceContext.Parent.Instance as N4; if (n4 != null) { if(!string.IsNullOrEmpty(n4.CityName_01) && string.IsNullOrEmpty(n4.PostalCode_03)) { var result = new SegmentErrorContext("N4", validationContext.SegmentIndex + 1, null, GetType().GetTypeInfo()); var errorContext = new DataElementErrorContext("116", validationContext.InSegmentIndex, DataElementErrorCode.ConditionalRequiredDataElementMissing, validationContext.InCompositeIndex, validationContext.RepetitionIndex, null); errorContext.IsSituational = true; result.Add(errorContext); return result; } } return null; } }
[StringLength(3, 15)] [N4PostCodeValidation] [DataElement("116", typeof(X12_AN))] [Pos(3)] public string PostalCode_03 { get; set; }
-
[AttributeUsage(AttributeTargets.Property)] public class LinLoopValidationAttribute : ValidationAttribute { public LinLoopValidationAttribute() : base(10) { } public override SegmentErrorContext ValidateEdi(ValidationContext validationContext) { var position = validationContext.SegmentIndex + 1; var linLoops = validationContext.InstanceContext.Instance as IList<Loop_LIN_ORDERS>; if (linLoops != null) { foreach (var linLoop in linLoops) { // Count all existing segments before the one that is validated to apply the correct index if (linLoop.PIA != null) position += linLoop.PIA.Count; if (linLoop.IMD != null) position += linLoop.IMD.Count; if (linLoop.MEA != null) position += linLoop.MEA.Count; if (linLoop.QTY != null) position += linLoop.QTY.Count; if (linLoop.PCD != null) position += linLoop.PCD.Count; if (linLoop.ALI != null) position += linLoop.ALI.Count; // Check if QTY exists and DTM also exist if (linLoop.QTY != null && linLoop.DTM == null) return new SegmentErrorContext("DTM", position + 1, null, GetType().GetTypeInfo(), SegmentErrorCode.RequiredSegmentMissing, "DTM segment is missing."); } } return null; } }
-
-
Implement IEdiValidator for any EDI loop, EDI segment, or EDI complex element, and add the situational validation logic in the ValidateEdi() method. This ensures that the logic will be executed as part of both IsValid() and AckMan.
public partial class Loop_2000A : IEdiValidator { public List<SegmentErrorContext> ValidateEdi(ValidationContext validationContext) { // Custom validation goes here, example below var result = new List<SegmentErrorContext>(); if (N1 != null && N2 == null) result.Add(new SegmentErrorContext("N2", validationContext.SegmentIndex + 2, GetType().GetTypeInfo(), SegmentErrorCode.RequiredSegmentMissing, "N2 segment is missing.")); return result; } }
- Use EDI Tools for .NET attributes RequiredIf and ExclusionIf. Go to the Conditional EDI validation article for more details.
Several HIPAA situational rules are available for HIPAA 5010 transactions 270, 271, 276, and 277. The EDI templates with the implementation are in a separate folder named SituationalSegments_270_271_276_277.
The tables below list all available rules in the following column order:
- The HIPAA Loop ID
- The HIPAA Segment ID and Name
- The page in the TR3 X12 implementation guideline where the situational rule is defined
- The name of the EDI template class implementing that rule
- The actual code that implements the rule
HIPAA situational rules for 270
Loop | Segment | Page | EDI template | Implementation |
---|---|---|---|---|
2100A | NM1 - INFORMATION SOURCE NAME | 69 | NM1_InformationSourceName |
[RequiredIf(2, ",1,")] |
2100B | NM1 - INFORMATION RECEIVER NAME | 75 | NM1_InformationReceiverName |
[RequiredIf(2, ",1,")] |
HIPAA situational rules for 271
Loop | Segment | Page | EDI template | Implementation |
---|---|---|---|---|
2100B | REF - INFORMATION RECEIVER ADDITIONAL IDENTIFICATION | 236 |
REF_InformationReceiver AdditionalIdentification |
[RequiredIf(1, ",0B,")] |
2100C | REF - SUBSCRIBER ADDITIONAL IDENTIFICATION | 254 |
REF_Subscriber AdditionalIdentification_3 |
[RequiredIf(1, ",18,6P,N6,")] |
2110C | REF - SUBSCRIBER ADDITIONAL IDENTIFICATION | 314 |
REF_Subscriber AdditionalIdentification |
[RequiredIf(1, ",18,6P,N6,")] |
2100D | REF - DEPENDENT ADDITIONAL IDENTIFICATION | 358 |
REF_Dependent AdditionalIdentification_3 |
[RequiredIf(1, ",18,6P,N6,")] |
2110D | REF - DEPENDENT ADDITIONAL IDENTIFICATION | 417 |
Loop:REF_Dependent AdditionalIdentification |
[RequiredIf(1, ",18,6P,N6,")] |
2110C | EB | 290 |
EB_SubscriberEligibility orBenefitInformation |
[ExclusionIf(1, ",A,")] |
2110D | EB | 394 |
EB_DependentEligibility orBenefitInformation |
[ExclusionIf(1, ",A,")] |
2100A | NM1 - INFORMATION SOURCE NAME | 218 |
NM1_Information SourceName |
[RequiredIf(2, ",1,")] |
2120C | NM1 - SUBSCRIBER BENEFIT RELATED ENTITY NAME | 329 |
NM1_DependentBenefit RelatedEntityName |
[RequiredIf(2, ",1,")] |
2120D | NM1 - DEPENDENT BENEFIT RELATED ENTITY NAME | 432 |
NM1_DependentBenefit RelatedEntityName |
[RequiredIf(2, ",1,")] |
HIPAA situational rules for 276
Loop | Segment | Page | EDI template | Implementation |
---|---|---|---|---|
2100B | NM1 - INFORMATION RECEIVER NAME | 45 | NM1_InformationReceiverName_3 |
[RequiredIf(2, ",1,")] |
2100C | NM1 - PROVIDER NAME | 49 | NM1_ProviderName |
[RequiredIf(2, ",1,")] |
2100D | NM1 - SUBSCRIBER NAME | 56 | NM1_SubscriberName_2 |
[RequiredIf(2, ",1,")] |
HIPAA situational rules for 277
Loop | Segment | Page | EDI template | Implementation |
---|---|---|---|---|
2100B | NM1 - INFORMATION RECEIVER NAME | 118 | NM1_InformationReceiverName_3 |
[RequiredIf(2, ",1,")] |
2100C | NM1 - PROVIDER NAME | 126 | NM1_ProviderName |
[RequiredIf(2, ",1,")] |
2100D | NM1 - SUBSCRIBER NAME | 135 | NM1_SubscriberName_2 |
[RequiredIf(2, ",1,")] |
Comments
0 comments
Please sign in to leave a comment.