Ejemplo n.º 1
0
        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);
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
0
        private void ValidateContingencies()
        {
            // Assumption: If id data segment is not present then this function will not report error
            // as we must have already reported that data segment as missing segment earlier
            Dictionary <string, List <IDocumentFragment> > contingencyOccurances = new Dictionary <string, List <IDocumentFragment> >();

            ReadSegmentsWithIdDataTypeChildrens(contingencyOccurances, FatpipeDocumentInst.RootFragment);

            foreach (string path in contingencyOccurances.Keys)
            {
                // Select pluglet for current path
                // Selecting pluglet from the 1st documentFragment as pluglet will be
                // same for all documentFragments with same path
                IDocumentFragment documentFragment = contingencyOccurances[path][0];
                IPluglet          pluglet          = documentFragment.Pluglet;

                // Pluglet will point to segment, process all child with data type as X12_IdDataType
                // Filter out non-mandatory data type pluglets
                foreach (Pluglet child in pluglet.Children)
                {
                    if (child.PlugletType == PlugletType.Data && child.DataType is X12_IdDataType && child.IsMandatory == true)
                    {
                        List <string> presentValues = GetAllPresentValues(contingencyOccurances[path], child);

                        X12_IdDataType dataType = child.DataType as X12_IdDataType;
                        foreach (string allowedValue in dataType.AllowedValues.Keys)
                        {
                            Contingency contingencies = dataType.GetContingencies(allowedValue);

                            // TODO: Use Ignore flag at id value level

                            // If Id value does not have any contingency then segment with that value must exist
                            if (contingencies == null || contingencies.ContingencyValues.Count == 0)
                            {
                                if (presentValues.Contains(allowedValue) == false && dataType.IsOptionalValue(allowedValue) == false)
                                {
                                    Errors.AddSegmentError(pluglet.Tag, X12ErrorCode.DeMandatoryIdValueMissingCode
                                                           , string.Format("{0} : {1}", X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeMandatoryIdValueMissingCode), allowedValue)
                                                           , documentFragment.SequenceNumber, documentFragment.StartOffset, documentFragment.EndOffset, EdiErrorType.Error);
                                }
                            }
                            // If Id value has contingencies of type Enumeration then segment with that value or any contingency value must exist
                            else if (contingencies.Type == ContingencyType.Enumeration)
                            {
                                bool valuePresent = presentValues.Contains(allowedValue);
                                if (valuePresent == false)
                                {
                                    foreach (string alternateValue in contingencies.ContingencyValues)
                                    {
                                        valuePresent = presentValues.Contains(alternateValue);
                                        if (valuePresent)
                                        {
                                            break;
                                        }
                                    }
                                }

                                if (valuePresent == false)
                                {
                                    Errors.AddSegmentError(pluglet.Tag, X12ErrorCode.DeMandatoryIdValueOrAlternativeValueMissingCode
                                                           , string.Format("{0} : {1}", X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeMandatoryIdValueOrAlternativeValueMissingCode), allowedValue)
                                                           , documentFragment.SequenceNumber, documentFragment.StartOffset, documentFragment.EndOffset, EdiErrorType.Error);
                                }
                            }
                            // If contingency type is cross segment then either both values must exist or both values missing
                            else if (contingencies.Type == ContingencyType.CrossSegment)
                            {
                                // TODO: handle all values in contingencies.ContingencyValues
                                string xPath = contingencies.ContingencyValues[0];
                                bool   currentValuePresent      = presentValues.Contains(allowedValue);
                                bool   crossSegmentValuePresent = IsCrossSegmentValuePresent(contingencyOccurances, xPath, pluglet.PathSeperator);

                                if (currentValuePresent != crossSegmentValuePresent)
                                {
                                    Errors.AddSegmentError(pluglet.Tag, X12ErrorCode.DeCrossSegmentIdValueOccurancesDoesNotMatch
                                                           , string.Format("{0} : {1} {2}", X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeCrossSegmentIdValueOccurancesDoesNotMatch), allowedValue, xPath)
                                                           , documentFragment.SequenceNumber, documentFragment.StartOffset, documentFragment.EndOffset, EdiErrorType.Error);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
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);
        }