예제 #1
0
        /// <summary>
        /// THis is to split the HL loops appropriately
        /// </summary>
        /// <param name="edi"></param>
        /// <param name="loopID"></param>
        /// <param name="position"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static List <String> LoopSplit(this string edi, EDILoop loopInfo, EDIDelim seperator)
        {
            string[]      segments = edi.Split(seperator.Segment);
            bool          inLoop   = false;
            List <string> loops    = new List <string>();
            List <string> tmp      = new List <string>();

            foreach (string segment in segments)
            {
                if (segment.StartsWith(loopInfo.GetFormat()))
                {
                    string[] elements = segment.Split(seperator.Element);
                    if (elements[loopInfo.GetPosition()].Equals(loopInfo.GetSelectionValue()))
                    {
                        if (tmp.Count > 0)
                        {
                            loops.Add(String.Join("" + seperator.Segment, tmp));
                            tmp.Clear();
                        }
                        inLoop = true;
                    }
                }
                if (inLoop)
                {
                    tmp.Add(segment);
                }
            }
            if (tmp.Count > 0)
            {
                loops.Add(String.Join("" + seperator.Segment, tmp));
            }
            return(loops);
        }
예제 #2
0
        /// <summary>
        /// This is the default write method.
        /// In Case of the EBSegment it needs to overwrite this
        /// </summary>
        /// <returns></returns>
        internal string ToEDIString(EDIDelim seperators)
        {
            StringBuilder rtnVal = new StringBuilder(_segmentID + seperators.Element);

            foreach (PropertyInfo propertyInfo in GetType().GetProperties())
            {
                if (propertyInfo.CanRead)
                {
                    //Attribute[] attrs = Attribute.GetCustomAttributes(propertyInfo);
                    //Custom types need to be done outside.
                    object propertyValue = propertyInfo.GetValue(this, null);
                    if (propertyValue != null)
                    {
                        if (propertyInfo.PropertyType.BaseType == typeof(CompositeBase))
                        {
                            //Grab the function we are going to use
                            MethodInfo method = propertyValue.GetType().GetMethod("ToEDIString", internalFlags);
                            //Invoke the function of that class on the class
                            rtnVal.Append(method.Invoke(propertyValue, new object[] { seperators.Subelement }).ToString());
                        }
                        else
                        {
                            //TODO: Implement a custome ConveterType here.
                            //Location to add the TypecOnverter... allows for input of one from outside
                            rtnVal.Append(propertyInfo.EDI2String(propertyValue));
                        }
                    }
                    rtnVal.Append(seperators.Element);
                }
            }


            return(rtnVal.ToString().TrimEnd(seperators.Element));
        }
예제 #3
0
        /// <summary>
        /// Call this with about the first 175 characters.  ISA contains 106 so the extra is just safety.
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>

        public static EDIDelim GetFileDelimiters(this string original)
        {
            EDIDelim rtnVal = new EDIDelim();

            rtnVal.Element    = original[3];
            rtnVal.Segment    = original[105];
            rtnVal.Subelement = original[104];
            rtnVal.Repitition = original[82];
            return(rtnVal);
        }
예제 #4
0
        /// <summary>
        /// THis is the raw generic you should use from your programs
        /// </summary>
        /// <param name="ediFile"></param>
        public void FromEDIFile(string ediFile, bool createAck = false)
        {
            //get the seperators
            //then call the from EDI string....
            EDIDelim currDelim = ediFile.SafeSubstring(0, 175).GetFileDelimiters();

            originalDelims = currDelim;
            try
            {
                FromEDIString(ediFile, currDelim);
            }
            catch (Exception)
            {
                //Do something for the Ack
                throw;
            }
            if (createAck)
            {
                CreateAcknowledgement(ediFile);
            }
        }
예제 #5
0
        /// <summary>
        /// Expectation is that a single ISA-IEA come to this function
        /// </summary>
        /// <param name="ediFile"></param>
        /// <returns></returns>
        public static List <String> SplitByGS(string ediFile)
        {
            EDIDelim      currDelim = ediFile.SafeSubstring(0, 175).GetFileDelimiters();
            List <string> rtnVal    = new List <string>();

            string[]      strSegments = ediFile.Split(new char[] { currDelim.Segment }, StringSplitOptions.RemoveEmptyEntries);
            List <String> holder      = new List <string>();

            int[] pntrs   = strSegments.FindAllIndexOf(a => a.StartsWith("GS"));
            int[] gePntrs = strSegments.FindAllIndexOf(a => a.StartsWith("GE"));

            for (int p = 0; p < pntrs.Length; p++)
            {
                holder.Add(strSegments[0]);
                holder.AddRange(strSegments.GetRange(pntrs[p], gePntrs[p]));
                holder.Add(strSegments[strSegments.Count() - 1]);
                rtnVal.Add(String.Join(("" + currDelim.Segment), holder) + currDelim.Segment);
                holder.Clear();
            }
            return(rtnVal);
        }
