Update: 2023-03-08
999 - Implementation Acknowledgment
Important
Bishop's X12 NET SDK adheres to the 999 Implementation Acknowledgment for Health Care Insurance (June 2007) defined in the ASC X12N/005010X231, Version 5, Release 1, ASC X12 Standards for Electronic Data Interchange, Technical Report Type 3 Implementation Guide.
Please obtain and reference this implementation guide for a detailed explanation of the 999 transaction set and to understand how it defines uniform data content, identifies valid code tables and specifies values applicable for the business focus of the 999.
Important
The 999 transaction CANNOT be used for application level validations or to respond to another 999. For data validation at the application level see the 277 transaction set.
As the name implies, the 999 "Implementation Acknowledgement" enables a receiver of an 837, 835, and 277 transaction to inform the sender that their transaction was successfully received or to report to the sender any X12 syntactical and relational data errors defined in the sender's implementation of the 837, 835 or 277 transaction.
The SDK handles the entire process of creating the appropriate 999 response to a sender's transaction including the handling of the TA1 segment.
TA1 Segment
The TA1 is a unique segment sent by the receiver in a 999 transaction for the sole purpose of informing the sender as to the validity or successful processing of the interchange (ISA/IEA envelope) in the sender's EDI transaction.
If the interchange is rejected by the receiver, the TA1 segment is be the only segment sent in the 999. The TA1 segment is also sent by the receiver, along with the rest of the 999 segments, indicating that the processing of the interchange was successful when the sender has requested that the TA1 is sent (see ISA14). If the sender has not requested that the TA1 is returned in the 999 and the interchange in the sender's transaction processed successful, then the TA1 segment is not sent in the 999.
Note
The receiver is required to return a TA1 segment within the 999 to the sender in response to the sender's transaction when:
- requested by the sender (as indicated in the ISA14 of the sender's transaction interchange); or,
- the interchange of the received EDI transaction is rejected.
Generating the 999
public void Load837()
{
try
{
// 837 file to load
string filename = @"C:\Temp\ClaimPro.837";
// Load an 837 transaction
using X12Doc x837 = X12Doc.Load(filename);
// Generate the 999 transaction in response to the 837. If the 837 contains interchange errors
// the 999 will only contain the ISA/TA1/IEA interchange segments where the TA1 will indicate
// the error as to why the 837 could not be processed.
//
// If the 837 does not contain interchange errors and the 837 contains a request for a TA1 segment
// (see ISA14) then the TA1 will be placed immediately after the ISA segment followed by the
// remainder of the appropriate 999 segments.
// if the 837 does not contain interchange errors and the 837 does not request a TA1 segment
// then only the appropriate 999 segments.
using X12Doc x999 = x837.Generate999(1);
x999.Save(filename + ".999", X12DocOptions.InsertCrLf);
}
catch (X12Exception e)
{
Console.WriteLine(e.ToString());
}
}
Consuming the 999
public void Consume999()
{
try
{
// 999 file to load
string filename = @"C:\Temp\ClaimPro.837.999";
// Load an 999 transaction
using X12Doc x999 = X12Doc.Load(filename);
Console.WriteLine($"Cntl#:{x999.ControlNumber} Date:{x999.DateTime} Sender:{x999.SenderETIN}");
// Assign the 999 helper to tSet
X12TA1Helper hTA1 = new(x999);
// If the 999 contains a TA1 segment (it should if you requested one in ISA14. Then the next line will provide information
// regarding the original transaction that this 999 is responding to. If a TA1 segment is not present then the original transaction
// is assumed to have been accepted.
if (hTA1.OrigInterchangeStatus != X12DocAck.NotSet)
{
Console.WriteLine($"Response to: Orig Cntl#:{hTA1.OrigInterchangeControlNumber} Orig Date:{hTA1.OrigInterchangeDateTime} Error:{hTA1.OrigError} Message:{hTA1.OrigMessage}");
Console.WriteLine();
}
foreach (X12Group grp in x999.Groups())
{
foreach (X12Transaction ts in grp.Transactions())
{
X12999Helper h999 = new(ts);
Console.WriteLine($"G:{h999.Type}:{h999.Version} Ctrl#:{h999.ControlNumber} Status:{h999.Status} Included:{h999.Included} Received:{h999.Received} Accepted:{h999.Accepted}");
foreach (X12999TsAck tsAck in h999.GetTsAcks().Where(t => t.Status == X12TsAck.Rejected))
{
Console.WriteLine($"T:{tsAck.Type}:{tsAck.Version} Cntl#:{tsAck.ControlNumber} Status:{tsAck.Status} Errors:{tsAck.SegmentErrors().Count()} ");
foreach (var ec in tsAck.ErrorCodes())
Console.WriteLine($"{ec} ");
foreach (X12999SegError se in tsAck.SegmentErrors())
{
if(!string.IsNullOrWhiteSpace(se.BusinessId))
Console.WriteLine($"\tBusiness Id:{se.BusinessId}");
Console.WriteLine($"\t{se.RefId} Pos:{se.PosInTSet} Error:{se.Error}");
foreach (X12999Ctx ctx in se.Context())
Console.WriteLine($"\tCTX: Seg:{ctx.SegId} Loop:{ctx.LoopId} PosInTSet:{ctx.PosInTSet} PosInSeg:{ctx.PosInSeg}(DEN:{ctx.DEN}) PosInEle:{ctx.PosInEle}(DEN:{ctx.CeDEN})");
foreach (X12999EleError ee in se.ElementErrors())
{
Console.WriteLine($"\t\t{se.SegId}{ee.RefId} {ee.Description} Error:{ee.Error} BadData:{ee.BadData}");
foreach (X12999Ctx ctx in ee.Context())
Console.WriteLine($"\t\t{ctx.DENDescription}");
}
}
}
}
}
}
catch (X12Exception e)
{
Console.WriteLine(e.ToString());
}
}
Splitting
Splitting transactions is the process of creating complete individual transactions consisting only of one Claim, Payment Advise, or Claim Acknowledgement.
999 documents are splittable at the GS/GE level.
Batching
999 documents are batchable at the GS/GE level. Meaning a single 999 transaction set may contain multiple GS/GE functional groups where each functional group reports the analysis of the sender's 837, 835 or 277 functional group (i.e., GS/GE).