/// <summary> /// Auto increments non default control numbers. /// </summary> public static void Generate997WithControlNumbers() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = Assembly.GetExecutingAssembly().GetManifestResourceStream("EdiFabric.Sdk.X12.Edi.PurchaseOrder.txt"); int isaControlNumber = 28; int gsControlNumber = 35; Debug.WriteLine("Start interchange control number: {0}", isaControlNumber); Debug.WriteLine("Start group control number: {0}", gsControlNumber); var settings = new AckSettings { AckHandler = (s, a) => { if (a.Message.Name == "TA1") { // a.AckInterchange is TA1 } if (a.Message.Name == "997") { var ack = Helpers.BuildAck(a.InterchangeHeader, a.GroupHeader, a.Message, AckVersion.X12_997, ++isaControlNumber, ++gsControlNumber); Debug.Write(ack); } }, MessageHandler = (s, a) => { if (!a.ErrorContext.HasErrors) { // do something with the message a.Message Debug.WriteLine("Message {0} with control number {1} is valid.", a.ErrorContext.Name, a.ErrorContext.ControlNumber); } }, AckVersion = AckVersion.X12_997, }; var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings); using (var ediReader = new X12Reader(edi, "EdiFabric.Sdk.X12")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } ackMan.Complete(); Debug.WriteLine("Last interchange control number: {0}", isaControlNumber); Debug.WriteLine("Last group control number: {0}", gsControlNumber); }
/// <summary> /// Generate a 997 for a valid message. /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\X12\PurchaseOrder.txt"); var settings = new AckSettings { AckHandler = (s, a) => { var tsTa1 = a.Message as TSTA1; var ts997 = a.Message as TS997; if (tsTa1 != null) { // a.Message is TA1 } if (ts997 != null) { // Inspect the acknowledgment var ackCode = ts997.AK9.FunctionalGroupAcknowledgeCode_01; var ack = AckBuilders.BuildAck(a.InterchangeHeader, a.GroupHeader, ts997, AckVersion.X12_997); Debug.Write(ack); } }, MessageHandler = (s, a) => { if (!a.ErrorContext.HasErrors) { // do something with the message a.Message Debug.WriteLine("Message {0} with control number {1} is valid.", a.ErrorContext.Name, a.ErrorContext.ControlNumber); } }, AckVersion = AckVersion.X12_997, // Turn off AK2 for valid messages to reduce size GenerateForValidMessages = false }; using (var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings)) { using (var ediReader = new X12Reader(edi, "EdiFabric.Examples.X12.Templates.V4010")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } } }
/// <summary> /// Detects duplicate interchanges with external method. /// </summary> public static void Generate997WithDuplicateInterchange() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = Assembly.GetExecutingAssembly().GetManifestResourceStream("EdiFabric.Sdk.X12.Edi.DetectDuplicateInterchange.txt"); var settings = new AckSettings { AckHandler = (s, a) => { if (a.Message.Name == "TA1") { // a.AckInterchange is TA1 } if (a.Message.Name == "997") { var ack = Helpers.BuildAck(a.InterchangeHeader, a.GroupHeader, a.Message, AckVersion.X12_997); Debug.Write(ack); } }, MessageHandler = (s, a) => { if (a.InDuplicateInterchange) { Debug.WriteLine(string.Format("Interchange with control number {0}", a.InterchangeHeader.InterchangeControlNumber_13)); Debug.WriteLine(string.Format("Group with control number {0}", a.GroupHeader.GroupControlNumber_6)); Debug.WriteLine("Message {0} with control number {1}", a.Message.Name, a.Message.GetTransactionContext().HeaderControlNumber); Debug.WriteLine("Is in duplicate interchange: {0}", a.InDuplicateInterchange); // reject message } }, AckVersion = AckVersion.X12_997, // Turn off AK2 for valid messages to reduce size GenerateForValidMessages = false, // Check for interchange duplicates InterchangeDuplicates = IsDuplicate }; var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings); using (var ediReader = new X12Reader(edi, "EdiFabric.Sdk.X12")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } ackMan.Complete(); }
/// <summary> /// Detects duplicate messages. /// </summary> public static void Generate997WithDuplicateMessage() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = Assembly.GetExecutingAssembly().GetManifestResourceStream("EdiFabric.Sdk.X12.Edi.DuplicateMessage.txt"); var settings = new AckSettings { AckHandler = (s, a) => { if (a.Message.Name == "TA1") { // a.AckInterchange is TA1 } if (a.Message.Name == "997") { var ack = Helpers.BuildAck(a.InterchangeHeader, a.GroupHeader, a.Message, AckVersion.X12_997); Debug.Write(ack); } }, MessageHandler = (s, a) => { if (a.ErrorContext.HasErrors) { Debug.WriteLine("Message {0} with control number {1} is invalid: {2}.", a.ErrorContext.Name, a.ErrorContext.ControlNumber, a.ErrorContext.Codes.FirstOrDefault()); } }, AckVersion = AckVersion.X12_997, // Turn off AK2 for valid messages to reduce size GenerateForValidMessages = false, // Check for message duplicates TransactionSetDuplicates = true }; var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings); using (var ediReader = new X12Reader(edi, "EdiFabric.Sdk.X12")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } ackMan.Complete(); }
/// <summary> /// Reads one item at a time from the EDI stream /// The interchange contains two purchase orders: /// The first is valid /// The second is invalid /// </summary> private static void ReadPurchaseOrdersOneAtATime() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load the sample purchase order to a stream Stream purchaseOrderStream = Assembly.GetExecutingAssembly() .GetManifestResourceStream("EdiFabric.Sdk.X12.Edi.PurchaseOrders.txt"); // 2. Read item by item, that is each call to Read() brings back either a control segment (ISA, GS, GE or IEA) or a transaction using (var ediReader = new X12Reader(purchaseOrderStream, "EdiFabric.Sdk.X12")) { // Call Read() instead of ReadToEnd() while (ediReader.Read()) { var po = ediReader.Item as TS850; if (po != null) { // 3. Validate it MessageErrorContext errorContext; if (po.IsValid(out errorContext)) { // The purchase order is valid, process it downstream } else { // The purchase order is invalid // Report it back to the sender, log, etc. // Inspect MessageErrorContext for the validation errors var errors = errorContext.Flatten(); // List all error messages Debug.WriteLine("Message {0} with control number {1} is invalid with errors:", errorContext.Name, errorContext.ControlNumber); foreach (var error in errors) { Debug.WriteLine(error); } } } } } }
/// <summary> /// Reads one item at a time from the EDI stream. /// Use for interchanges containing multiple transactions. /// The sample file contains two purchase orders - a valid one and an invalid one. /// </summary> public static void ReadPurchaseOrdersOneAtATime() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream ediStream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files.X12\PurchaseOrders.txt"); // 2. Read item by item, that is each call to Read() // brings back either a control segment (ISA, GS, GE or IEA) or a transaction using (var ediReader = new X12Reader(ediStream, TemplateFactory.FullTemplateFactory)) { while (ediReader.Read()) { // 3. Check if current item is purchase order var po = ediReader.Item as TS850; if (po != null) { // 4. Validate it MessageErrorContext errorContext; if (po.IsValid(out errorContext)) { // The purchase order is valid, process it downstream } else { // The purchase order is invalid Debug.WriteLine("Message {0} with control number {1} is invalid with errors:", errorContext.Name, errorContext.ControlNumber); // List all error messages var errors = errorContext.Flatten(); foreach (var error in errors) { Debug.WriteLine(error); } } } } } }
/// <summary> /// Validate the typed control segments /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); Stream ediStream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\X12\Invoice.txt"); using (var ediReader = new X12Reader(ediStream, "EdiFabric.Examples.X12.Templates.V4010")) { while (ediReader.Read()) { var isa = ediReader.Item as ISA; if (isa != null) { // Validate var isaErrors = isa.Validate(); // Pull the sender id from ISA var senderId = isa.InterchangeSenderID_6; Debug.WriteLine("Sender ID:"); Debug.WriteLine(senderId); } var gs = ediReader.Item as GS; if (gs != null) { // Validate var gsErrors = gs.Validate(); // Pull the sender id from GS var senderId = gs.SenderIDCode_2; Debug.WriteLine("Sender ID:"); Debug.WriteLine(senderId); } } } }
/// <summary> /// Reads one item at a time from the EDI stream. /// Use for interchanges containing multiple transactions. /// The sample file contains two purchase orders - a valid one and an invalid one. /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); // 1. Load to a stream Stream ediStream = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\X12\PurchaseOrders.txt"); // 2. Read item by item, that is each call to Read() // brings back either a control segment (ISA, GS, GE or IEA) or a transaction using (var ediReader = new X12Reader(ediStream, "EdiFabric.Examples.X12.Templates.V4010")) { while (ediReader.Read()) { // 3. Check if current item is purchase order var po = ediReader.Item as TS850; if (po != null) { ProcessPurchaseOrder(ediReader.CurrentInterchangeHeader, ediReader.CurrentGroupHeader, po); } } } }
/// <summary> /// Generate a 997 for an invalid purchase order. /// </summary> public static void Generate999ForInvalid() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = Assembly.GetExecutingAssembly().GetManifestResourceStream("EdiFabric.Sdk.X12.Edi.PurchaseOrderInvalid.txt"); var processedMessages = new ConcurrentBag <string>(); var settings = new AckSettings { AckHandler = (s, a) => { if (a.Message.Name == "TA1") { // a.AckInterchange is TA1 } if (a.Message.Name == "999") { var ack999 = a.Message as TS999; var allFailed = ack999.AK2Loop1.Where(f => f.IK5.TransactionSetAcknowledgmentCode_01 == "R").ToList(); var allAccepted = ack999.AK2Loop1.Where(f => f.IK5.TransactionSetAcknowledgmentCode_01 == "A").ToList(); foreach (var failedMessage in allFailed) { if (processedMessages.Contains(failedMessage.AK2.TransactionSetControlNumber_02)) { failedMessage.IK5.TransactionSetAcknowledgmentCode_01 = "E"; } } var ack = Helpers.BuildAck(a.InterchangeHeader, a.GroupHeader, a.Message, AckVersion.Hipaa_999); Debug.Write(ack); } }, MessageHandler = (s, a) => { if (a.ErrorContext.HasErrors) { // In case we decide to process the message anyway, preserve the control number processedMessages.Add(a.Message.GetTransactionContext().HeaderControlNumber); // Process the invalid message // Reject message // Log/report it // Inspect MessageErrorContext for the validation errors var errors = a.ErrorContext.Flatten(); Debug.WriteLine("Message {0} with control number {1} is invalid with errors:", a.ErrorContext.Name, a.ErrorContext.ControlNumber); foreach (var error in errors) { Debug.WriteLine(error); } } }, AckVersion = AckVersion.Hipaa_999, // Turn off AK2 for valid messages to reduce size GenerateForValidMessages = false }; var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings); using (var ediReader = new X12Reader(edi, "EdiFabric.Sdk.X12")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } ackMan.Complete(); }
/// <summary> /// Generates custom 999. /// </summary> public static void GenerateCustom999() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = Assembly.GetExecutingAssembly().GetManifestResourceStream("EdiFabric.Sdk.X12.Edi.PurchaseOrdersMultipleGroups.txt"); var custom999 = new Custom999 { AK1Loops = new List <TS999_AK1Loop>() }; ISA currentIsa = null; GS currentGs = null; int isaCounter = 0; int gsCounter = 0; var settings = new AckSettings { AckHandler = (s, a) => { if (a.AckType == AckType.Technical) { // Raise 999 acknowledgment at the end of every interchange var currentAck = Helpers.BuildAck(currentIsa, currentGs, custom999, AckVersion.Hipaa_999, ++isaCounter, ++gsCounter); Debug.Write(currentAck); custom999 = null; } if (a.AckType == AckType.Implementation) { currentIsa = a.InterchangeHeader; currentGs = a.GroupHeader; if (custom999 == null) { custom999 = new Custom999 { AK1Loops = new List <TS999_AK1Loop>() } } ; var ak1Loop = new TS999_AK1Loop(); var current999 = a.Message as TS999; if (current999 != null) { if (custom999.ST == null) { custom999.ST = current999.ST; } ak1Loop.AK1 = current999.AK1; ak1Loop.AK2Loop1 = current999.AK2Loop1; ak1Loop.AK9 = current999.AK9; custom999.AK1Loops.Add(ak1Loop); } } }, AckVersion = AckVersion.Hipaa_999, TechnicalAck = TechnicalAck.Enforce }; var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings); using (var ediReader = new X12Reader(edi, "EdiFabric.Sdk.X12")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } ackMan.Complete(); } }
/// <summary> /// Generate 997 for an invalid message. /// </summary> public static void Run() { Debug.WriteLine("******************************"); Debug.WriteLine(MethodBase.GetCurrentMethod().Name); Debug.WriteLine("******************************"); var edi = File.OpenRead(Directory.GetCurrentDirectory() + @"\..\..\..\Files\X12\PurchaseOrderInvalid.txt"); var processedMessages = new ConcurrentBag <string>(); var settings = new AckSettings { AckHandler = (s, a) => { var tsTa1 = a.Message as TSTA1; var ts997 = a.Message as TS997; if (tsTa1 != null) { // a.Message is TA1 } if (ts997 != null) { var allFailed = ts997.AK2Loop1.Where(f => f.AK5.TransactionSetAcknowledgmentCode_01 == "R").ToList(); var allAccepted = ts997.AK2Loop1.Where(f => f.AK5.TransactionSetAcknowledgmentCode_01 == "A").ToList(); foreach (var failedMessage in allFailed) { if (processedMessages.Contains(failedMessage.AK2.TransactionSetControlNumber_02)) { failedMessage.AK5.TransactionSetAcknowledgmentCode_01 = "E"; } } var ack = AckBuilders.BuildAck(a.InterchangeHeader, a.GroupHeader, ts997, AckVersion.X12_997); Debug.Write(ack); } }, MessageHandler = (s, a) => { if (a.ErrorContext.HasErrors) { // In case we decide to process the message anyway, preserve the control number processedMessages.Add(a.Message.ErrorContext.ControlNumber); // Process the invalid message // Reject message // Log/report it // Inspect MessageErrorContext for the validation errors var errors = a.ErrorContext.Flatten(); Debug.WriteLine("Message {0} with control number {1} is invalid with errors:", a.ErrorContext.Name, a.ErrorContext.ControlNumber); foreach (var error in errors) { Debug.WriteLine(error); } } }, AckVersion = AckVersion.X12_997, // Turn off AK2 for valid messages to reduce size GenerateForValidMessages = false }; using (var ackMan = new Plugins.Acknowledgments.X12.AckMan(settings)) { using (var ediReader = new X12Reader(edi, "EdiFabric.Templates.X12")) { while (ediReader.Read()) { ackMan.Publish(ediReader.Item); } } } }