예제 #6
0
        //TODO: Determine how to pass delimiters easily.
        internal string ToEDIString(EDIDelim seperators)
        {
            //Always set these values so that we ensure file is consistent.
            SetISADelimiters(seperators.Repitition, seperators.Subelement);
            List <string> strSegments = new List <string>();

            foreach (PropertyInfo propertyInfo in GetType().GetProperties())
            {
                if (propertyInfo.CanRead)
                {
                    //Foreach loop add since it is a list the "FromEDIString"
                    object propertyValue = propertyInfo.GetValue(this, null);

                    if (propertyValue != null)
                    {
                        if (IsPropertyACollection(propertyInfo))
                        {
                            //loop through it.
                            var collection = (IEnumerable)propertyInfo.GetValue(this, null);
                            foreach (var item in collection)
                            {
                                MethodInfo method = item.GetType().GetMethod("ToEDIString", internalFlags);
                                //Invoke the function of that class on the class
                                strSegments.Add(method.Invoke(item, new object[] { seperators }).ToString());
                            }
                        }
                        else
                        {
                            //Grab the function we are going to use
                            MethodInfo method = propertyValue.GetType().GetMethod("ToEDIString", internalFlags);
                            //Invoke the function of that class on the class
                            strSegments.Add(method.Invoke(propertyValue, new object[] { seperators }).ToString());
                        }
                    }
                }
            }

            return(String.Join(("" + seperators.Segment), strSegments));
        }
