Hide “Export to Excel” – D365 Operations

The option of “Export to Excel” always appears by default on all the forms . Is there is a way to suppress this option. Yes. Here it is :

Export To Excel.JPG

The property ” Export Allowed” in the form grid can be set to No. Thus the user will not be able to see the option of “Export to Excel”.

Another tip : Is it possible to change the text “Export to Excel” to other text value?? Yes. In the picture above, look at the other option “Export label”. By default, this label takes the value as “Export to Excel”. User can enter the label as per the requirement and the effect can be see on the form after a build.

 

Advertisements
Posted in D365 Operations, Dynamics 365 Operations - Ax 7.0 | Tagged , | Leave a comment

Unhide the personalised field(s) – D365 operations

Personalisations helps us to hide/unhide/add the fields which we need or do not need. In my previous blog  , we saw on exporting limited fields with the help of personalisation.

In this blog, let us see to unhide the fields which we were hidden.

For instance, let us assume, the field “Orderer” has been hidden from the form “Vendor Invoice Entry”. This field will not be visible even after the form refresh or reload the form. Given below the steps on doing this.

  1. Click on Personalise option again

hide 1

On clicking this option, you will see this personalize table. Click the highlighted one. (this is the option to Unhide) .

As soon as you click this highlighted option, you will see all the hidden fields:

hide2

Then click on the field which you wanted to see. (In  this case, click Orderer ). Then click Close in the personalize table. Now you will be able to see the field.

hide3.png

 

Posted in D365 Operations, Dynamics 365 Operations - Ax 7.0, Uncategorized | Tagged , | Leave a comment

Limited fields export using Export to Excel – D365 Operations

