This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DEVELOPERS FORUM - Copying a multilevel BOM

parepalli - Thursday, July 11, 2013 10:39 PM:

Hi all

 I want to copy a multilevel BOM of unknown levels using C#. I am able to do for known levels. But, I am having trouble with copying BOM of unknown levels. If it's possible, please let me know.

Thanks!



Brian - Monday, July 15, 2013 9:10 PM:

Hi Parepalli,

You need to use a recursive  function to go down as far as the BOM goes.

Create a method: C# Server side:

Create an Action: Type; Item, Location: Server. Method (name of method created above)

Paste this code into the method:

 

// Server side action to create a copy of a top level Part item

 

        // Edited 16 July 2013

        // Brian Pye. 

        // Added test to see if the old part has already been cloned.

        // If yes then use existing new clone part. If no then create new clone part.

 

 

        Innovator inn = this.getInnovator();

        CopyHelper ch = new CopyHelper();

 

        Item ctx = this;

 

        Item newParent = ch.copyFields("Part", ref ctx, ref inn);

        ch.addNextLevel(ref newParent, ref ctx, ref inn);

        Item result = newParent.apply();

 

        return this;

 

    }

 

    public class CopyHelper

    {

 

        private string[] copyFieldArray;

        private Dictionary<string, Item> partRefDict;

 

        public CopyHelper()

        {

            partRefDict = new Dictionary<string, Item>();

            copyFieldArray = new string[] { "classification", "description", "external_id", "external_owner", "make_buy", "managed_by_id", "name", "owned_by_id",  team_id", "thumbnail"};

        }

 

        public Item copyFields(string type, ref Item original, ref Innovator inn)

        {

            Item newItem = inn.newItem(type, "merge");

            // Since merge edits if the item is found and adds if it is not found then we need an

            // ID for the edit to work against. Create an ID for the new item to use.

            newItem.setID(inn.getNewID());

            for (int i = 0; i < copyFieldArray.Length; i++)

            {

                newItem.setProperty(copyFieldArray[i], original.getProperty(copyFieldArray[i], ""));

            }

            return newItem;

        }

 

        public void addNextLevel(ref Item parent, ref Item oldParent, ref Innovator inn)

        {

            // retrieve all of the next level parts down

            // for each Part make a new part and recurse to the next level

            Item oldBom = inn.newItem("Part BOM", "get");

            oldBom.setProperty("source_id", oldParent.getID());

            oldBom.setAttribute("select", "related_id,source_id");

            oldBom = oldBom.apply();

 

 

            Item parts = oldBom.getItemsByXPath("//Item[@type='Part']");

            int count = parts.getItemCount();

            for (int j = 0; j < count; j++)

            {

                Item part = parts.getItemByIndex(j);

                Item rel = inn.newItem("Part BOM", "add");

                if (partRefDict.ContainsKey(part.getID()))

                {

                    // if the old part is already in the partRefDictionary then this old part has already been

                    // cloned during this branch operation.

                    // In this case we want to use the existing cloned part in place of creating a new cloned

                    // part.

                    Item newPart = inn.newItem();

                    bool hasValue = partRefDict.TryGetValue(part.getID(), out newPart);

 

                    rel.setProperty("related_id", newPart.getID());

                }

                else

                {

                    Item newPart = copyFields("Part", ref part, ref inn);

                    // add the old and new part to the dictionary object.

                    partRefDict.Add(part.getID(), newPart);

                    addNextLevel(ref newPart, ref part, ref inn);

 

                    rel.setRelatedItem(newPart);

                }

 

                parent.addRelationship(rel);

            }

        }

 

        //}  last method or class closing bracket is ommitted.

 

This should create a copy of the Part BOM hierarchy starting from the Part you selected the Action to run on.

It will create new Parts for each part in the BOM and then create a new hierachy under the parts.

This may do more than you want but the process of walking the tree (recursive function) is the same and can be adapted from here.

Hope this helps,

Brian.



parepalli - Monday, July 15, 2013 10:43 PM:

thank you so much Brian. I will try with it and get back to you.