Version Control in Dynamics AX: Check-in a project and all of its pending objects

By Eric Meissner | November 7, 2016

There have been times in Dynamics AX, when I have had to check in a project that includes a lot of objects. Whenever we do a new design or bug fix we always create a project and then add in all the objects that we are making changes to. When completed, we check in the project and all objects with pending changes so they are all included in the same change set.

Sometimes you have a project that is very large and you also could have a lot of other pending objects. This can make the check-in a pain. You have to go through the whole list of pending objects and select the ones that you need. There is the potential of missing objects or selecting an object that isn’t part of the project and shouldn’t be part of check-in. To help resolve or make this easier I made a modification to version control.

Steps and examples to make this small change to the SysVersionControlCheckIn form are below:

1. Go to a project you want to check in. In this example, I have a project that is checked out and some objects that are also checked out.

version-control_eric

2. Right-click on that project and select Check In
3. On the Check-in form all objects in the project that are checked out will also be checked to be included in check in.

version-control_eric2

This is an easy and quick way to check in a project and all the objects included in that project. Instead of having to manually select each one you want to include in the check in. This will also eliminate the possibility of selecting an object that shouldn’t be part of the check in.

To include this functionality there is a small addition to the form SysVersionControlCheckedIn.

In method setSelectedAotElements I added the call to the new method.

void setSelectedAotElements()
{
    LastAotSelection lastAotSelection = new LastAotSelection();
    TreeNode treeNode;

    treeNode = lastAotSelection.first();

    element.setSelected(treeNode == null);

    while (treeNode)
    {
        select forupdate item
            where item.ItemPath == treeNode.treeNodePath();

        if (item)
        {
            item.Selected = true;
            item.update();

            // BEGIN Select all items in a project - 10/20/2016 SSI EDM
            this.ssi_selectAllProjectItems(treeNode);
            // END Select all items in a project - 10/20/2016 SSI EDM
        }

        treeNode = lastAotSelection.next();
    }

    sysVersionControlTmpItem_ds.executeQuery();
}

Created new method that will loop through the objects in a project and mark them to be checked in if the object is part of the pending object list. If the object being checked in is not a project this logic will be skipped.

/// <summary>
/// method will search for project file for treeNode being checked in
/// if project found it’ll loop through all project treeNodes and mark other pending objects for check in
/// </summary>
/// <param name="_treeNode">
/// object being set for check in
/// </param>
/// <remarks>
/// Mark all project objects for check in - 10/20/2016 SSI EDM
/// </remarks>

private void ssi_selectAllProjectItems(TreeNode _treeNode)
{
    // assign the project name
    ProjName          projName = _treeNode.treeNodeName();
    // get a list of shared projects
    ProjectListNode   list = infolog.projectRootNode().AOTfindChild("@SYS71475");
    ProjectNode       pnProj;
    // search for project being checked in
    ProjectNode       pn = list.AOTfindChild(projName);
    
    void searchAllObj(projectNode rootNode)
    {
        #TreeNodeSysNodeType
        TreeNode          childNode;
        TreeNodeIterator  rootNodeIterator;

        if (rootNode)
        {
            rootNodeIterator = rootNode.AOTiterator();
            childNode = rootNodeIterator.next();
            // loop through all childNodes of project
            while (childnode)
            {
                if (childNode.treeNodeType().id() == #NT_PROJECT_GROUP)
                {
                    // childNode is a project group, search for next childNode
                    searchAllObj(childNode);
                }
                else
                {
                    // object found, check to see if object is checked out
                    select forupdate item
                        where item.ItemPath == childNode.treeNodePath();

                    if (item)
                    {
                        // object is checked out, mark for check in
                        item.Selected = true;
                        item.update();
                    }
                }
                
                // load next child
                childNode = rootNodeIterator.next();
            }
        }
    }

    // check if project was found    
    if (pn)
    {
        // project found, loop through project treeNodes
        pnProj = pn.loadForInspection();
        searchAllObj(pnProj);
        pnproj.treeNodeRelease();
    }
}


Under the terms of this license, you are authorized to share and redistribute the content across various mediums, subject to adherence to the specified conditions: you must provide proper attribution to Stoneridge as the original creator in a manner that does not imply their endorsement of your use, the material is to be utilized solely for non-commercial purposes, and alterations, modifications, or derivative works based on the original material are strictly prohibited.

Responsibility rests with the licensee to ensure that their use of the material does not violate any other rights.

Start the Conversation

It’s our mission to help clients win. We’d love to talk to you about the right business solutions to help you achieve your goals.

Subscribe To Our Blog

Sign up to get periodic updates on the latest posts.

Thank you for subscribing!