As we all know , “Export to Excel” in a form exports the data of all the fields given in the form`s grid.

There may be situations where the user expects to export only few fields from the form .

There are 2 ways to do this :

  1. Make the Visible property of the field in the form as No. But if the user expects the field to be available, then this is not a feasible solution.
  2. Another ideal way with  less technical intervention is form Personalisation. User can export and import the personalisation . Given below the steps to do it.
    •  Personalise the form by hiding the unnecessary fields. (When the session is refreshed, user will be able to see all the fields in the form)
    • Export the personalisation. It is exported as XML file which has the changes for hidden fields.
    • Whenever user needs to use “Export to Excel” , below steps are to be followed
    • Same approach can be used for Exporting the personalisation as well.
    • 1
    • 2
    • 3

 

Posted in Uncategorized | 1 Comment

Extract security objects details for a role

There are situations where we feel it would be handy to get a report having the details of  all the security objects which are used by a role.

There is another option of getting these details by navigating to AOT>Roles> Choose a role name -> right click> Addins-> Security tools. In this case, we see a lengthy report (listed for each field).

I have a simple job which creates a csv file and gives details about RoleName, AOTRoleName,Label,Description,Menu Item , Menu item Type, Menu item label,Duty, Privilege,Access level.

public void AE_SecurityReport()
{
 #AOT
 #File

 SecurityRoleAOTName roleAOTName ;
 SecurityRoleName roleName;
 SecurityRole securityRole;

 TreeNode treeNode;
 TreeNode treeNodeDuty = infolog.findNode(@'\Security\Duties\');
 TreeNode treeNodePriv = infolog.findNode(@'\Security\Privileges\');
 TreeNode treeNodePrivNew;
 TreeNode treeNodeDutyNew;
 TreeNode treeNodeObj;
 TreeNodeTraverser treenodeT;
 TreeNode treeNodeRole;
 TreeNode treeMenu;

 Set setDuty ;
 Set setPrivilege;
 Set setMenuItem;

 SetEnumerator setEnumerator ;

 SysModelElement modelElement;
 SysModelElementType modelElementType;

 UtilElementName name;
 TreeNodePath path;

 str maintainlicenseType;
 str viewlicenseType;
 str menuLabelName;
 str roleAccess;
 str configurationKey;

 String50 menuName;
 String255 securityPrivilege, securityDuty, securityMenuPath;
 String50 engLabel, frLabel, engDescription, frDescription;

 Label objLabel = new Label();
 CommaTextIo commaTextIo;
 FileIOPermission permission;
 FileName fileName;

 container getPrivilegeDetails(
        SecurityRoleAOTName _roleName, MenuItemName _menuItemName)
 {
        SecurityTaskEntryPoint secTaskEntryPoint;
        SecurityRole secRole;
        SecurityRoleTaskGrant secRoleTaskGrant;
        SecurityEntryPointLink secEntryPointLink;
        SecurableObject secObject;
        SecurityTask secTask,secTaskDuty;
        SecuritySubTask secSubTask;
        String255 secPrivilege, secDuty;
        container conPrivDuty, conSecDuty ,conAccess ;
        container conSecPrivilege;

        Select secRole where secRole.AotName == _roleName;
        select secObject where secObject.Name == _menuItemName &&
          (secObject.Type == SecurableType::MenuItemDisplay ||
           secObject.Type == SecurableType::MenuItemAction ||
           secObject.Type == SecurableType::MenuItemOutput);
        select secEntryPointLink where secEntryPointLink.EntryPoint == secObject.RecId;

      while select SecurityTask from secRoleTaskGrant
            where secRoleTaskGrant.SecurityRole == secRole.RecId
      join SecuritySubTask from secSubTask
           where secSubTask.SecurityTask == secRoleTaskGrant.RecId
      join AotName from secTask
           where secTask.RecId == secSubTask.SecuritySubTask
              && secTask.Type == SecurityTaskType::Privilege
      join AotName from secTaskDuty
          where secTaskDuty.RecId == secSubTask.SecurityTask
             && secTaskDuty.Type == SecurityTaskType::Duty
      join PermissionGroup from secTaskEntryPoint
         where secTaskEntryPoint.EntryPoint == secEntryPointLink.RecId &&
               secTaskEntryPoint.SecurityTask == secSubTask.SecuritySubTask
     {
           conSecPrivilege += secTask.AotName;
           conSecDuty += secTaskDuty.AotName;
           conAccess += enum2str(secTaskEntryPoint.PermissionGroup);
     }
    conPrivDuty = [conSecPrivilege, conSecDuty,conAccess];
    return conPrivDuty;
  } 
  ;
 permission = new FileIOPermission(fileName,#io_write);
 permission.assert();
 commaTextIo = new CommaTextIo(fileName,#io_write);
 commaTextIo.write('RoleName,AOTRoleName,Label,Description,MenuItemType,MenutItemName,MenuItem Label,Duty,Privilege,Access Level');

 select Name,AotName from securityRole where securityRole.AotName == "Production Manager";
 
 roleAOTName = securityRole.AotName;
 treeNode = TreeNode::findNode(@'\Security\Roles\'+ roleAOTName).AOTfirstChild();
 treeNodeRole = treeNode::findNode(@'\Security\Roles\'+ roleAOTName);

// Loop through the roles to get Duties
 treenodeT = null;
 setDuty = new Set(Types::String);
 treenodeT = new TreeNodeTraverser(treeNode, false);
 while(treenodeT.next())
 {
     setDuty.add(treenodeT.currentNode().AOTname());
 }
 setEnumerator = null;
 setPrivilege = new Set(Types::String);
 // Loop thru the duties to get privileges
 setEnumerator = setDuty.getEnumerator();
 while (setEnumerator.moveNext())
 {
      treeNodeDutyNew = treeNodeDuty.AOTfindChild(setEnumerator.current()).AOTfirstChild();
      treenodeT = new TreeNodeTraverser(treeNodeDutyNew, false);
      while(treenodeT.next())
      {
         setPrivilege.add(treenodeT.currentNode().AOTname());
      }
 }

// Loop thru the privileges to get Entry points
 setEnumerator = null;
 setMenuItem = new Set(Types::String);
 setEnumerator = setPrivilege.getEnumerator();

while (setEnumerator.moveNext())
 {
      treeNodePrivNew = treeNodePriv.AOTfindChild(setEnumerator.current()).AOTfirstChild();
      treenodeT = new TreeNodeTraverser(treeNodePrivNew, false);
      while(treenodeT.next())
      {
         setMenuItem.add(treenodeT.currentNode().AOTname());
      }
 }

// loop thru the menu items to get the properties
 setEnumerator = null;
 setEnumerator = setMenuItem.getEnumerator();
 while (setEnumerator.moveNext())
 {
     name = setEnumerator.current();
     select firstOnly1 modelelement 
         where modelelement.Name == name
      && (modelelement.ElementType == enum2int(UtilElementType::OutputTool) ||
          modelelement.ElementType == enum2int(UtilElementType::ActionTool) ||
          modelelement.ElementType == enum2int(UtilElementType::DisplayTool));

     switch (modelelement.ElementType)
     {
         case enum2int(UtilElementType::OutputTool) :
         path = #MenuItemsOutputPath;
         break;

         case enum2int(UtilElementType::ActionTool) :
         path = #MenuItemsActionPath;
         break;

         case enum2int(UtilElementType::DisplayTool) :
         path = #MenuItemsDisplayPath;
         break;

         default :
         path = '';
         break;
      }
 if (path)
 {
       select modelElementType where modelelementtype.TreeNodeName == path;
       treeNodeObj = infolog.findNode(path).AOTfindChild(name);
       menuLabelName = treeNodeObj.AOTgetProperty('Label');
       menuName = treeNodeObj.AOTgetProperty('Name');
       engLabel = SysLabel::labelId2String(treeNodeRole.AOTgetProperty('Label'), 'en-us');
       frLabel = SysLabel::labelId2String(treeNodeRole.AOTgetProperty('Label'), 'fr');
       engDescription = SysLabel::labelId2String(treeNodeRole.AOTgetProperty('Description'), 'en-us');
       frDescription = SysLabel::labelId2String(treeNodeRole.AOTgetProperty('Description'), 'Fr');

       treeMenu = infolog.findNode(#MenusPath);
       treenodeT = new TreeNodeTraverser(treeMenu, false);

       securityMenuPath = ' ';
       while(treenodeT.next())
       {
         if(treeNodeT.currentNode().AOTfindChild(SysLabel::labelId2String2(menuLabelName)))//objLabel.extractString(menuLabelName)))
         {
            securityMenuPath = treenodeT.currentNode().treeNodePath();
         }
       }
      securityPrivilege = conPeek(getPrivilegeDetails(roleAOTName, menuName),1);
      securityDuty = conPeek(getPrivilegeDetails(roleAOTName, menuName),2);
      roleAccess = conPeek(getPrivilegeDetails(roleAOTName, menuName),3);
      maintainlicenseType = treeNodeObj.AOTgetProperty('MaintainUserLicense');
      viewlicenseType = treeNodeObj.AOTgetProperty('ViewUserLicense');
      configurationkey = treeNodeObj.AOTgetProperty('ConfigurationKey');

      commaTextIo.write(roleName,roleAOTName,engLabel, engDescription, modelElementType.Name, treeNodeObj.AOTname(), objLabel.extractString(menuLabelName), securityDuty, securityPrivilege, roleAccess);
 }
 CodeAccessPermission::revertAssert(); 
 }
}
Posted in Ax 2012, Ax Security, Ax2012, Dynamics Ax, Uncategorized | Tagged , | Leave a comment

Publish button not enabled in “Open in Excel” – D365 operations

I had a strange issue when trying to Publish the changes from “Open in Excel”.

Publish button was not enabled.  It was greyed out .

Just to brief about the set up:

I created a data entity with ReqItemTable as Primary data source and added the remaining datasources (InventDim/ReqItemGroup) to the data entity.

I mapped the needed fieds in AUTO REPORT.
Now I get the option “Open in Excel” in my form and I could export the fields succesfully.
But the button “Publish” is disabled .

Capture

What was the solution: Simple – One of field which was present in Entity key was missing in the AutoReport fields. On adding that, Publish button is enabled and I am able to proceed with updating the changes.

Capture1

 

Posted in D365 Operations, Excel D365, Uncategorized | Tagged , , | Leave a comment

Roles of current user – D365 operations

There are situations where we need to enable/disable a control based on the users role.

I have written a code which is split into 2 sections :

First part of the code checks – the roles assigned to the user and returns the roles in a list

Second part of the code takes 2 parameters – First parameter is list from the above result, Second one is also a list which checks has the roles to be verified. This is needed to enable or disable a control.

This logic is applicable for Ax2012 as well.

GetRoles1

GetRoles

Posted in Ax 2012, D365 Operations, Dynamics 365 Operations - Ax 7.0, Uncategorized | Tagged | Leave a comment

D365 Operations – Change the label of a dialog field

Without overlayering, is it possible to change the label of a dialog field ? Yes!!! You can do this in Post event handler of dialog method.

But I had to chose the option of referring the field name in my code. Given below the code snippet:

/// <summary>
/// Change the dialog label
/// </summary>
/// <param name=”args”></param>
[PostHandlerFor(classStr(ReqItemJournalUpdate),                                              methodStr(ReqItemJournalUpdate, dialog))]
public static void ReqItemJournalUpdate_Post_dialog(XppPrePostArgs args)
{
    Dialog dlg ; 
  
    Map                        mapDlgFields ;
    MapEnumerator mapEnums;
    dlg                      = Args.getReturnValue();
    mapDlgFields = dlg.name2dialogClass();
    mapEnums      = mapDlgFields.getEnumerator();
    while (mapEnums.moveNext())
    {
             if(mapEnums.currentKey() == “Fld4_1”)
            {
                  dlg.form().design().control(“Fld4_1”).label(“This is new label for this field”);
            }
    }
}

Intellisense doesnot work for retrieving the property name “Label”. So we need to feed it and you will not the build doesn’t give any errors.

 

Posted in D365 Operations, Uncategorized | Tagged | Leave a comment