EDI Acknowledgments Generation

Acknowledgment Manager (AckMan)

An EDI acknowledgment serves as a receipt, to acknowledge that an EDI transaction, or a group of transactions, was received by the remote party. It is pivotal that the communication between business partners is reliable and audit-able, and that the exact status of the transactions is known to both parties at any moment. Without specific acknowledgment of receipt and acceptance, subsequent processing of the transactions is usually delayed until their status is confirmed. By incorporating EDI acknowledgments into your business process, most or all status inquiries can be eliminated and trading partners are automatically notified that their transactions have indeed been received and then confirmed, rejected or partially accepted.

EdiFabric AckMan can be used in conjunction with the framework, to produce technical, functional and implementation acknowledgments. It can be easily attached to the reader, without having an impact on the core process, to analyze transactions on the fly and generate acknowledgments by raising them as events. This allows the consumer application to process the acknowledgments asynchronously if needed and to have full control over the state of the currently read item at any given point.

Example code

 

 

 


 

 

 

Acknowledgment types

EdiFabric AckMan can generate the following types of acknowledgments:

 

 

 


 

 

 

AckSettings

The first step in generating acknowledgments is to configure AckMan. AckSettings provides the single point of configuration and is the only parameter to AckMan's constructor.

The following options are available:

AckHandler

The acknowledgment handler. It is raised after reaching the end of each group as the EDI document is read along. This is where the acknowledgments will be raised and it's the same handler for all acknowledgment types.

MessageHandler

The message handler. It is raised after reaching the end of each message as the EDI document is read along. The event arguments contain the interchange and group headers and whether the message is valid or duplicated.

MessageControlNumber

This is the initial value for EDI transaction sets control numbers. By default, it assigns consecutive numbers starting from 1. This property is incremented every time a new acknowledgment is generated.

GenerateForValidMessages

Indicates if AK2 or UCM segment groups should be generated only if the message is rejected or always.

TechnicalAck

Controls the generation of technical acknowledgment. You can enforce or suppress technical acknowledgments. By default, it generates it according to the ISA14 flag (for X12) or UNB9 flag (for EDIFACT).

TransactionSetDuplicates

Indicates whether to detect duplicate messages within the same group.

GroupDuplicates

Indicates whether to detect duplicate groups within the same interchange.

InterchangeDuplicates

A delegate to detect duplicate interchanges.

AllowPartial (X12 only)

Indicates if a group can be marked (Ak901 or IK901) as partial accepted if not all of the messages were accepted. When this is turned off, groups can only be either accepted or rejected. When this is turned on, a group containing both accepted and rejected messages is marked as partial accepted. Regardless of the flag, if a group contains only rejected messages then it is always marked as rejected.

Ak901ShouldBeP (X12 only)

Indicates the partially accepted code to be either E or P. The default is E.

AckVersion (X12 only)

The version of the acknowledgment. This can be X12_997 (004010 compliant), Hipaa_997 (005010 compliant) or Hipaa_999 (005010 compliant). The default is X12_997.

 

 

 


 

 

 

AckHandler

The acknowledgment handler provides the generated ack as a typed object in case any additional enhancement is needed. AckMan does not support CTX segments and these need to be manually crafted if required. You are also provided with the typed interchange header (ISA) and group header (GS) of the original message which can be used for producing the final acknowledgment.

X12

 var settings = new AckSettings
 {
	AckHandler = (s, a) =>
	{
		if (a.Message.Name == "TA1")
		{
			// a.AckInterchange is TA1 
		}

		if (a.Message.Name == "999")
		{
		   var ack = BuildAck(a.InterchangeHeader, a.GroupHeader,
                        a.Message, AckVersion.Hipaa_999);
		   Debug.Write(ack);
		}
	},
	MessageHandler = (s, a) =>
	{
		if (!a.ErrorContext.HasErrors)
		{
			// do something with the message a.Message
		}
	},
	AckVersion = AckVersion.Hipaa_999,
	// Turn on AK2 for valid messages
	GenerateForValidMessages = true
 };

EDIFACT

 var settings = new AckSettings
 {
	AckHandler = (s, a) =>
	{
		if (a.Message.Name == "CONTRL" && a.AckType == AckType.Technical)
		{
			// a.AckInterchange is technical acknowledgment 
		}

		if (a.Message.Name == "CONTRL" && a.AckType == AckType.Functional)
		{
		   var ack = BuildAck(a.InterchangeHeader, a.GroupHeader,
                        a.Message);
		   Debug.Write(ack);
		}
	},
	MessageHandler = (s, a) =>
	{
		if (!a.ErrorContext.HasErrors)
		{
			// do something with the message a.Message
		}
	},
	// Turn on UCM for valid messages
	GenerateForValidMessages = true
 };

 

 

 


 

 

 

AckMan

In order to generate acknowledgments, you need to create an instance of AckMan. It takes AckSettings as the only parameter.

To start generating acknowledgments simply publish every item read by the reader, maintaining the sequence, to AckMan. Acknowledgments will be raised in the handlers and can be offloaded for asynchronous processing.

AckMan implements IDisposable and needs to be disposed of. This is to ensure that a final validation is always executed even for EDI documents which are missing closing trailers.

X12

 using(var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings))
 {
     using (var ediReader = new X12Reader(edi, "EdiFabric.Sdk.X12"))
     {
	  while (ediReader.Read())
		ackMan.Publish(ediReader.Item);
     }
 }

EDIFACT

 using(var ackMan = new Plugins.Acknowledgments.Edifact.AckMan(settings))
 {
     using (var ediReader = new EdifactReader(edi, "EdiFabric.Sdk.Edifact"))
     {
	  while (ediReader.Read())
		ackMan.Publish(ediReader.Item);
     }
 }

When using AckMan all processing happens within the handlers - all acknowledgments arrive in the AckHandler and all messages arrive in the MessageHandler together with their validation context and interchange\group headers. The reader is only used to read the stream and publish the items to AckMan.

The benefit of utilizing AckMan is not just its ability to generate acknowledgments, but to also provide the messages from the EDI document in the context of their respective groups and interchanges, and to indicate their conformance according to their rules.

 

 

 


 

 

 

Duplicates

Interchanges can be identified as duplicates by their unique identifier comprised of the three values for Sender code, Receiver code, and Control number.

For example the unique identifier of the following interchange header:

ISA*00* *00* *ZZ*FROM *ZZ*TO *071214*1406*U*00204*810000263*0*T*>~

is Sender code: FROM, Receiver code: TO and Control number:810000263

In order to be able to detect duplicate interchanges, the unique identifiers need to be preserved externally (in a database for example). An external delegate can be configured in AckMan, which takes the unique identifier as a string and returns an indicator if a duplicate was found.

Func<string, bool> InterchangeDuplicates

Interchange unique numbers should be considered valid only for a certain amount of time that was agreed with the trading partner. After that time the same control numbers can be assigned again and will not be considered as duplicates.

Duplicate groups within an interchange are identified by the group control number GS06. Duplicate messages within a group are identified by the transaction control number ST02.

 

 

 


 

 

 

FunctionalGroupVersion Not Supported

By default, this isn't raised. To enable it in:

  • 999 or 997 in AK905 with code 2
  • CONTRL in UCM with code 17

you need to raise GroupNotSupportedException.

Was this article helpful?
1 out of 1 found this helpful