public void CreatePurchaseOrder850() { string expected = @"ISA*00* *00* *01*828513080 *01*001903202U *100817*0850*U*00401*000000245*0*P*:~ GS*PO*828513080*001903202U*20100817*0850*245*X*005010X222~ ST*850*0001~ BEG*05*SA*S41000439**20100810~ CUR*BY*USD~ PER*IC*Doe,Jane******Doe,Jane~ SE*5*0001~ GE*1*1~ IEA*1*000000245~"; var purcaseOrderDate = new DateTime(2010, 8, 17, 08, 50, 0); var interchange = new Interchange(purcaseOrderDate, 245, true) { InterchangeSenderIdQualifier = "01", InterchangeSenderId = "828513080", InterchangeReceiverIdQualifier = "01", InterchangeReceiverId = "001903202U", InterchangeDate = purcaseOrderDate, }; interchange.SetElement(14, "0"); FunctionGroup group = interchange.AddFunctionGroup("PO", purcaseOrderDate, 1, "005010X222"); group.ApplicationSendersCode = "828513080"; group.ApplicationReceiversCode = "001903202U"; group.Date = purcaseOrderDate; group.ControlNumber = 245; Transaction transaction = group.AddTransaction("850", "0001"); Segment bhtSegment = transaction.AddSegment("BEG"); bhtSegment.SetElement(1, "05"); bhtSegment.SetElement(2, "SA"); bhtSegment.SetElement(3, "S41000439"); bhtSegment.SetElement(5, "20100810"); bhtSegment = transaction.AddSegment("CUR"); bhtSegment.SetElement(1, "BY"); bhtSegment.SetElement(2, "USD"); bhtSegment = transaction.AddSegment("PER"); bhtSegment.SetElement(1, "IC"); bhtSegment.SetElement(2, "Doe,Jane"); bhtSegment.SetElement(8, "Doe,Jane"); var x12 = interchange.SerializeToX12(true); Assert.AreEqual(expected, x12); }
public void CreatePurchaseOrder850() { DateTime purcaseOrderDate = new DateTime(2010, 8, 17, 08, 50, 0); Interchange interchange = new Interchange(purcaseOrderDate, 245, true) { InterchangeSenderIdQualifier = "01", InterchangeSenderId = "828513080", InterchangeReceiverIdQualifier = "01", InterchangeReceiverId = "001903202U", InterchangeDate = purcaseOrderDate, }; interchange.SetElement(14, "0"); //No Aknowlegement is 0 FunctionGroup group = interchange.AddFunctionGroup("PO", purcaseOrderDate, 1, "005010X222"); group.ApplicationSendersCode = "828513080"; group.ApplicationReceiversCode = "001903202U"; group.Date = purcaseOrderDate; group.ControlNumber = 245; Transaction transaction = group.AddTransaction("850", "0001"); Segment bhtSegment = transaction.AddSegment("BEG"); bhtSegment.SetElement(1, "05"); bhtSegment.SetElement(2, "SA"); bhtSegment.SetElement(3, "S41000439"); bhtSegment.SetElement(5, "20100810"); bhtSegment = transaction.AddSegment("CUR"); bhtSegment.SetElement(1, "BY"); bhtSegment.SetElement(2, "USD"); bhtSegment = transaction.AddSegment("PER"); bhtSegment.SetElement(1, "IC"); bhtSegment.SetElement(2, "Doe,Jane"); bhtSegment.SetElement(8, "Doe,Jane"); var x12 = interchange.SerializeToX12(true); System.Diagnostics.Trace.Write(x12); }
public void TestEmptyElement() { string expectedSegmentString = "BEG*05*SA*S41000439"; DateTime purcaseOrderDate = new DateTime(2010, 8, 17, 08, 50, 0); Interchange interchange = new Interchange(purcaseOrderDate, 245, true) { InterchangeSenderIdQualifier = "01", InterchangeSenderId = "828513080", InterchangeReceiverIdQualifier = "01", InterchangeReceiverId = "001903202U", InterchangeDate = purcaseOrderDate, }; interchange.SetElement(14, "0"); //No Aknowlegement is 0 FunctionGroup group = interchange.AddFunctionGroup("PO", purcaseOrderDate, 1, "005010X222"); group.ApplicationSendersCode = "828513080"; group.ApplicationReceiversCode = "001903202U"; group.Date = purcaseOrderDate; group.ControlNumber = 245; Transaction transaction = group.AddTransaction("850", "0001"); string segmentString = string.Empty; Segment bhtSegment = transaction.AddSegment("BEG"); segmentString = bhtSegment.SegmentString; //test getting it prematurely bhtSegment.SetElement(1, "05"); bhtSegment.SetElement(2, "SA"); bhtSegment.SetElement(3, "S41000439"); bhtSegment.SetElement(5, ""); segmentString = bhtSegment.SegmentString; Assert.AreEqual(expectedSegmentString, segmentString); }
public void CreatePurchaseOrderChangeNotice860() { DateTime purcaseOrderDate = new DateTime(2010, 8, 17, 08, 50, 0); DateTime changeOrderDate = DateTime.Now; DateTime requestedShipDate = DateTime.Now.AddDays(2d); Interchange interchange = new Interchange(changeOrderDate, 245, true) { InterchangeSenderIdQualifier = "01", InterchangeSenderId = "828513080", InterchangeReceiverIdQualifier = "01", InterchangeReceiverId = "001903202U", InterchangeDate = changeOrderDate, }; interchange.SetElement(14, "0"); //No Aknowlegement is 0 FunctionGroup group = interchange.AddFunctionGroup("PO", changeOrderDate, 1, "005010X222"); group.ApplicationSendersCode = "828513080"; group.ApplicationReceiversCode = "001903202U"; group.Date = changeOrderDate; group.ControlNumber = 245; Transaction transaction = group.AddTransaction("860", "0001"); //BCH - Beginning Segment for Purchase Order Change //Mandatory / Max Use=1 time Segment bhtSegment = transaction.AddSegment("BCH"); bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.TransactionSetPurpose, "01"); //01 is cancelllation 04 is change bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.TransactionSetTypeCode, "SA"); bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.PurchaseOrderDate, purcaseOrderDate.ToString("yyyyMMdd")); bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.ChangeRequestDate, changeOrderDate.ToString("yyyyMMdd")); //REF- Reference Identification //Optional / Max Use=1 time bhtSegment = transaction.AddSegment("REF"); bhtSegment.SetElement((int)ReferenceIdentificationIndex.ReferenceIdentificationQualifier, "IA"); bhtSegment.SetElement((int)ReferenceIdentificationIndex.ReferenceNumber, "1to30chars"); //DTM – Date/Time Reference //Optional/ Max Use=1 time bhtSegment = transaction.AddSegment("DTM"); bhtSegment.SetElement((int)DateTimeReferenceIndex.TermsTypeCode, "010"); bhtSegment.SetElement((int)DateTimeReferenceIndex.RequestedShipDate, requestedShipDate.ToString("yyyyMMdd")); //Add to test //N1 – Name //Optional / Max Use=1 //N3 – Address Information //Conditional – use if N1 used/ Max Use=2 //N4 – Geographic Location //Conditional – use if N3 used / Max Use=1 time //POC – Line Item Change //Mandatory / Max Use=1 times per loop / Max Loop=99 times //DTM – Date/Time Reference //Mandatory / Max Use=1 times per loop //CTT – Transaction Totals //Mandatory / Max Use=1 time var x12 = interchange.SerializeToX12(true); System.Diagnostics.Trace.Write(x12); }
public List <Interchange> ParseMultiple(Stream stream, Encoding encoding) { var envelopes = new List <Interchange>(); using (X12StreamReader reader = new X12StreamReader(stream, encoding)) { Interchange envelop = new Interchange(_specFinder, reader.CurrentIsaSegment); envelopes.Add(envelop); Container currentContainer = envelop; FunctionGroup fg = null; Transaction tr = null; Dictionary <string, HierarchicalLoop> hloops = new Dictionary <string, HierarchicalLoop>(); string segmentString = reader.ReadNextSegment(); string segmentId = reader.ReadSegmentId(segmentString); int segmentIndex = 1; while (segmentString.Length > 0) { switch (segmentId) { case "ISA": envelop = new Interchange(_specFinder, segmentString + reader.Delimiters.SegmentTerminator); envelopes.Add(envelop); currentContainer = envelop; fg = null; tr = null; hloops = new Dictionary <string, HierarchicalLoop>(); break; case "IEA": if (envelop == null) { throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString)); } envelop.SetTerminatingTrailerSegment(segmentString); break; case "GS": if (envelop == null) { throw new InvalidOperationException(String.Format("Segment '{0}' cannot occur before and ISA segment.", segmentString)); } currentContainer = fg = envelop.AddFunctionGroup(segmentString);; break; case "GE": if (fg == null) { throw new InvalidOperationException(String.Format("Segment '{0}' does not have a matching GS segment precending it.", segmentString)); } fg.SetTerminatingTrailerSegment(segmentString); fg = null; break; case "ST": if (fg == null) { throw new InvalidOperationException(string.Format("segment '{0}' cannot occur without a preceding GS segment.", segmentString)); } segmentIndex = 1; currentContainer = tr = fg.AddTransaction(segmentString); hloops = new Dictionary <string, HierarchicalLoop>(); break; case "SE": if (tr == null) { throw new InvalidOperationException(string.Format("Segment '{0}' does not have a matching ST segment preceding it.", segmentString)); } tr.SetTerminatingTrailerSegment(segmentString); tr = null; break; case "HL": Segment hlSegment = new Segment(null, reader.Delimiters, segmentString); string id = hlSegment.GetElement(1); string parentId = hlSegment.GetElement(2); if (parentId == "") { currentContainer = tr.AddHLoop(segmentString); } else { if (hloops.ContainsKey(parentId)) { currentContainer = hloops[parentId].AddHLoop(segmentString); } else { throw new InvalidOperationException(String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it.", id, parentId)); } } if (hloops.ContainsKey(id)) { throw new InvalidOperationException(String.Format("Hierarchical Loop {0} cannot be added to transaction {1} because the ID {2} already exists.", segmentString, tr.ControlNumber, id)); } hloops.Add(id, (HierarchicalLoop)currentContainer); break; case "TA1": // Technical acknowledgement if (envelop == null) { throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString)); } envelop.AddSegment(segmentString); break; default: while (currentContainer != null) { if (currentContainer.AddSegment(segmentString) != null) { break; } else { if (currentContainer is LoopContainer) { LoopContainer loopContainer = (LoopContainer)currentContainer; Loop newLoop = loopContainer.AddLoop(segmentString); if (newLoop != null) { currentContainer = newLoop; break; } else { if (currentContainer is Transaction) { var tran = (Transaction)currentContainer; throw new TransactionValidationException( "Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0}.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex); } else { currentContainer = currentContainer.Parent; continue; } } } else { break; } } } break; } segmentString = reader.ReadNextSegment(); segmentId = reader.ReadSegmentId(segmentString); segmentIndex++; } return(envelopes); } }
public static void Add999Transaction(this FunctionGroup group, IEnumerable <FunctionalGroupResponse> groupResponses) { int transactionId = 0; foreach (var groupResponse in groupResponses) { var trans = group.AddTransaction("999", string.Format("{0:0000}", ++transactionId)); if (group.VersionIdentifierCode.Contains("5010")) { trans.SetElement(3, group.VersionIdentifierCode); } // Functional group response header var ak1 = trans.AddSegment <TypedSegmentAK1>(new TypedSegmentAK1()); ak1.AK101_FunctionalIdCode = groupResponse.FunctionalIdCode; ak1.AK102_GroupControlNumber = groupResponse.GroupControlNumber; ak1.AK103_VersionIdentifierCode = groupResponse.VersionIdentifierCode; foreach (var response in groupResponse.TransactionSetResponses) { // Transaction Set Response Header var ak2 = trans.AddLoop <TypedLoopAK2>(new TypedLoopAK2()); ak2.AK201_TransactionSetIdentifierCode = response.TransactionSetIdentifierCode; ak2.AK202_TransactionSetControlNumber = response.TransactionSetControlNumber; if (!string.IsNullOrEmpty(response.ImplementationConventionReference)) { ak2.AK203_ImplementationConventionReference = response.ImplementationConventionReference; } foreach (var segmentError in response.SegmentErrors.OrderBy(se => se.SegmentPosition)) { var ik3 = ak2.AddLoop <TypedLoopIK3>(new TypedLoopIK3()); ik3.IK301_SegmentIdCode = segmentError.SegmentIdCode; ik3.IK302_SegmentPositionInTransactionSet = segmentError.SegmentPosition; if (segmentError.LoopIdentifierCode != null) { ik3.IK303_LoopIdentifierCode = segmentError.LoopIdentifierCode; } if (segmentError.ImplementationSegmentSyntaxErrorCode != null) { ik3.IK304_SyntaxErrorCode = segmentError.ImplementationSegmentSyntaxErrorCode; } foreach (var context in segmentError.ContextErrors) { var ctx = ik3.AddSegment <TypedSegmentCTX>(new TypedSegmentCTX()); ctx.CTX01._1_ContextName = "SITUATIONAL TRIGGER"; ctx.CTX01._2_ContextReference = context.IdentificationReference; ctx.CTX02_SegmentIdCode = context.SegmentIdCode; ctx.CTX03_SegmentPositionInTransactionSet = context.SegmentPositionInTransactionSet; ctx.CTX04_LoopIdentifierCode = context.LoopIdentifierCode; } foreach (var elementNote in segmentError.ElementNotes) { var ik4 = ik3.AddLoop <TypedLoopIK4>(new TypedLoopIK4()); ik4.IK401._1_ElementPositionInSegment = elementNote.PositionInSegment.ElementPositionInSegment; ik4.IK401._2_ComponentDataElementPositionInComposite = elementNote.PositionInSegment.ComponentDataElementPositionInComposite; ik4.IK401._3_RepeatingDataElementPosition = elementNote.PositionInSegment.RepeatingDataElementPosition; if (elementNote.DataElementReferenceNumber != null) { ik4.IK402_DataElementReferenceNumber = elementNote.DataElementReferenceNumber; } ik4.IK403_SyntaxErrorCode = elementNote.SyntaxErrorCode; if (elementNote.CopyOfBadElement != null) { ik4.IK404_CopyOfBaDataElement = elementNote.CopyOfBadElement; } foreach (var context in elementNote.ContextErrors) { var ctx = ik4.AddSegment <TypedSegmentCTX>(new TypedSegmentCTX()); ctx.CTX01._1_ContextName = "SITUATIONAL TRIGGER"; ctx.CTX01._2_ContextReference = context.IdentificationReference; ctx.CTX02_SegmentIdCode = context.SegmentIdCode; ctx.CTX03_SegmentPositionInTransactionSet = context.SegmentPositionInTransactionSet; ctx.CTX04_LoopIdentifierCode = context.LoopIdentifierCode; } } } // Transaction Set Response Trailer var ik5 = ak2.AddSegment <TypedSegmentIK5>(new TypedSegmentIK5()); ik5.IK501_TransactionSetAcknowledgmentCode = response.AcknowledgmentCode.ToString().Substring(0, 1); if (response.SyntaxErrorCodes.Count > 0) { ik5.IK502_SyntaxErrorCode = response.SyntaxErrorCodes[0]; } if (response.SyntaxErrorCodes.Count > 1) { ik5.IK503_SyntaxErrorCode = response.SyntaxErrorCodes[1]; } if (response.SyntaxErrorCodes.Count > 2) { ik5.IK504_SyntaxErrorCode = response.SyntaxErrorCodes[2]; } if (response.SyntaxErrorCodes.Count > 3) { ik5.IK505_SyntaxErrorCode = response.SyntaxErrorCodes[3]; } if (response.SyntaxErrorCodes.Count > 4) { ik5.IK506_SyntaxErrorCode = response.SyntaxErrorCodes[4]; } } // Functional group response trailer var ak9 = trans.AddSegment <TypedSegmentAK9>(new TypedSegmentAK9()); ak9.AK901_FunctionalGroupAcknowledgeCode = groupResponse.AcknowledgmentCode.ToString().Substring(0, 1); ak9.AK902_NumberOfTransactionSetsIncluded = groupResponse.TransactionSetResponses.Count; ak9.AK903_NumberOfReceivedTransactionSets = groupResponse.TransactionSetResponses.Count; ak9.AK904_NumberOfAcceptedTransactionSets = groupResponse.TransactionSetResponses.Where(tsr => tsr.AcknowledgmentCode == AcknowledgmentCodeEnum.A_Accepted || tsr.AcknowledgmentCode == AcknowledgmentCodeEnum.E_Accepted_ButErrorsWereNoted).Count(); if (groupResponse.SyntaxErrorCodes.Count > 0) { ak9.AK905_FunctionalGroupSyntaxErrorCode = groupResponse.SyntaxErrorCodes[0]; } if (groupResponse.SyntaxErrorCodes.Count > 1) { ak9.AK906_FunctionalGroupSyntaxErrorCode = groupResponse.SyntaxErrorCodes[1]; } if (groupResponse.SyntaxErrorCodes.Count > 2) { ak9.AK907_FunctionalGroupSyntaxErrorCode = groupResponse.SyntaxErrorCodes[2]; } if (groupResponse.SyntaxErrorCodes.Count > 3) { ak9.AK908_FunctionalGroupSyntaxErrorCode = groupResponse.SyntaxErrorCodes[3]; } if (groupResponse.SyntaxErrorCodes.Count > 4) { ak9.AK909_FunctionalGroupSyntaxErrorCode = groupResponse.SyntaxErrorCodes[4]; } } }
/// <summary> /// Parses all interchanges from an X12 document /// </summary> /// <param name="stream">Stream pointing to source X12 data</param> /// <param name="encoding">Stream encoding for reading data</param> /// <returns><see cref="Interchange"/> collection parsed from X12</returns> /// <exception cref="InvalidOperationException">Thrown on any missing segments or parent IDs</exception> public List <Interchange> ParseMultiple(Stream stream, Encoding encoding) { var envelopes = new List <Interchange>(); using (var reader = new X12StreamReader(stream, encoding, this.ignoredChars)) { var envelop = new Interchange(this.specFinder, reader.CurrentIsaSegment); envelopes.Add(envelop); Container currentContainer = envelop; FunctionGroup fg = null; Transaction tr = null; var hloops = new Dictionary <string, HierarchicalLoop>(); string segmentString = reader.ReadNextSegment(); string segmentId = reader.ReadSegmentId(segmentString); int segmentIndex = 1; var containerStack = new Stack <string>(); while (segmentString.Length > 0) { switch (segmentId) { case "ISA": envelop = new Interchange(this.specFinder, segmentString + reader.Delimiters.SegmentTerminator); envelopes.Add(envelop); currentContainer = envelop; fg = null; tr = null; hloops = new Dictionary <string, HierarchicalLoop>(); break; case "IEA": if (envelop == null) { throw new InvalidOperationException(string.Format(Resources.X12ParserMismatchSegment, segmentString, "ISA")); } envelop.SetTerminatingTrailerSegment(segmentString); break; case "GS": if (envelop == null) { throw new InvalidOperationException(string.Format(Resources.X12ParserMissingPrecedingSegment, segmentString, "ISA")); } currentContainer = fg = envelop.AddFunctionGroup(segmentString); break; case "GE": if (fg == null) { throw new InvalidOperationException(string.Format(Resources.X12ParserMismatchSegment, segmentString, "GS")); } fg.SetTerminatingTrailerSegment(segmentString); fg = null; break; case "ST": if (fg == null) { throw new InvalidOperationException(string.Format(Resources.X12ParserMissingGsSegment, segmentString)); } segmentIndex = 1; currentContainer = tr = fg.AddTransaction(segmentString); hloops = new Dictionary <string, HierarchicalLoop>(); break; case "SE": if (tr == null) { throw new InvalidOperationException(string.Format(Resources.X12ParserMismatchSegment, segmentString, "ST")); } tr.SetTerminatingTrailerSegment(segmentString); tr = null; break; case "HL": var hierarchicalLoopSegment = new Segment(null, reader.Delimiters, segmentString); string id = hierarchicalLoopSegment.GetElement(1); string parentId = hierarchicalLoopSegment.GetElement(2); string levelCode = hierarchicalLoopSegment.GetElement(3); while (!(currentContainer is HierarchicalLoopContainer hlCurrentContainer && hlCurrentContainer.AllowsHierarchicalLoop(levelCode))) { if (currentContainer.Parent != null) { currentContainer = currentContainer.Parent; } else { throw new InvalidOperationException(string.Format( Resources.X12ParserInvalidHLoopSpecification, segmentString, tr.ControlNumber)); } } bool parentFound = false; if (!string.IsNullOrEmpty(parentId)) { if (hloops.ContainsKey(parentId)) { parentFound = true; currentContainer = hloops[parentId].AddHLoop(segmentString); } else { if (this.throwExceptionOnSyntaxErrors) { throw new InvalidOperationException(string.Format(Resources.X12ParserMissingParentIdError, id, parentId)); } this.OnParserWarning(new X12ParserWarningEventArgs { FileIsValid = false, InterchangeControlNumber = envelop.InterchangeControlNumber, FunctionalGroupControlNumber = fg.ControlNumber, TransactionControlNumber = tr.ControlNumber, SegmentPositionInInterchange = segmentIndex, Segment = segmentString, SegmentId = segmentId, Message = string.Format(Resources.X12ParserMissingParentIdWarning, id, parentId) }); } } if (string.IsNullOrEmpty(parentId) || !parentFound) { while (!(currentContainer is HierarchicalLoopContainer hlCurrentContainer && hlCurrentContainer.HasHierachicalSpecs())) { currentContainer = currentContainer.Parent; } currentContainer = ((HierarchicalLoopContainer)currentContainer).AddHLoop(segmentString); } if (hloops.ContainsKey(id)) { throw new InvalidOperationException(string.Format(Resources.X12ParserHLoopIdExists, segmentString, tr.ControlNumber, id)); } hloops.Add(id, (HierarchicalLoop)currentContainer); break; case "TA1": if (envelop == null) { throw new InvalidOperationException(string.Format(Resources.X12ParserMismatchSegment, segmentString, "ISA")); } envelop.AddSegment(segmentString); break; default: var originalContainer = currentContainer; containerStack.Clear(); while (currentContainer != null) { if (currentContainer.AddSegment(segmentString) != null) { if (segmentId == "LE") { currentContainer = currentContainer.Parent; } break; } if (currentContainer is LoopContainer loopContainer) { Loop newLoop = loopContainer.AddLoop(segmentString); if (newLoop != null) { currentContainer = newLoop; break; } if (currentContainer is Transaction tran) { if (this.throwExceptionOnSyntaxErrors) { throw new TransactionValidationException( Resources.X12ParserSegmentCannotBeIdentitied, tran.IdentifierCode, tran.ControlNumber, string.Empty, segmentString, segmentIndex, string.Join(",", containerStack)); } currentContainer = originalContainer; currentContainer.AddSegment(segmentString, true); this.OnParserWarning(new X12ParserWarningEventArgs { FileIsValid = false, InterchangeControlNumber = envelop.InterchangeControlNumber, FunctionalGroupControlNumber = fg.ControlNumber, TransactionControlNumber = tran.ControlNumber, SegmentPositionInInterchange = segmentIndex, SegmentId = segmentId, Segment = segmentString, Message = string.Format( Resources.X12ParserSegmentWarning, tran.IdentifierCode, tran.ControlNumber, segmentString, segmentIndex, string.Join(",", containerStack), containerStack.LastOrDefault()) }); break; } if (currentContainer is Loop containerLoop) { containerStack.Push(containerLoop.Specification.LoopId); } if (currentContainer is HierarchicalLoop hloop) { containerStack.Push($"{hloop.Specification.LoopId}[{hloop.Id}]"); } currentContainer = currentContainer.Parent; continue; } break; } break; } segmentString = reader.ReadNextSegment(); segmentId = reader.ReadSegmentId(segmentString); segmentIndex++; } return(envelopes); } }
public void CreatePurchaseOrderChangeNotice860() { string expected = @"ISA*00* *00* *01*828513080 *01*001903202U *100818*0850*U*00401*000000245*0*P*:~ GS*PO*828513080*001903202U*20100818*0850*245*X*005010X222~ ST*860*0001~ BCH*01*SA****20100817*****20100818~ REF*IA*1to30chars~ DTM*010*20100819~ SE*5*0001~ GE*1*1~ IEA*1*000000245~"; var purcaseOrderDate = new DateTime(2010, 8, 17, 08, 50, 0); DateTime changeOrderDate = purcaseOrderDate.AddDays(1d); DateTime requestedShipDate = purcaseOrderDate.AddDays(2d); var interchange = new Interchange(changeOrderDate, 245, true) { InterchangeSenderIdQualifier = "01", InterchangeSenderId = "828513080", InterchangeReceiverIdQualifier = "01", InterchangeReceiverId = "001903202U", InterchangeDate = changeOrderDate, }; interchange.SetElement(14, "0"); FunctionGroup group = interchange.AddFunctionGroup("PO", changeOrderDate, 1, "005010X222"); group.ApplicationSendersCode = "828513080"; group.ApplicationReceiversCode = "001903202U"; group.Date = changeOrderDate; group.ControlNumber = 245; Transaction transaction = group.AddTransaction("860", "0001"); Segment bhtSegment = transaction.AddSegment("BCH"); bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.TransactionSetPurpose, "01"); //01 is cancelllation 04 is change bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.TransactionSetTypeCode, "SA"); bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.PurchaseOrderDate, purcaseOrderDate.ToString("yyyyMMdd")); bhtSegment.SetElement((int)BeginningSegmentPurchaseOrderChangeIndex.ChangeRequestDate, changeOrderDate.ToString("yyyyMMdd")); bhtSegment = transaction.AddSegment("REF"); bhtSegment.SetElement((int)ReferenceIdentificationIndex.ReferenceIdentificationQualifier, "IA"); bhtSegment.SetElement((int)ReferenceIdentificationIndex.ReferenceNumber, "1to30chars"); bhtSegment = transaction.AddSegment("DTM"); bhtSegment.SetElement((int)DateTimeReferenceIndex.TermsTypeCode, "010"); bhtSegment.SetElement((int)DateTimeReferenceIndex.RequestedShipDate, requestedShipDate.ToString("yyyyMMdd")); //Add to test //N1 – Name //Optional / Max Use=1 //N3 – Address Information //Conditional – use if N1 used/ Max Use=2 //N4 – Geographic Location //Conditional – use if N3 used / Max Use=1 time //POC – Line Item Change //Mandatory / Max Use=1 times per loop / Max Loop=99 times //DTM – Date/Time Reference //Mandatory / Max Use=1 times per loop //CTT – Transaction Totals //Mandatory / Max Use=1 time var x12 = interchange.SerializeToX12(true); Assert.AreEqual(expected, x12); }
public Transaction CreateProfessionalTransaction(ClaimLine claim, FunctionGroup fg, FileConfigModel config, int parentControlNumber = 1) { var controlNumber = parentControlNumber.ToString("D9"); // = (fg.Transactions.Count + 1).ToString("D9"); var t = fg.AddTransaction("837", controlNumber); try { if (!string.IsNullOrWhiteSpace(fg.VersionIdentifierCode)) { t.SetElement(3, fg.VersionIdentifierCode); } } catch { } var bht = t.AddSegment("BHT"); bht.SetElement(1, "0019"); bht.SetElement(2, "00"); bht.SetElement(3, t.ControlNumber); bht.SetElement(4, DateTime.UtcNow.ToString("yyyyMMdd")); bht.SetElement(5, DateTime.UtcNow.ToString("hhmm")); bht.SetElement(6, "CH"); var submitterProvider = new ProviderInfo() { FirstName = "", LastName = "SUBMITTER NAME", ProviderId = 1, ProviderTypeId = 2, AlternateId = "ID", WorkPhoneNumber = "3050000000" }; var sender = t.AddLoop(new TypedLoopNM1("41")); sender.NM102_EntityTypeQualifier = EntityTypeQualifier.Person; if (submitterProvider.ProviderTypeId == 2) { sender.NM102_EntityTypeQualifier = EntityTypeQualifier.NonPersonEntity; sender.NM103_NameLastOrOrganizationName = submitterProvider.FullName.Clean(35); } else { if (submitterProvider?.LastName != null) { sender.NM103_NameLastOrOrganizationName = submitterProvider.LastName.Clean(35); sender.NM104_NameFirst = submitterProvider.FirstName.Clean(35); } } //SUBMITTER sender.NM108_IdCodeQualifier = "46"; //ETIN if (!String.IsNullOrWhiteSpace(config.SenderIDQualifier) && config.SenderIDQualifier != "30") { sender.NM108_IdCodeQualifier = config.SenderIDQualifier; } sender.NM109_IdCode = config.SenderID.Clean(); var senderPer = sender.AddSegment(new TypedSegmentPER()); senderPer.PER01_ContactFunctionCode = "IC"; //INMEDIATA BUSINESS RULE var nameTest = (sender.NM104_NameFirst + " " + sender.NM103_NameLastOrOrganizationName).Clean(); if (nameTest != submitterProvider.FullName.Clean()) { senderPer.PER02_Name = submitterProvider.FullName.Clean(); } if (!string.IsNullOrWhiteSpace(submitterProvider.WorkPhoneNumber)) { senderPer.PER03_CommunicationNumberQualifier = CommunicationNumberQualifer.Telephone; senderPer.PER04_CommunicationNumber = submitterProvider.WorkPhoneNumber.StripNonNumeric(); } else { senderPer.PER03_CommunicationNumberQualifier = CommunicationNumberQualifer.Telephone; senderPer.PER04_CommunicationNumber = "3050001234"; } //END SUBMITTER //Loop 1000B var reciever = t.AddLoop(new TypedLoopNM1("40")); reciever.NM102_EntityTypeQualifier = EntityTypeQualifier.NonPersonEntity; reciever.NM103_NameLastOrOrganizationName = "RECIEVER NAME"; reciever.NM108_IdCodeQualifier = "46"; reciever.NM109_IdCode = fg.Interchange.InterchangeReceiverId != null?fg.Interchange.InterchangeReceiverId.Trim() : ""; //BILLER var providerLoop = t.AddHLoop("1", "20", true); var billingProvider = new ProviderInfo() { FirstName = "", LastName = "LASTNAME", ProviderId = 1, ProviderTypeId = 2, ProviderNPI = 1111111111, AlternateId = "660000000", WorkAddress1 = "", WorkAddress2 = "", WorkCity = "", WorkPhoneNumber = "" }; if (!String.IsNullOrWhiteSpace(billingProvider.SpecialtyCode)) { var provSpecialty = providerLoop.AddSegment(new TypedSegmentPRV()); provSpecialty.PRV01_ProviderCode = "BI"; provSpecialty.PRV02_ReferenceIdQualifier = "PXC"; provSpecialty.PRV03_ProviderTaxonomyCode = billingProvider.SpecialtyCode; } var provName = providerLoop.AddLoop(new TypedLoopNM1("85")); provName.NM102_EntityTypeQualifier = EntityTypeQualifier.Person; if (billingProvider.ProviderTypeId == 2) { provName.NM102_EntityTypeQualifier = EntityTypeQualifier.NonPersonEntity; provName.NM103_NameLastOrOrganizationName = billingProvider.FullName.Clean(35); } else { if (!string.IsNullOrWhiteSpace(billingProvider.FirstName)) { provName.NM103_NameLastOrOrganizationName = billingProvider.LastName.Clean(35); provName.NM104_NameFirst = billingProvider.FirstName.Clean(35); } } provName.NM108_IdCodeQualifier = "XX";//NPI provName.NM109_IdCode = billingProvider.ProviderNPI?.ToString(); //QH if (billingProvider.WorkAddress1 != null) { AddNm1Address(provName, billingProvider.WorkAddress1, billingProvider.WorkAddress2, "", billingProvider.WorkCity, "FL"); } //CONTACT var provNameRef = provName.AddSegment(new TypedSegmentREF()); if (!string.IsNullOrWhiteSpace(billingProvider.AlternateId) && billingProvider.AlternateId.StartsWith("66")) { provNameRef.REF01_ReferenceIdQualifier = "EI"; } else { provNameRef.REF01_ReferenceIdQualifier = "SY"; } provNameRef.REF02_ReferenceId = billingProvider.AlternateId; //PATIENT var subscriberLoop = providerLoop.AddHLoop("2", "22", false); //PLAN if (!string.IsNullOrWhiteSpace(claim.ContractNumber)) { var sbr = subscriberLoop.AddSegment(new TypedSegmentSBR()); sbr.SBR01_PayerResponsibilitySequenceNumberCode = "P"; sbr.SBR02_IndividualRelationshipCode = "18"; sbr.SBR09_ClaimFilingIndicatorCode = "CI"; } if (!string.IsNullOrWhiteSpace(claim.PatientFirstName)) { var subsName = subscriberLoop.AddLoop(new TypedLoopNM1("IL")); subsName.NM102_EntityTypeQualifier = EntityTypeQualifier.Person; subsName.NM103_NameLastOrOrganizationName = claim.PatientLastName.Clean(); subsName.NM104_NameFirst = claim.PatientFirstName.Clean(); //if (!String.IsNullOrWhiteSpace(claim.PatientName)) // subsName.NM105_NameMiddle = TypeEx.Clean(claim.PatientName); if (!string.IsNullOrWhiteSpace(claim.ContractNumber)) { subsName.NM108_IdCodeQualifier = "MI";//Health Plan Member Identification Number subsName.NM109_IdCode = claim.ContractNumber.Clean(); } //Address AddNm1Address(subsName, "ADDRESS1", "ADDRESS2", "33176", "MIAMI", "FL"); var subsNameDMG = subsName.AddSegment(new TypedSegmentDMG()); subsNameDMG.DMG01_DateTimePeriodFormatQualifier = $"D{DTPFormatQualifier.MMDDCCYY.ToString("d")}"; //"D8"; subsNameDMG.DMG02_DateOfBirth = claim.MemberBirthDate ?? fillerBirthDate; subsNameDMG.DMG03_Gender = Gender.Unknown; } //PAYER var pay = subscriberLoop.AddLoop(new TypedLoopNM1("PR")); pay.NM102_EntityTypeQualifier = EntityTypeQualifier.NonPersonEntity; pay.NM103_NameLastOrOrganizationName = "PAYER MEDICAL"; pay.NM108_IdCodeQualifier = "PI"; pay.NM109_IdCode = "GHP6600000000"; //CLAIM - LOOP 2300 var clm = subscriberLoop.AddLoop(new TypedLoopCLM()); clm.CLM02_TotalClaimChargeAmount = claim.Tariff ?? 0; clm.CLM05._1_FacilityCodeValue = "11"; clm.CLM05._2_FacilityCodeQualifier = "B"; clm.CLM05._3_ClaimFrequencyTypeCode = "1"; //CLAIM NUMBER if (!string.IsNullOrWhiteSpace(claim.ClaimNumber)) { //CLM Claim Information clm.CLM01_PatientControlNumber = claim.ClaimNumber.ToString(); //clm.CLM05._3_ClaimFrequencyTypeCode = "7"; //Header //bht.SetElement(2, "18");//Reissue //original claim from reissue //var ref = clm.AddSegment(new TypedSegmentREF()); //ref.REF01_ReferenceIdQualifier = "F8"; //ref.REF02_ReferenceId = claim.ClaimNumber; } if (!string.IsNullOrWhiteSpace(claim.PlaceOfService)) { clm.CLM05._1_FacilityCodeValue = claim.PlaceOfService; } clm.CLM06_ProviderOrSupplierSignatureIndicator = true; clm.CLM07_ProviderAcceptAssignmentCode = "A"; clm.CLM08_BenefitsAssignmentCerficationIndicator = "Y"; clm.CLM09_ReleaseOfInformationCode = "Y"; clm.CLM10_PatientSignatureSourceCode = "P"; //Add DX var dxList = new List <string>(); if (!string.IsNullOrWhiteSpace(claim.Dx1)) { dxList.Add(claim.Dx1.Clean()); } if (!string.IsNullOrWhiteSpace(claim.Dx2)) { dxList.Add(claim.Dx2.Clean()); } if (!string.IsNullOrWhiteSpace(claim.Dx3)) { dxList.Add(claim.Dx3.Clean()); } if (!string.IsNullOrWhiteSpace(claim.Dx4)) { dxList.Add(claim.Dx4.Clean()); } if (!string.IsNullOrWhiteSpace(claim.Dx5)) { dxList.Add(claim.Dx5.Clean()); } if (!string.IsNullOrWhiteSpace(claim.Dx6)) { dxList.Add(claim.Dx6.Clean()); } if (!string.IsNullOrWhiteSpace(claim.Dx7)) { dxList.Add(claim.Dx7.Clean()); } if (dxList.Count > 0) { var hiSegment = clm.AddSegment(new TypedSegmentHI()); foreach (var item in dxList) { var index = dxList.IndexOf(item) + 1; if (string.IsNullOrWhiteSpace(item)) { continue; } var prefix = "A"; //inmediata requires dotless notation var code = item.Replace(".", "").ToUpper(); if (index == 1) { hiSegment.HI01_HealthCareCodeInformation = prefix + "BK:" + code; } if (index == 2) { hiSegment.HI02_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 3) { hiSegment.HI03_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 4) { hiSegment.HI04_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 5) { hiSegment.HI05_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 6) { hiSegment.HI06_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 7) { hiSegment.HI07_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 8) { hiSegment.HI08_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 9) { hiSegment.HI09_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 10) { hiSegment.HI10_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 11) { hiSegment.HI11_HealthCareCodeInformation = prefix + "BF:" + code; } if (index == 12) { hiSegment.HI12_HealthCareCodeInformation = prefix + "BF:" + code; } } } var serviceList = new List <string>(); if (!string.IsNullOrWhiteSpace(claim.CPT)) { serviceList.Add(claim.CPT.Clean()); } int cnt = 1; foreach (var serviceCode in serviceList) { if (!string.IsNullOrWhiteSpace(claim.RenderNPI)) { var clmProv = AddClmProvider(clm, claim, "82", "PE", "PXC"); } //Service var svc1 = clm.AddLoop(new TypedLoopLX("LX")); svc1.LX01_AssignedNumber = cnt.ToString(); var compositeCodeBuilder = new System.Text.StringBuilder(); if (!string.IsNullOrWhiteSpace(serviceCode)) { compositeCodeBuilder.Append("HC:" + serviceCode.Clean()); } var svc101 = svc1.AddSegment(new TypedSegmentSV1()); if (!string.IsNullOrWhiteSpace(serviceCode)) { svc101.SV101_CompositeMedicalProcedure = compositeCodeBuilder.ToString(); } //AMOUNT svc101.SV102_MonetaryAmount = claim.Tariff.toString("F"); svc101.SV103_UnitBasisMeasCode = "UN"; svc101.SV104_Quantity = "1"; //Only when not the same as CLM05 if (!string.IsNullOrWhiteSpace(claim.PlaceOfService) && clm.CLM05._1_FacilityCodeValue != claim.PlaceOfService) { svc101.SV105_FacilityCode = claim.PlaceOfService; } //DX Pointer svc101.SV107_CompDiagCodePoint = "1"; var svc101DTP = svc1.AddSegment(new TypedSegmentDTP()); svc101DTP.DTP01_DateTimeQualifier = DTPQualifier.Service; if (claim.ServiceFrom.HasValue && claim.ServiceTo.HasValue) { svc101DTP.DTP02_DateTimePeriodFormatQualifier = DTPFormatQualifier.CCYYMMDD_CCYYMMDD; svc101DTP.DTP03_Date = new DateTimePeriod(claim.ServiceFrom.Value, claim.ServiceTo.Value); } else if (claim.ServiceFrom.HasValue) { svc101DTP.DTP02_DateTimePeriodFormatQualifier = DTPFormatQualifier.CCYYMMDD; svc101DTP.DTP03_Date = new DateTimePeriod(claim.ServiceFrom.Value); } //End Service Date cnt++; } return(t); }
public void CreatePurchaseOrder850(PurchaseOrder purchaseOrder, string fileName) { DateTime purcaseOrderDate = DateTime.Now; Interchange interchange = new Interchange(purcaseOrderDate, Convert.ToInt32(purchaseOrder.Number), true) { InterchangeSenderIdQualifier = "ZZ", InterchangeSenderId = InterchangeSenderId, InterchangeReceiverIdQualifier = "ZZ", InterchangeReceiverId = InterchangeReceiverId, InterchangeDate = purcaseOrderDate, }; interchange.SetElement(14, "0"); //No Aknowlegement is 0 FunctionGroup group = interchange.AddFunctionGroup("PO", purcaseOrderDate, Convert.ToInt32(purchaseOrder.Number), "004010"); group.ApplicationSendersCode = InterchangeSenderId; group.ApplicationReceiversCode = InterchangeReceiverId; // group.Date = purcaseOrderDate; // group.ControlNumber = Convert.ToInt32(purchaseOrder.Number); Transaction transaction = group.AddTransaction("850", "0001"); Segment bhtSegment = transaction.AddSegment("BEG"); bhtSegment.SetElement(1, "00"); bhtSegment.SetElement(2, "SA"); bhtSegment.SetElement(3, purchaseOrder.Number); bhtSegment.SetElement(5, purcaseOrderDate.ToString("yyyyMMdd")); //bhtSegment = transaction.AddSegment("CUR"); //bhtSegment.SetElement(1, "BY"); //bhtSegment.SetElement(2, "USD"); //bhtSegment = transaction.AddSegment("PER"); //bhtSegment.SetElement(1, "IC"); //bhtSegment.SetElement(2, "Doe,Jane"); //bhtSegment.SetElement(8, "Doe,Jane"); //bill to section Loop loop = transaction.AddLoop("N1"); loop.SetElement(1, "BT"); loop.SetElement(2, purchaseOrder.Customer.BillingName); loop.SetElement(3, 92); loop.SetElement(4, purchaseOrder.Customer.BillingAddress.Id); Segment segment = loop.AddSegment("N3"); segment.SetElement(1, purchaseOrder.Customer.BillingAddress.Street); segment.SetElement(2, purchaseOrder.Customer.BillingAddress.City + " " + purchaseOrder.Customer.BillingAddress.State + " " + purchaseOrder.Customer.BillingAddress.PostalCode + " " + purchaseOrder.Customer.BillingAddress.Country); segment = loop.AddSegment("N4"); segment.SetElement(1, purchaseOrder.Customer.BillingAddress.City); segment.SetElement(2, purchaseOrder.Customer.BillingAddress.ShortState); // short state segment.SetElement(3, purchaseOrder.Customer.BillingAddress.PostalCode); segment.SetElement(4, purchaseOrder.Customer.BillingAddress.ShortCountry); //short country //ship to to section loop = transaction.AddLoop("N1"); loop.SetElement(1, "ST"); loop.SetElement(2, purchaseOrder.Customer.ShippingName); loop.SetElement(3, 92); loop.SetElement(4, purchaseOrder.Customer.ShippingAddress.Id); segment = loop.AddSegment("N3"); segment.SetElement(1, purchaseOrder.Customer.ShippingAddress.Street); segment.SetElement(2, purchaseOrder.Customer.ShippingAddress.City + " " + purchaseOrder.Customer.ShippingAddress.State + " " + purchaseOrder.Customer.ShippingAddress.PostalCode + " " + purchaseOrder.Customer.ShippingAddress.Country); segment = loop.AddSegment("N4"); segment.SetElement(1, purchaseOrder.Customer.ShippingAddress.City); segment.SetElement(2, purchaseOrder.Customer.BillingAddress.ShortState); // short state segment.SetElement(3, purchaseOrder.Customer.BillingAddress.PostalCode); segment.SetElement(4, purchaseOrder.Customer.BillingAddress.ShortCountry); //short country int count = 1; foreach (LineItem lineItem in purchaseOrder.Items) { loop = transaction.AddLoop("PO1"); loop.SetElement(1, count++); loop.SetElement(2, lineItem.Quantity); loop.SetElement(3, "EA"); loop.SetElement(4, lineItem.Price); loop.SetElement(6, "CGT"); loop.SetElement(7, lineItem.SupplierItemNumber); } loop = transaction.AddLoop("CTT"); loop.SetElement(1, --count); var x12 = interchange.SerializeToX12(true); Console.WriteLine(x12); // Write the string to a file. fileName += purchaseOrder.Number + ".850"; System.IO.StreamWriter file = new System.IO.StreamWriter(fileName); file.WriteLine(x12); file.Close(); }
public void CreatePurchaseOrder850() { DateTime purcaseOrderDate = DateTime.Now; Interchange interchange = new Interchange(purcaseOrderDate, 245, true) { InterchangeSenderIdQualifier = "01", InterchangeSenderId = "828513080", InterchangeReceiverIdQualifier = "01", InterchangeReceiverId = "001903202U", InterchangeDate = purcaseOrderDate, }; interchange.SetElement(14, "0"); //No Aknowlegement is 0 FunctionGroup group = interchange.AddFunctionGroup("PO", purcaseOrderDate, 1, "005010X222"); group.ApplicationSendersCode = "828513080"; group.ApplicationReceiversCode = "001903202U"; group.Date = purcaseOrderDate; group.ControlNumber = 245; Transaction transaction = group.AddTransaction("850", "0001"); Segment bhtSegment = transaction.AddSegment("BEG"); bhtSegment.SetElement(1, "00"); bhtSegment.SetElement(2, "SA"); bhtSegment.SetElement(3, "S41000439"); bhtSegment.SetElement(5, "20100810"); bhtSegment = transaction.AddSegment("CUR"); bhtSegment.SetElement(1, "BY"); bhtSegment.SetElement(2, "USD"); bhtSegment = transaction.AddSegment("PER"); bhtSegment.SetElement(1, "IC"); bhtSegment.SetElement(2, "Doe,Jane"); bhtSegment.SetElement(8, "Doe,Jane"); // Bill to address Loop loop = transaction.AddLoop("N1"); loop.SetElement(1, "BT"); loop.SetElement(2, "Doe Jane"); loop.SetElement(3, 92); loop.SetElement(4, 10001); Segment segment = loop.AddSegment("N3"); segment.SetElement(1, "Street"); segment.SetElement(2, "City State Pin Country"); segment = loop.AddSegment("N4"); segment.SetElement(1, "City"); segment.SetElement(2, "SS"); segment.SetElement(3, "PIN"); segment.SetElement(4, "SC"); // ship to address loop = transaction.AddLoop("N1"); loop.SetElement(1, "ST"); loop.SetElement(2, "Doe Jane"); loop.SetElement(3, 92); loop.SetElement(4, 10001); segment = loop.AddSegment("N3"); segment.SetElement(1, "Street"); segment.SetElement(2, "City State Pin Country"); segment = loop.AddSegment("N4"); segment.SetElement(1, "City"); segment.SetElement(2, "SS"); segment.SetElement(3, "PIN"); segment.SetElement(4, "SC"); // add products ordered loop = transaction.AddLoop("PO1"); loop.SetElement(1, "1"); loop.SetElement(2, 10); loop.SetElement(3, "EA"); loop.SetElement(4, "10.2"); loop.SetElement(6, "IB"); loop.SetElement(7, "100001"); var x12 = interchange.SerializeToX12(true); Console.WriteLine(x12); }
public List <Interchange> ParseMultiple(Stream stream, Encoding encoding) { var envelopes = new List <Interchange>(); using (X12StreamReader reader = new X12StreamReader(stream, encoding, _ignoredChars)) { Interchange envelop = new Interchange(_specFinder, reader.CurrentIsaSegment); envelopes.Add(envelop); Container currentContainer = envelop; FunctionGroup fg = null; Transaction tr = null; Dictionary <string, HierarchicalLoop> hloops = new Dictionary <string, HierarchicalLoop>(); string segmentString = reader.ReadNextSegment(); string segmentId = reader.ReadSegmentId(segmentString); int segmentIndex = 1; Stack <string> containerStack = new Stack <string>(); while (segmentString.Length > 0) { switch (segmentId) { case "ISA": envelop = new Interchange(_specFinder, segmentString + reader.Delimiters.SegmentTerminator); envelopes.Add(envelop); currentContainer = envelop; fg = null; tr = null; hloops = new Dictionary <string, HierarchicalLoop>(); break; case "IEA": if (envelop == null) { throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString)); } envelop.SetTerminatingTrailerSegment(segmentString); break; case "GS": if (envelop == null) { throw new InvalidOperationException(String.Format("Segment '{0}' cannot occur before and ISA segment.", segmentString)); } currentContainer = fg = envelop.AddFunctionGroup(segmentString);; break; case "GE": if (fg == null) { throw new InvalidOperationException(String.Format("Segment '{0}' does not have a matching GS segment precending it.", segmentString)); } fg.SetTerminatingTrailerSegment(segmentString); fg = null; break; case "ST": if (fg == null) { throw new InvalidOperationException(string.Format("segment '{0}' cannot occur without a preceding GS segment.", segmentString)); } segmentIndex = 1; currentContainer = tr = fg.AddTransaction(segmentString); hloops = new Dictionary <string, HierarchicalLoop>(); break; case "SE": if (tr == null) { throw new InvalidOperationException(string.Format("Segment '{0}' does not have a matching ST segment preceding it.", segmentString)); } tr.SetTerminatingTrailerSegment(segmentString); tr = null; break; case "HL": Segment hlSegment = new Segment(null, reader.Delimiters, segmentString); string id = hlSegment.GetElement(1); string parentId = hlSegment.GetElement(2); string levelCode = hlSegment.GetElement(3); while (!(currentContainer is HierarchicalLoopContainer) || !((HierarchicalLoopContainer)currentContainer).AllowsHierarchicalLoop(levelCode)) { if (currentContainer.Parent != null) { currentContainer = currentContainer.Parent; } else { throw new InvalidOperationException(String.Format("Heierchical Loop {0} cannot be added to transaction set {1} because it's specification cannot be identified.", segmentString, tr.ControlNumber)); } } bool parentFound = false; if (parentId != "") { if (hloops.ContainsKey(parentId)) { parentFound = true; currentContainer = hloops[parentId].AddHLoop(segmentString); } else { if (_throwExceptionOnSyntaxErrors) { throw new InvalidOperationException(String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it. To change this to a warning, pass throwExceptionOnSyntaxErrors = false to the X12Parser constructor.", id, parentId)); } else { OnParserWarning(new X12ParserWarningEventArgs { FileIsValid = false, InterchangeControlNumber = envelop.InterchangeControlNumber, FunctionalGroupControlNumber = fg.ControlNumber, TransactionControlNumber = tr.ControlNumber, SegmentPositionInInterchange = segmentIndex, Segment = segmentString, SegmentId = segmentId, Message = String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it. This will be parsed as if it has no parent, but the file may not be valid.", id, parentId) }); } } } if (parentId == "" || !parentFound) { while (!(currentContainer is HierarchicalLoopContainer && ((HierarchicalLoopContainer)currentContainer).HasHierachicalSpecs())) { currentContainer = currentContainer.Parent; } currentContainer = ((HierarchicalLoopContainer)currentContainer).AddHLoop(segmentString); //hloops = new Dictionary<string, HierarchicalLoop>(); } if (hloops.ContainsKey(id)) { throw new InvalidOperationException(String.Format("Hierarchical Loop {0} cannot be added to transaction {1} because the ID {2} already exists.", segmentString, tr.ControlNumber, id)); } hloops.Add(id, (HierarchicalLoop)currentContainer); break; case "TA1": // Technical acknowledgement if (envelop == null) { throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString)); } envelop.AddSegment(segmentString); break; default: var originalContainer = currentContainer; containerStack.Clear(); while (currentContainer != null) { if (currentContainer.AddSegment(segmentString) != null) { if (segmentId == "LE") { currentContainer = currentContainer.Parent; } break; } else { if (currentContainer is LoopContainer) { LoopContainer loopContainer = (LoopContainer)currentContainer; Loop newLoop = loopContainer.AddLoop(segmentString); if (newLoop != null) { currentContainer = newLoop; break; } else { if (currentContainer is Transaction) { var tran = (Transaction)currentContainer; if (_throwExceptionOnSyntaxErrors) { throw new TransactionValidationException( "Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0} in any of the expected loops: {5}. To change this to a warning, pass throwExceptionOnSyntaxErrors = false to the X12Parser constructor.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex, string.Join(",", containerStack)); } else { currentContainer = originalContainer; currentContainer.AddSegment(segmentString, true); OnParserWarning(new X12ParserWarningEventArgs { FileIsValid = false, InterchangeControlNumber = envelop.InterchangeControlNumber, FunctionalGroupControlNumber = fg.ControlNumber, TransactionControlNumber = tran.ControlNumber, SegmentPositionInInterchange = segmentIndex, SegmentId = segmentId, Segment = segmentString, Message = string.Format("Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0} in any of the expected loops: {5}. It will be added to loop {6}, but this may invalidate all subsequent segments.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex, string.Join(",", containerStack), containerStack.LastOrDefault()) }); break; } } else { if (currentContainer is Loop) { containerStack.Push(((Loop)currentContainer).Specification.LoopId); } if (currentContainer is HierarchicalLoop) { var hloop = ((HierarchicalLoop)currentContainer); containerStack.Push(string.Format("{0}[{1}]", hloop.Specification.LoopId, hloop.Id)); } currentContainer = currentContainer.Parent; continue; } } } else { break; } } } break; } segmentString = reader.ReadNextSegment(); segmentId = reader.ReadSegmentId(segmentString); segmentIndex++; } return(envelopes); } }