예제 #7
0
        /// <summary>
        /// THis is the recursive function that is called.
        /// </summary>
        /// <param name="ediData"></param>
        /// <param name="seperators"></param>
        internal void FromEDIString(string ediData, EDIDelim seperators)
        {
            string[] strSegments = ediData.Split(new char[] { seperators.Segment }, StringSplitOptions.RemoveEmptyEntries);

            //Hopefully allows us to determine if the segment even belongs in the current object.
            List <string> objSegments = GetAvailableSegments();

            int p = 0;

            //TODO: How do we align the inbound to the object...

            for (int objPntr = 0; objPntr < GetType().GetProperties().Length; objPntr++)
            {
                PropertyInfo propertyInfo = GetType().GetProperties()[objPntr];
                if (propertyInfo.CanRead)
                {
                    Attribute[] attrs     = Attribute.GetCustomAttributes(propertyInfo);
                    bool        IsGeneric = false;
                    if (attrs.Any(x => x.GetType() == typeof(EDILoop)))
                    {
                        EDILoop currentLoop = ((EDILoop)attrs.FirstOrDefault(z => z.GetType() == typeof(EDILoop)));

                        currentLoop.AdjustFormat(seperators.Element);
                        //Check to see if the segment starts this way...
                        //string segStart = currentLoop.GetFormat() + seperators.Element;

                        if (strSegments[p].StartsWith(currentLoop.GetFormat()))
                        {
                            //This should be the amount of Segments we need to group together in order to split properly.
                            int es = strSegments.Count() - p - currentLoop.GetEndSkip();
                            //we know that the current loop is at least one we want...
                            //es cannot be less than 1
                            if (es == 0)
                            {
                                es = 1;
                            }
                            //TODO: Multiple altsegment ending ID's how to handle here...
                            if (currentLoop.GetAltSegmentID().Any())
                            {
                                for (int i = p + 1; i < strSegments.Count(); i++)
                                {
                                    //if (strSegments[i].StartsWith(currentLoop.GetAltSegmentID()))
                                    if (
                                        currentLoop.GetAltSegmentID()
                                        .Any(alt => strSegments[i].StartsWith(alt + seperators.Element)))
                                    {
                                        es = i - p;
                                        break;
                                    }
                                }
                            }

                            //We need to determine the end point of the alt ending if present.
                            List <string> loopValues =
                                String.Join("" + seperators.Segment, strSegments, p, es)
                                .TransactionSplit(currentLoop, seperators);

                            //Foreach loop add since it is a list the "FromEDIString"
                            object propertyValue = propertyInfo.GetValue(this, null);
                            //This should always do the later but for testing have it here...
                            if (propertyValue == null)
                            {
                                //How do we put this as the property value
                                ConstructorInfo ctor     = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes);
                                object          instance = ctor.Invoke(null);

                                propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType),
                                                      null);
                                propertyValue = propertyInfo.GetValue(this, null);
                            }
                            if (IsPropertyACollection(propertyInfo))
                            {
                                MethodInfo Addmethod = propertyValue.GetType().GetMethod("Add");
                                Type       t         = propertyValue.GetType().GetGenericArguments()[0];
                                //EDIBase call
                                MethodInfo ediMethod = t.GetMethod("FromEDIString", internalFlags);

                                foreach (string lValues in loopValues)
                                {
                                    var tmp = t.GetConstructor(new Type[] {}).Invoke(new object[] {});
                                    //Invoke the EDI string parser
                                    ediMethod.Invoke(tmp, new object[] { lValues, seperators });
                                    //Add the new item to the list.
                                    Addmethod.Invoke(propertyValue, new object[] { tmp });
                                }
                            }
                            else
                            {
                                //This should only be called once... but we shall see...
                                foreach (string lValues in loopValues)
                                {
                                    MethodInfo ediMethod = propertyValue.GetType()
                                                           .GetMethod("FromEDIString", internalFlags);
                                    ediMethod.Invoke(propertyValue, new object[] { lValues, seperators });
                                }
                            }
                            //p = strSegments.Count() - currentLoop.GetEndSkip();
                            p = p + es;
                        }
                        else
                        {
                            //If EDI file we are reading has an extra segment that is not part of the object
                            //then we need to skip it and go on to the next one, while keeping our place
                            //in the current file to properly unmarshal the rest of the file
                            if (!IsValidSegment(strSegments[p], objSegments, objPntr))
                            {
                                p++;
                                objPntr--;
                            }
                        }
                    }
                    else
                    {
                        //Handle single and list of simple segments.
                        string segmentID = propertyInfo.PropertyType.Name.Replace("Seg", "");
                        if (segmentID.ToUpper().StartsWith("LIST"))
                        {
                            segmentID = propertyInfo.PropertyType.GetGenericArguments()[0].Name.Replace("Seg", "");

                            if (propertyInfo.PropertyType.GetGenericArguments()[0].Name.StartsWith("Generic"))
                            {
                                IsGeneric = true;
                            }
                        }
                        if (p > strSegments.Count() - 1)
                        {
                            break;
                        }

                        if (strSegments[p].StartsWith(segmentID) || IsGeneric)
                        {
                            //Actually Grab the class of what we are trying to do
                            object propertyValue = propertyInfo.GetValue(this, null);
                            if (propertyValue == null)
                            {
                                //How do we put this as the property value
                                ConstructorInfo ctor     = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes);
                                object          instance = ctor.Invoke(null);

                                propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType),
                                                      null);
                                propertyValue = propertyInfo.GetValue(this, null);
                            }
                            //Collection of single objects
                            if (IsPropertyACollection(propertyInfo))
                            {
                                //This is the list of objects and function for the adding

                                MethodInfo Addmethod = propertyValue.GetType().GetMethod("Add");

                                //THis is the type of object and the method we need plus the segment ID
                                Type       t         = propertyValue.GetType().GetGenericArguments()[0];
                                MethodInfo ediMethod = t.GetMethod("FromEDIString", internalFlags);
                                string     segID     = t.Name.Replace("Seg", "");

                                //Start looping through the segments
                                while (strSegments[p].StartsWith(segID) || IsGeneric)
                                {
                                    //Create an instance of the list object
                                    var tmp = t.GetConstructor(new Type[] {}).Invoke(new object[] {});
                                    //Invoke the EDI string parser
                                    ediMethod.Invoke(tmp, new object[] { strSegments[p], seperators });
                                    //Add the new item to the list.
                                    Addmethod.Invoke(propertyValue, new object[] { tmp });
                                    p++;
                                    if ((p >= strSegments.Count()) || (IsGeneric && (p >= strSegments.Count() - 1)))
                                    {
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                //This didn't work so good....  but we are not loop through the segments of the base type..
                                if (propertyValue.GetType().BaseType == typeof(EDIBase))
                                {
                                    string inputValue = String.Join("" + seperators.Segment, strSegments, p,
                                                                    strSegments.Count() - 1);
                                    MethodInfo ediMethod = propertyValue.GetType()
                                                           .GetMethod("FromEDIString", internalFlags);
                                    //This should always do the later but for testing have it here...
                                    ediMethod.Invoke(propertyValue, new object[] { inputValue, seperators });
                                    p = (strSegments.Count() - 1);
                                }
                                else
                                {
                                    //Grab the function we are going to use
                                    //                        Type[] paramTypes = _countMethodParams.Select(p => p.GetType()).ToArray();
                                    MethodInfo method = propertyValue.GetType()
                                                        .GetMethod("FromEDIString", internalFlags);
                                    //Invoke the function of that class on the class
                                    //strSegments.Add(method.Invoke(propertyValue, new object[] { '*' }).ToString());
                                    method.Invoke(propertyValue, new object[] { strSegments[p], seperators });
                                    p++;
                                }
                            }
                        }
                        else
                        {
                            //If EDI file we are reading has an extra segment that is not part of the object
                            //then we need to skip it and go on to the next one, while keeping our place
                            //in the current file to properly unmarshal the rest of the file
                            if (!IsValidSegment(strSegments[p], objSegments, objPntr))
                            {
                                p++;
                                objPntr--;
                            }
                        }
                    }
                }

                if (p > strSegments.Count() - 1)
                {
                    break;
                }
            }
        }
