Hide Modules For a Role
While working on AX 2012 customization, there was an interesting requirement from our client to hide modules from the navigation pane. For a particular role the client wanted only two Modules to be displayed. Since I wasn’t sure how to achieve this functionality so obviously first thing first, I googled this requirement. And was astonished to find out no solution available to hide modules (you may question my googling though 🙂 ), in fact I found a link from Microsoft Dynamics Community that suggested that this can’t be done.
So keeping in mind few things here, firstly AX is designed such a way that if no menu items within a module are available for a particular role, the module is then hidden. But if even a single menu item is available for the logged in user, then the user gets to see the Module within the navigation pane. Same is the case for Menus; Here there is a possibility that in two different modules named A and B there are some common Menu items. In our case we want to make sure that only the Module that we want to appear comes up, and the other Module is not visible even if it has some Menu Items that are common with the visible Module.
As we know there is already an option to customize the navigation pane (which shows or hides modules), shown below. So the code written to achieve this functionality has been inspired from here:
As mentioned before this restriction is for one type of role only, so we need to find an existing ax class that gets called when AX starts up and after navigation pane has been constructed, So the appropriate class that I ended up with is the Info class.
Firstly a new class was created named HideModules, within this new class a static method is created namely HideModulesForRole and following code was added within that method:
//<Mazik>
//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, 'YourRoleName'))
{
mainmenunode = TreeNode::findNode(#MainMenuLocation);
menuitemiter = mainmenunode.AOTiterator();
menunode = menuitemiter.next();
while(menunode != null)
{
aotName = menunode.AOTname();
if(aotName == 'Home' || aotName == 'YourMenuName')
{
// 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);
}
}
//</Mazik>
So this static method needs to be called from the startupPost method of the Info class.
There is also one thing to consider, we would also need to block the user from manually adding modules from navigation Pane Options, for this purpose the clicked method of the OKButton within SysNavPaneOptionsDialog Form needs to be edited. (It’s quite straight forward so I am not adding the details here.) Due to this, we can set the form to return error message while trying to edit navigation pane options. And voila, for a moment everything worked like a charm. Afterwards as I was going through the functionality a bug was observed. I was happy to find out only one 🙂 , So here is the detail:
If you try to change the company all of the modules come back. So for this purpose some help was asked from the Microsoft Dynamics Community. As advised in the first reply of the link, I used the SwitchCompany method of the SysDataAreaSelect Form. At the bottom of the form the same static method HideModulesForRole has been called and this bug is fixed, now if we hide modules it remain the same way even if the company changes.
So that’s it for now, If you come across any issues during achieving the same functionality (i.e. hide modules from navigation pane) feel free to contact me on nayyar.mashkoor@maziktech.com (any corrections are also highly appreciated).
Thanks for reading !