Example #1
0
        /// <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);
            }
        }
Example #2
0
        private void ProcessSTSegment()
        {
            string location = "EDIReader.ProcessSTSegment";
            string errors   = string.Empty;

            Logger.Info(location, "Start - {0}", GetCurrentPosContext());
            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, "{0} - Invalid segment - {1}", GetCurrentPosContext(), CurrentSegment);
            }
            else
            {
                // 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). {4}",
                                                ISARecordFields.Length, GSRecordFields.Length, MaxISAFieldRecordCount, GetCurrentPosContext()));
                    }

                    //TODO: For testing invoking DocumentPlugFactory.CreateEDIDocumentPlug
                    if (FPManager == null)
                    {
                        DocumentPlug = DocumentPlugFactory.CreateEDIDocumentPlug(currentTransactionSetType, ISARecordFields);
                    }
                    else
                    {
                        DocumentPlug = CreateEDIDocumentPlug(currentTransactionSetType, ISARecordFields);
                    }

                    CurrentPluglet = DocumentPlug.RootPluglet;

                    // Construct start segment list
                    CurrentPluglet.InitializeStartSegmentList();

                    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.Info(location, "Stop - {0}. Elapsed time {1} ms", GetCurrentPosContext(), sw.ElapsedMilliseconds);
        }
Example #3
0
        // 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);
        }
        /// <summary>
        /// Return flat file input and construct IFatpipeDocument
        /// IFatpipeDocument will NOT contain ISA and GA segments as it's not
        /// present in case of flat file.
        /// Since ISA segment is missing and there is no speific ST segment
        /// DocumentPlug is mandatory parameter.
        /// </summary>
        /// <returns></returns>
        public IFatpipeDocument ReadFile(Stream flatFileStream, IDocumentPlug documentPlug)
        {
            if (flatFileStream == null)
            {
                throw new ArgumentNullException("flatFileStream", "Flat file stream cannot be null");
            }

            if (documentPlug == null)
            {
                throw new ArgumentNullException("documentPlug", "Document plug cannot be null");
            }

            string location = "FlatFileReader.ReadFile";

            Logger.Debug(location, "Start");

            Stopwatch sw = new Stopwatch();

            sw.Start();

            errors       = new InterchangeErrors();
            DocumentPlug = documentPlug;

            long orgStartPos = flatFileStream.Position;

            FlatFileDelimiters        = InitializeDelimiters(documentPlug);
            SegmentDelimiter          = ((char)FlatFileDelimiters.SegmentDelimiter).ToString();
            FormattedSegmentDelimiter = SegmentDelimiter;

            bool crLFPresent = FlatFileDelimiters.SegmentDelimiter == Delimiters.CarriageReturn || FlatFileDelimiters.SegmentDelimiterSuffix1 == Delimiters.CarriageReturn;

            if (!crLFPresent)
            {
                FormattedSegmentDelimiter = string.Format("{0}{1}", FormattedSegmentDelimiter, Environment.NewLine);
            }

            SegmentNumberFromStart = 0;
            CurrentSegmentStartPos = 0;

            this.DocumentReader = new StreamReader(flatFileStream, Encoding.UTF8);

            // Since flat file doesn't have concept of ST/SE, ans we want to use InterchangeErrors for reporting purpose
            // create dummy transaction set details
            Errors.AddTransactionSetDetails(1, "", "", true);

            CurrentPluglet = DocumentPlug.RootPluglet;
            CurrentPluglet.ResetCurrentOccurances(); // do we need this for flat files?
            CurrentPluglet.InitializeStartSegmentList();

            FatpipeDocumentInst = new FatpipeDocument();
            //FatpipeDocumentInst.TransactionSetType = ???;
            FatpipeDocumentInst.DocumentPlug = DocumentPlug;
            FatpipeDocumentInst.RootFragment = CurrentPluglet.ConstructDocumentFragment(null, null);

            while ((CurrentSegmentDetails = ReadNextSegment()) != null &&
                   CurrentSegmentDetails.Length > 0)
            {
                Logger.Debug(location, "{0} - Next segment {1}", GetCurrentPosContext(), CurrentSegmentDetails[0]);

                CreateAndAddNewSegment(CurrentSegmentDetails[0], CurrentSegmentDetails);

                if (string.IsNullOrWhiteSpace(FatpipeDocumentInst.OriginalPayload))
                {
                    FatpipeDocumentInst.OriginalPayload = CurrentSegment;
                }
                else
                {
                    FatpipeDocumentInst.OriginalPayload += SegmentDelimiter + CurrentSegment;
                }

                if (string.IsNullOrWhiteSpace(FatpipeDocumentInst.BeautifiedOriginalPayloadBody))
                {
                    FatpipeDocumentInst.BeautifiedOriginalPayloadBody = CurrentSegment;
                }
                else
                {
                    FatpipeDocumentInst.BeautifiedOriginalPayloadBody += FormattedSegmentDelimiter + CurrentSegment;
                }
            }

            sw.Stop();
            Logger.Debug(location, "Stop - Elapsed time {0} ms", sw.ElapsedMilliseconds);

            return(FatpipeDocumentInst);
        }