private void CheckMissingMandatoryElements(IPluglet currentPluglet, IDocumentFragment currentDocumentFragment) { foreach (IPluglet childPluglet in currentPluglet.Children) { if (childPluglet.IsMandatory == false) { continue; } bool childExist = false; foreach (IDocumentFragment childDocumentFragment in currentDocumentFragment.Children) { if (childDocumentFragment.Pluglet.Tag == childPluglet.Tag) { childExist = true; break; } } EdiErrorType errorType = EdiErrorType.Error; if (childPluglet.IsIgnore) { errorType = EdiErrorType.Warning; } if (childExist == false) { Errors.AddSegmentError(childPluglet.Tag, X12ErrorCode.MandatorySegmentMissingCode , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.MandatorySegmentMissingCode), childPluglet.Tag) , CurrentElementNumber, CurrentLinePayloadStart + TotalPayloadLength, CurrentLinePayloadEnd + TotalPayloadLength, errorType); } } }
private IDocumentFragment ConstructNewDocumentFragment(string elementName, IPluglet currentPluglet, IDocumentFragment currentDocumentFragment) { IDocumentFragment newDocumentPluglet = null; IPluglet nextPluglet = null; // Special case for root pluglet if (CurrentElementNumber == 0) { nextPluglet = currentPluglet; string rootNodeName = elementName; int pos = elementName.IndexOf(":"); if (pos != -1) { rootNodeName = elementName.Substring(pos + 1); } if (string.Equals(nextPluglet.Tag, rootNodeName, StringComparison.InvariantCultureIgnoreCase) == false) { Errors.AddSegmentError(elementName, -1, string.Format("Invalid root node name. Expected: {0}, Actual {1}", nextPluglet.Tag, rootNodeName), CurrentElementNumber, CurrentLinePayloadStart + TotalPayloadLength, CurrentLinePayloadEnd + TotalPayloadLength, EdiErrorType.Error); } } else { foreach (IPluglet childPluglet in currentPluglet.Children) { if (string.Equals(childPluglet.Tag, elementName, StringComparison.InvariantCultureIgnoreCase)) { nextPluglet = childPluglet; break; } } } if (nextPluglet == null) { Errors.AddSegmentError(elementName, X12ErrorCode.UnrecognizedSegmentIDCode, X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), CurrentElementNumber, CurrentLinePayloadStart + TotalPayloadLength, CurrentLinePayloadEnd + TotalPayloadLength, EdiErrorType.Error); // TODO: Should we add 'Unrecognized segment' pluglet here? } else { newDocumentPluglet = new DocumentFragment() { Parent = currentDocumentFragment, Pluglet = nextPluglet, Value = elementName, }; if (currentDocumentFragment.Children == null) { ((DocumentFragment)currentDocumentFragment).Children = new List <IDocumentFragment>(); } currentDocumentFragment.Children.Add(newDocumentPluglet); } return(newDocumentPluglet); }
/// <summary> /// Find corrosponding Pluglet for given segmentname and create new segment /// </summary> /// <param name="segmentName"></param> /// <param name="segmentDetails"></param> private void CreateAndAddNewSegment(string segmentName, string[] segmentDetails) { const string firstSegmentName = "ST"; string errorMsgs = string.Empty; IPluglet nextPluglet; string location = "EDIReader.CreateAndAddNewSegment"; Logger.Debug(location, "Adding {0} segment", segmentName); string missingMandatorySegments; nextPluglet = CurrentPluglet.GetSegmentPluglet(segmentName, segmentDetails, firstSegmentName, out missingMandatorySegments); // First add missing mandatory segment errors if (nextPluglet != null && !string.IsNullOrWhiteSpace(missingMandatorySegments)) { string error = string.Format("Missing mandatory segments ({0}) between {1} and {2}" , missingMandatorySegments, CurrentPluglet.Tag, segmentName); if (FatpipeDocumentInst.Errors == null) { FatpipeDocumentInst.Errors = new List <string>(); } FatpipeDocumentInst.Errors.Add(error); Logger.Error("EDIReader.CreateAndAddNewSegment", EventId.EDIReaderMissingMandatorySegment, "{0} - {1}", GetCurrentPosContext(), error); EdiErrorType errorType = nextPluglet.IsIgnore ? EdiErrorType.Warning : EdiErrorType.Error; foreach (string segment in missingMandatorySegments.Split(',')) { Errors.AddSegmentError(segmentName, X12ErrorCode.MandatorySegmentMissingCode , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.MandatorySegmentMissingCode), segment) , SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, errorType); } } if (nextPluglet == null) { /* //TODO: Revisit following if condition - do we really want to ignore ISA/GS segment missing in schema? * if (segmentName != "ISA" && segmentName != "GS") * { * errors = string.Format("{0} segment not found in schema after {1}", segmentName, CurrentPluglet.Name); * * Logger.Error(location, EventId.EDIReaderUnknownSegment, "{0} - {1}", GetCurrentPosContext(), errors); * Errors.AddSegmentError(segmentName, X12ErrorCode.UnrecognizedSegmentIDCode * , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), SegmentNumber); * } */ //experimenting with unknown here above is actual //IPluglet unknown = new Pluglet("UNRECOGNIZED_SEGMENT", "Unknown Segment", PlugletType.Segment, CurrentPluglet.Parent); IPluglet unknown = new Pluglet( new PlugletInput() { Name = "UNRECOGNIZED_SEGMENT", Definition = "Unknown Segment", Type = PlugletType.Segment, Parent = CurrentPluglet.Parent, IsIgnore = false, AddToParent = false, IsTagSameAsName = true, }); // IPluglet x = new Pluglet("child"+i, "Unknown Data", PlugletType.Data, unknown); //unknown.Children.Add(x); //} //DocumentFragment newFragment = unknown.ConstructDocumentFragment(segmentDetails, false, EDIDelimiters, out errors); errorMsgs = string.Format("{0} segment not found in schema after {1}", segmentName, CurrentPluglet.Name); Errors.AddSegmentError(segmentName, X12ErrorCode.UnrecognizedSegmentIDCode , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), SegmentNumber , this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error); DocumentFragment newFragment = new DocumentFragment() { Pluglet = unknown, Children = new List <IDocumentFragment>(), }; IPluglet childPluglet = new Pluglet("Data", "Data", PlugletType.Data, null); DocumentFragment child = new DocumentFragment() { Parent = newFragment, Pluglet = childPluglet, Children = null, SequenceNumber = SegmentNumber, StartOffset = this.CurrentSegmentStartPos, EndOffset = this.CurrentSegmentEndPos - 1, }; newFragment.Children.Add(child); child.Value = CurrentSegment; if (newFragment == null) { errorMsgs = string.Format("{0} DocumentFragment creation failed. Errors: {1}", segmentName, errorMsgs); Logger.Error(location, EventId.EDIReaderDocFragmentCreation, "{0} - {1}", GetCurrentPosContext(), errorMsgs); //TODO: what should be the code here? //Errors.AddGenericError(segmentName, X12ErrorCode.??? } else { ((DocumentFragment)FatpipeDocumentInst.RootFragment).AddDocumentFragment(newFragment); // CurrentPluglet = newFragment.Pluglet; } //experimenting with unknown here } else { if (nextPluglet.RepetitionInfo.MaxOccurs == 0) { Errors.AddSegmentError(segmentName, X12ErrorCode.UnexpectedSegmentCode , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnexpectedSegmentCode), nextPluglet.Tag) , SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error); } else { DocumentFragment newFragment = nextPluglet.ConstructDocumentFragment(segmentDetails, false, EDIDelimiters, SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, ref errors, out errorMsgs); if (newFragment == null) { //errorMsgs = string.Format("{0} DocumentFragment creation failed. Errors: {1}", segmentName, errorMsgs); Logger.Error(location, EventId.EDIReaderDocFragmentCreation, "{0} - {1}", GetCurrentPosContext(), errorMsgs); // TODO: Replace UnexpectedSegmentCode with appropriate one Errors.AddGenericError(segmentName, X12ErrorCode.UnexpectedSegmentCode, errorMsgs, SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos); } else { ((DocumentFragment)FatpipeDocumentInst.RootFragment).AddDocumentFragment(newFragment); CurrentPluglet = newFragment.Pluglet; } } } if (!string.IsNullOrEmpty(errorMsgs)) { if (FatpipeDocumentInst.Errors == null) { FatpipeDocumentInst.Errors = new List <string>(); } FatpipeDocumentInst.Errors.Add(errorMsgs); } }
// Return value indicate if ST segment is valid or not private bool ProcessSTSegment() { string location = "EDIReader.ProcessSTSegment"; string errors = string.Empty; Stopwatch sw = new Stopwatch(); sw.Start(); LastState = EDIState.ST; int currentTransactionSetType; if (CurrentSegmentDetails == null || CurrentSegmentDetails.Length < 2 || int.TryParse(CurrentSegmentDetails[1], out currentTransactionSetType) == false) { InvalidTransactionSetCount++; //TODO: Add error Logger.Error(location, EventId.EDIReaderInvalidSegment, "{0} - Invalid segment - {1}", GetCurrentPosContext(), CurrentSegment); Errors.AddSegmentError(CurrentSegment, X12ErrorCode.UnexpectedSegmentCode , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnexpectedSegmentCode), SegmentNumber , this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error); } else { ValidTransactionSetCount++; // TODO: Optimization - Load DocumentPlug, reconstruct ISA and GA segment if transaction set type changed //if (PrevTransactionSetType != currentTransactionSetType) { // Make sure that ISA and GA fields are already present if (ISARecordFields == null || GSRecordFields == null) { throw new EDIReaderException( string.Format("ISA and GA segments should be present before ST segment. {0}", GetCurrentPosContext())); } if (ISARecordFields.Length != MaxISAFieldRecordCount || GSRecordFields.Length == 0) { throw new EDIReaderException( string.Format("ISA and GA segments length ({0}, {1}) does not match expected length ({2}, non-zero). {3}", ISARecordFields.Length, GSRecordFields.Length, MaxISAFieldRecordCount, GetCurrentPosContext())); } //TODO: For testing invoking DocumentPlugFactory.CreateEDIDocumentPlug if (DocumentPlug == null) { if (FPManager == null) { DocumentPlug = DocumentPlugFactory.CreateEDIDocumentPlug(currentTransactionSetType); } else { DocumentPlug = CreateEDIDocumentPlug(currentTransactionSetType, ISARecordFields); } } else // Make sure that DocumentPlug and ST document type match { // DocumentPlug.DocumentType = 0 indicates that there was problem retrieving DocumentType // while constructing DocumentPlug if (DocumentPlug.DocumentType != 0 && DocumentPlug.DocumentType != currentTransactionSetType) { string errorDescription = "Spec Cert relates to document {0}, however ST01 value is {1}.; test File is rejected"; errorDescription = string.Format(errorDescription, DocumentPlug.DocumentType, currentTransactionSetType); FieldError fieldError = DataTypeHelper.GenerateFieldError(X12ErrorCode.DeInvalidCodeValueCode, errorDescription, CurrentSegmentDetails[0]); long currentSegmentFieldStartIndex = this.CurrentSegmentStartPos + 3; // length of "ST<delimiter>" long currentSegmentFieldEndIndex = currentSegmentFieldStartIndex + CurrentSegmentDetails[1].Length - 1; Logger.Error(location, EventId.EDIReaderInvalidTransactionSetType, errorDescription); Errors.AddFieldError(CurrentSegmentDetails[0], "ST01", fieldError.ErrorCode, fieldError.Description, SegmentNumber, 1, CurrentSegmentDetails[1], currentSegmentFieldStartIndex, currentSegmentFieldEndIndex, EdiErrorType.Error); return(false); } } CurrentPluglet = DocumentPlug.RootPluglet; CurrentPluglet.ResetCurrentOccurances(); // Construct start segment list CurrentPluglet.InitializeStartSegmentList(); FatpipeDocumentInst.TransactionSetType = currentTransactionSetType; if (CurrentSegmentDetails.Length > 2) { FatpipeDocumentInst.TransactionNumber = CurrentSegmentDetails[2]; } FatpipeDocumentInst.DocumentPlug = DocumentPlug; FatpipeDocumentInst.RootFragment = CurrentPluglet.ConstructDocumentFragment(null, null); // Construct ISA node //CreateAndAddNewSegment(EDIState.ISA.ToString(), ISARecordFields); // Construct GS node //CreateAndAddNewSegment(EDIState.GS.ToString(), GSRecordFields); //GSSegmentProcessed = true; //GSPluglet = CurrentPluglet; PrevTransactionSetType = currentTransactionSetType; } //else //{ // // Move to GS node to start new segment // CurrentPluglet = GSPluglet; // // Remove previous TransactionSet // if (FatpipeDocumentInst.RootFragment.Children != null) // { // IDocumentFragment transactionSetChild = FatpipeDocumentInst.RootFragment.Children.Any( c => c.Pluglet.Tag == "TransactionSet"); // FatpipeDocumentInst.RootFragment.Children.Remove(transactionSetChild); // } // // Set errors to null // FatpipeDocumentInst.Errors = null; //} // Construct ST node CreateAndAddNewSegment(EDIState.ST.ToString(), CurrentSegmentDetails); } sw.Stop(); Logger.Debug(location, "Stop - {0}. Elapsed time {1} ms", GetCurrentPosContext(), sw.ElapsedMilliseconds); return(true); }