예제 #8
0
 public static List <string> TransactionSplit(this string edi, EDILoop loopInfo, EDIDelim delims)
 {
     if (String.IsNullOrWhiteSpace(loopInfo.GetSelectionValue()))
     {
         if (String.IsNullOrWhiteSpace(loopInfo.GetIgnoreStartID()))
         {
             return(edi.TransactionSplit(loopInfo.GetSplitFormat(), delims.Segment));
         }
         return(edi.DoTransactionSplit(loopInfo, delims));
     }
     return(edi.LoopSplit(loopInfo, delims));
 }
예제 #9
0
        public static List <string> DoTransactionSplit(this string edi, EDILoop loopInfo, EDIDelim seperators)
        {
            List <string> rtnVal = new List <string>();

            string[] segments = edi.Split(seperators.Segment);

            List <string> tmp = new List <string>();

            bool doCheck  = true;
            int  startSeg = 0;
            int  endSeg   = 0;

            //assumption is that this will be called when the first segment meets the initial criteria
            tmp.Add(segments[0]);
            for (int i = 1; i < segments.Count(); i++)
            {
                if (segments[i].StartsWith(loopInfo.GetFormat()) && doCheck)
                {
                    rtnVal.Add(string.Join("" + seperators.Segment, tmp));
                    tmp.Clear();
                }
                if (segments[i].StartsWith(loopInfo.GetIgnoreStartID()))
                {
                    doCheck = false;
                }
                if (segments[i].StartsWith(loopInfo.GetIgnoreEndID()))
                {
                    doCheck = true;
                }
                tmp.Add(segments[i]);
            }
            if (tmp.Count > 0)
            {
                rtnVal.Add(string.Join("" + seperators.Segment, tmp));
            }
            return(rtnVal);
        }
예제 #10
0
        /// <summary>
        /// In order to try to avoid issues with someone calling this wrong
        /// Make it internal as reflection should all happen here...
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="seperators"></param>
        /// <param name="isGeneric">Only used for Acknowledgements</param>
        internal void FromEDIString(string segment, EDIDelim seperators)
        {
            string[] elements = segment.Split(seperators.Element);
            if (GetType() == typeof(GenericSeg))
            {
                _segmentID = elements[0];
                RawData    = segment;
            }
            else
            {
                int x = 1;
                foreach (PropertyInfo propertyInfo in GetType().GetProperties())
                {
                    if (propertyInfo.CanRead)
                    {
                        Attribute[] attrs = Attribute.GetCustomAttributes(propertyInfo);

                        object propertyValue = propertyInfo.GetValue(this, null);


                        var bType = propertyInfo.PropertyType.BaseType;
                        if (bType == typeof(CompositeBase))
                        {
                            if (propertyValue == null)
                            {
                                //How do we put this as the property value
                                ConstructorInfo ctor     = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes);
                                object          instance = ctor.Invoke(null);

                                propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType),
                                                      null);
                                propertyValue = propertyInfo.GetValue(this, null);
                            }

                            //This allowed us to get past the 834 issue...
                            if (!string.IsNullOrWhiteSpace(elements[x]))
                            {
                                MethodInfo ediMethod = propertyValue.GetType().GetMethod("FromEDIString", internalFlags);
                                //This should always do the later but for testing have it here...
                                ediMethod.Invoke(propertyValue, new object[] { elements[x], seperators.Subelement });
                            }

                            x++;
                            if (x > elements.Count() - 1)
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrWhiteSpace(elements[x]) ||
                                attrs.Any(ax => ax.GetType() == typeof(EDIFixedLen)))
                            {
                                //The extension of FromEDIString is the actual converter... we need to do this differently
                                //get converter and set value
                                propertyInfo.SetValue(this, elements[x].FromEDIString(propertyInfo.PropertyType, attrs),
                                                      null);
                            }
                            x++;
                            if (x > elements.Count() - 1)
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }