AX 2012 How to hide the modules as per user roles across the company

Steps to hide the modules in AX 2012 R3:

Step 1. Create a new Class 

class RBHideModules
{
}

Step 2 : Create a new Static  method to replace the "Navigation Option" in all the companies.
 if you want the same modules reflect in all the companies , then the below method is required.

public static void replaceNavOptionsInAllCompanies()
{
    #define.elementName('Usersetup')
    #define.designName('NavPaneOptionsButtons')

    DataArea        dataArea;
    SysLastValue    sysLastValue, sysLastValue2;

    select sysLastValue
    where
        sysLastValue.company == curext() &&
        sysLastValue.userId == curUserId() &&
        sysLastValue.elementName == #elementName &&
        sysLastValue.designName == #designName;

    if (sysLastValue)
    {
        while select id from dataArea
            where !dataArea.isVirtual && dataArea.Id != curext()
        {
            select forUpdate sysLastValue2
                where sysLastValue2.company == dataArea.Id &&
                    sysLastValue2.userId == curUserId() &&
                    sysLastValue2.elementName == #elementName &&
                    sysLastValue2.designName == #designName;

            ttsBegin;

            sysLastValue2.company = dataArea.Id;
            sysLastValue2.userId = curUserId();
            sysLastValue2.elementName = sysLastValue.elementName;
            sysLastValue2.recordType = sysLastValue.recordType;
            sysLastValue2.designName = sysLastValue.designName;
            sysLastValue2.isKernel = sysLastValue.isKernel;
            sysLastValue2.value = sysLastValue.value;

            sysLastValue2.write();

            ttsCommit;
        }
    }
}


Step 3. Create a new static method in the class  as shown below (Save and Close it) to hide the modules.

//Code for Hide Modules Functionality
public static void HideModulesForRole()
{
    container   cont_navButtons;
    container   cont_UserRoles;

    TreeNode            menunode;
    TreeNode            mainmenunode;
    TreeNodeIterator    menuitemiter;

    str aotName;

    int i = 1;
    int j = 1;
    int loc;

    boolean isAdmin = false;

    SecurityRole        securityRole;
    SecurityUserRole    securityUserRole;

    #AOT
    #define.Zero('0')
    #define.MainMenuLocation('\\Menus\\MainMenu')

    //Fetch all roles for currently logged in User and insert in variable cont_UserRoles.
    while select securityUserRole
        join securityRole
            where securityUserRole.User ==  curUserId()
                && securityRole.RecId == securityUserRole.SecurityRole
    {
        cont_UserRoles += securityRole.AotName;

        if (securityRole.AotName == '-SysAdmin-')
        {
            isAdmin = true;
        }
    }

    if (!isAdmin && conFind(cont_UserRoles, 'YourRolesName'))
    {
        mainmenunode = TreeNode::findNode(#MainMenuLocation);
        menuitemiter = mainmenunode.AOTiterator();
        menunode     = menuitemiter.next();

        while(menunode != null)
        {
            aotName = menunode.AOTname();

            if(aotName == 'Home' || aotName == 'InventoryManagement')
            {
                // Prefix 1 to show module
                cont_navButtons = conIns(cont_navButtons, j, '1' + aotName);
            }

            else
            {
                // Prefix 0 to hide module
                cont_navButtons = conIns(cont_navButtons, j, '0' + aotName);
            }
            j++;

            menunode = menuitemiter.next();
        }
        // Hide Modules with 0 as prefix
        infolog.navPane().setCurrMenuButtons(cont_navButtons);

// this is required only incase if you want to hide the modules in all the companies
        RBHideModules::replaceNavOptionsInAllCompanies(); 
    }
}



Step 4 : Open the method "startupPost" from the  Class -> Info , Call the  newly created class static method as shown. (Save & Close) 

void startupPost()
{
    RBHideModules::HideModulesForRole();
}

Notes : The above code will works only for the startup company, In case if the user changes the company , all the modules will be reflected again.  To Avoid that please continue with the step 4:

Step 4: Open the form "SysDataAreaSelect" ,  add the code to the method "SwitchCompany" in the last line before the loop ends.

void SwitchCompany(boolean NewWorkspace)

{
      (..... means  standard code already available)
      .....
      ......
      RBHideModules::HideModulesForRole();
}

Step 5: Restrict the user using the Navigation Pane option manually to add the modules.

Edit the "OkButton" clicked method of the Form "SysNavPaneOptionsDialog", write the below code above the super();

RBHideModules::HideModulesForRole();

This will restrict the user to add the modules manually.

Result : Whenever the user changes the company from the company dialog , it hides the modules as  you expect.



1 comment:

  1. dear sir how to diable left menu itms( modules) from as user in D365fo
    Regards

    ReplyDelete

D365 F&O Release Pipeline Step by Step Configuration Without ISV's

  Step-by-Step Guide: Creating D365FO Build and Deploy Pipelines Azure DevOps Build Pipeline I will walk through the standard procedures...