/// <summary> /// Construct EDI representation of document (current transaction set /// along with header segments) /// </summary> /// <param name="ediDelimiters"></param> /// <returns></returns> public string ToEDI(Delimiters ediDelimiters) { ILogger logger = LoggerFactory.Logger; string ediDocument = RootFragment.ToEDI(ediDelimiters, false); return(ediDocument); }
/// <summary> /// Construct EDI representation of this fragment /// </summary> /// <param name="ediDelimiters"></param> /// <param name="internalSegment"></param> /// <returns></returns> public string ToEDI(Delimiters ediDelimiters, bool internalSegment) { if (Children == null) { return(string.Empty); } StringBuilder segment = new StringBuilder(); string componentDelimiter = ((char)ediDelimiters.ComponentSeperator).ToString(); string fieldDelimiter = ((char)ediDelimiters.FieldSeperator).ToString(); string delimiter = internalSegment == true ? componentDelimiter : fieldDelimiter; // construct segment only for parent with at least 1 leaf node if (Children.Any(c => c.Pluglet.PlugletType == PlugletType.Data)) { if (internalSegment == false) { segment.AppendFormat("{0}", Pluglet.Tag); } foreach (IDocumentFragment child in Children) { if (child.Pluglet.PlugletType == PlugletType.Data) { if (segment.Length != 0 || internalSegment == false) { segment.AppendFormat("{0}{1}", delimiter, child.Value); } else { segment.AppendFormat("{0}", child.Value); } } else { segment.AppendFormat("{0}{1}", fieldDelimiter, child.ToEDI(ediDelimiters, true)); } } } else { string childSegment; StringBuilder segmentB = new StringBuilder(3); segmentB.Append((char)ediDelimiters.SegmentDelimiter); if (ediDelimiters.SegmentDelimiterSuffix1 != -1) { segmentB.Append((char)ediDelimiters.SegmentDelimiterSuffix1); } if (ediDelimiters.SegmentDelimiterSuffix2 != -1) { segmentB.Append((char)ediDelimiters.SegmentDelimiterSuffix2); } string segmentDelimiter = segmentB.ToString(); foreach (IDocumentFragment child in Children) { childSegment = child.ToEDI(ediDelimiters, false); segment.AppendFormat("{0}{1}" , string.IsNullOrEmpty(segment.ToString()) ? string.Empty : segmentDelimiter , childSegment); } IDocumentFragment firstChild = Children[0]; // Special case for ading SE/GE/IEA segments switch (firstChild.Pluglet.Tag) { case "ST": string txnSetNumber = ""; int segmentCount = 0; if (firstChild.Children != null && firstChild.Children.Count > 1) { txnSetNumber = firstChild.Children[1].Value; } // Set segmentCount to child count of X12_00401_850 segmentCount = this.CountAllChilds() + 1; // +1 for SE segment //segment.AppendFormat("{0}SE{1}{2}{3}{4}", segmentDelimiter, fieldDelimiter, segmentCount, fieldDelimiter, txnSetNumber); //segment.AppendFormat("{0}GE{1}1{2}1", segmentDelimiter, fieldDelimiter, fieldDelimiter); //segment.AppendFormat("{0}IEA{1}1{2}{3}", segmentDelimiter, fieldDelimiter, fieldDelimiter, "NNNN"); break; } } return(segment.ToString()); }
/// <summary> /// Construct DocumentFragment for leaf node parent and then create and attach leaf nodes to it. /// </summary> /// <param name="pluglet"></param> /// <param name="segmentDetails"></param> /// <param name="internalSegment"></param> /// <param name="ediDelimiters"></param> /// <param name="segmentStartIndex"></param> /// <param name="segmentEndIndex"></param> /// <param name="ediErrors"></param> /// <param name="error"></param> /// <returns></returns> public static DocumentFragment ConstructDocumentFragment(this IPluglet pluglet, string[] segmentDetails, bool internalSegment, Delimiters ediDelimiters, int segmentSeqNumber, long segmentStartIndex, long segmentEndIndex, ref InterchangeErrors ediErrors, out string error) { if (pluglet == null) { throw new ArgumentNullException("pluglet"); } if (segmentDetails == null) { throw new ArgumentNullException("segmentDetails"); } LoggerFactory.Logger.Info("PlugletExtensions.ConstructDocumentFragment", "Constructing {0} instance", pluglet.Tag); if (pluglet.Children == null) { error = string.Format("Pluglet {0} does not have childrens", pluglet.Name); return(null); } // -1 is required since SegmentDetails[0] is the SegmentName if (pluglet.Children.Count < segmentDetails.Length - 1) { error = string.Format("Document has {1} data elements, it is less than segment children count {2} as described in Spec", pluglet.Name, pluglet.Children.Count, segmentDetails.Length); return(null); } error = string.Empty; ++pluglet.CurrentOccurrences; DocumentFragment documentFragment = new DocumentFragment() { Pluglet = pluglet, Children = new List <IDocumentFragment>(), SequenceNumber = segmentSeqNumber, StartOffset = segmentStartIndex, EndOffset = segmentEndIndex, }; int plugletNum = 0; DocumentFragment dataFragment; IPluglet plugletChild; bool validateValue; long currentSegmentFieldStartIndex = segmentStartIndex; //SegmentNum start from 1 since SegmentDetails[0] is Segment name int segmentNum = 1; // if this is internal segment (composite segment - segment handing data and segment as children) then // start segmentDetails from 0 if (internalSegment == true) { segmentNum = 0; } EdiErrorType errorType = pluglet.IsIgnore ? EdiErrorType.Warning : EdiErrorType.Error; for (; segmentNum < segmentDetails.Length; segmentNum++, plugletNum++) { if (segmentNum != 0) { currentSegmentFieldStartIndex += segmentDetails[segmentNum - 1].Length + 1; } validateValue = false; plugletChild = pluglet.Children[plugletNum]; if (plugletChild.PlugletType == PlugletType.Data) { dataFragment = new DocumentFragment() { Parent = documentFragment, Pluglet = plugletChild, Value = segmentDetails[segmentNum], /*SequenceNumber = segmentSeqNumber, * StartOffset = currentSegmentFieldStartIndex, * EndOffset = currentSegmentFieldStartIndex + segmentDetails[segmentNum].Length,*/ }; validateValue = true; } else if (plugletChild.PlugletType == PlugletType.Segment) { if (string.IsNullOrEmpty(segmentDetails[segmentNum]) == false) { string segmentError = string.Empty; string [] internalSegmentDetails = segmentDetails[segmentNum].Split((char)ediDelimiters.ComponentSeperator); dataFragment = plugletChild.ConstructDocumentFragment(internalSegmentDetails, true, ediDelimiters, segmentSeqNumber, currentSegmentFieldStartIndex, currentSegmentFieldStartIndex + segmentDetails[segmentNum].Length, ref ediErrors, out segmentError); if (string.IsNullOrEmpty(segmentError) == false) { if (string.IsNullOrEmpty(error) == true) { error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name); } error = string.Format("{0} Error constructing {1}: {2}", error, plugletChild.Name, segmentError); } } else { dataFragment = new DocumentFragment() { Parent = documentFragment, Pluglet = plugletChild, Value = segmentDetails[segmentNum], }; } } else { error = string.Format("ConstructDocumentSegmentInstance: Error constructing SegmentInstance. Pluglet {0} is of type {1}", pluglet.Name, plugletChild.Name); return(null); } if (validateValue == true && plugletChild.DataType != null && string.IsNullOrEmpty(segmentDetails[segmentNum]) == false) { FieldError fieldError = plugletChild.DataType.ValidateValue(new StringBuilder(segmentDetails[segmentNum])); if (fieldError != null) { if (string.IsNullOrEmpty(error) == true) { error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name); } error = string.Format("{0} Error data validation failed {1}: {2} ({3})", error, plugletChild.Name, fieldError.Description, fieldError.DataValue); ediErrors.AddFieldError(segmentDetails[0], plugletChild.Tag, fieldError.ErrorCode, fieldError.Description, segmentSeqNumber, segmentNum, segmentDetails[segmentNum], currentSegmentFieldStartIndex, currentSegmentFieldStartIndex + segmentDetails[segmentNum].Length - 1, errorType); } } //TODO: Add validation (extension method) documentFragment.Children.Add(dataFragment); if (string.IsNullOrEmpty(segmentDetails[segmentNum]) && plugletChild.IsMandatory == true) { if (string.IsNullOrEmpty(error) == true) { error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name); } error = string.Format("{0} Child {1} is mandatory but missing", error, plugletChild.Name); ediErrors.AddFieldError(segmentDetails[0], plugletChild.Tag, X12ErrorCode.DeMandatoryDataElementMissingCode, X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeMandatoryDataElementMissingCode), segmentSeqNumber, segmentNum, string.Empty, currentSegmentFieldStartIndex, currentSegmentFieldStartIndex, errorType); } } for (; segmentNum <= pluglet.Children.Count; segmentNum++, plugletNum++) { plugletChild = pluglet.Children[plugletNum]; if (plugletChild.IsMandatory == true) { if (string.IsNullOrEmpty(error) == true) { error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name); } error = string.Format("{0} Child {1} is mandatory but missing", error, plugletChild.Name); ediErrors.AddFieldError(segmentDetails[0], plugletChild.Tag, X12ErrorCode.DeMandatoryDataElementMissingCode, X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeMandatoryDataElementMissingCode), segmentSeqNumber, segmentNum, string.Empty, currentSegmentFieldStartIndex, currentSegmentFieldStartIndex, errorType); } } return(documentFragment); }