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

Advertisements
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

D365 Operations – Change Dialog caption

Without overlayering, is it possible to change the Caption of a Runbase dialog class in D365 Operations. YES!!!! You can!!!!

Create a post event Handler of Description method and use

/// <summary>
/// Change the value for caption
/// </summary>
/// <param name=”args”></param>
[PostHandlerFor(classStr(ReqItemJournalUpdate),
                                  staticMethodStr(ReqItemJournalUpdate, description))]
public static void ReqItemJournalUpdate_Post_description(XppPrePostArgs args)
{
     Args.setReturnValue(“This is a new caption”);
}
Build the solution and execute now. You will see the new caption.
Posted in D365 Operations, Dynamics 365 Operations - Ax 7.0, Uncategorized | Tagged | Leave a comment

“AX client execution of ‘Executing CIL generation’ timed out” TFS build

I was setting up a new build definition for my project and was facing the exception of Time out error “AX client execution of ‘Executing CIL generation’ timed out”

Initially I assumed that there should be some issue in Ax CIL and tried few troubleshooting steps

1.Increased the execution time of CIL in build from 60 minutes to 180 minutes.

2.Launching manual full CIL from my login . It completed without any errors.

Then I tried logging on to build account credentials . When Ax is launched , customer experience dialog pop up displayed. So I understood this window was blocking the CIL step.

Clicked ok and took a back up of the database (Reason being this latest database has the option of not displaying additional dialogs from this login). Then used this database as staging database.

Amazing.. It worked. 🙂

In order to avoid any additional dialogs to be displayed when Ax launched, set the field “SQLEnabled” from SysUserInfo table .

 

 

Posted in Ax 2012, TFS build | Tagged , | Leave a comment

Trace Parser – Ax2012

If you find any performance issues in the code or if Ax moves to not- responding mode in mid of executing a process, developer can take the help of readily available tool in Ax – Trace Parser.

User can analyse the events which causes performance bottlenecks (X++ code taking longer time to execute, indefinite while loops etc) .

I am not explaining the steps in trace parser installation in this post. Our focus will be on its usage and how it helps developer when there is a performance hit.

How to reach this tool in Ax?

1

By default, the parameters , “Xpp” and “BindingParameters” are disabled. You need to enable it.

2

Click “Start Trace” and specify a file name. . Execute the scenario which gives performance issue . Once done, “Stop Trace” and this will create a trace file .

Now click “Open Trace” button. In case you get any error in opening the file,

4

go to start and type Trace parser

5

You can import the trace file . Attach your session to investigate the scenario.

6

Call Tree tab shows the hierarchy of events happened.  Long duration tasks are highlighted in red which helps the developer to analyse the code.

12

X++/RPC tab – You can sort it by exclusive and inclusive and find the calls taking most of the time.  There is a call stack tab which shows the trace of the methods called.

14

SQL tab : It shows the db calls and it helps the developer to check the DB statements which consumes more time . It can give us the clue if any index is missing or an insert during the index causes the problem.

With this, we get basic idea on using Trace parser. I am briefing you about another tool from SQL side which is called “Activity monitor”.

This tool ,when used with Trace parser helps to fix the performance issue in the application. You should have administrator permission to trigger this tool.

Option 1

8

Option 2 : Shortcut icon

9

The column “Head Blocker” specifies if there is any process blocked during execution .We will also get to know the dependant process is affected by this block.

10

In order to kill the blocking process, right click and select the option “Kill”.

To dig more the details, click “Details” tab which gives a hint on the statements that are causing the block.

11

So  Activity monitor and Trace parser go hand in hand to pull out the performance issue without investing more time in probing the issue.

Posted in Ax 2012, Performance, Tracing | Tagged , , | 1 Comment

Update physical dimension of an item Ax2012 – CSV import

There are two ways where we can update the physical dimensions of an item in Ax2012.

Option 1:

1

 

Option 2:

2

Option 1 updates the fields in invent table . But it doesn`t reflect the changes in option 2 form (Manage Inventory -> Physical dimensions).

If either width or depth or height is changed , Volume calculation has to be done manually.

So this option is not the ideal way to update the physical dimensions fields.

Option2 addresses all the issues in former approach. Changes done on this table would reflect in Invent table fields . Volume calculations are taken care as well.

Thus , apt way to modify the values of physical dimensions will be from the path PIM-> Released Products -> Manage Inventory -> Physical dimensions.

Code snippet is given below to import the fields using csv.

static void AE_ImportItemsPhysicalDimensions(Args _args)
{
Dialog dialog = new Dialog();
DialogField dialogField;
AsciiIo importFile;
str filePath,fileNameOnly;
filetype type;
container record;
str Delimiter = “,”;
int totalRecords, updates;

InventTable inventTable;
WHSPhysDimUOM WHSPhysDimUOM;

dialogField=dialog.addField(extendedTypeStr(FilenameOpen),”Select File”,”Select file to import”);
dialog.caption(“Import Items weight and size”);
dialog.filenameLookupFilter([‘csv’,’*.csv’]);
if(!dialog.run())
return;
[filePath, fileNameOnly, type] = fileNameSplit(dialogField.value());
importFile = new AsciiIo(dialogField.value(), ‘R’);
if((!importFile) || (importFile.status() != IO_Status::Ok))
{
warning(“Error in opening import file”);
throw(Exception::Error);
}
importFile.inFieldDelimiter(Delimiter);
if((!importFile) || (importFile.status() != IO_Status::Ok))
{
warning(“Error in opening log file”);
throw(Exception::Error);
}
try
{
ttsbegin;
while(importFile.status() == IO_Status::Ok)
{
record = importFile.read();
if(!record)
break;
totalRecords++;

inventTable = InventTable::find(conPeek(record,1), true);
select forupdate Width, Height, Depth from WHSPhysDimUOM where WHSPhysDimUOM.ItemId == inventTable.ItemId && WHSPhysDimUOM.UOM == ‘Un’;
if(!inventTable)
{
warning(strFmt(“Item %1 doesn’t exist.”,conPeek(record,1)));
}
else
{
updates++;
WHSPhysDimUOM.Width = conPeek(record,3);
WHSPhysDimUOM.Height = conPeek(record,4);
WHSPhysDimUOM.Depth = conPeek(record,5);
WHSPhysDimUOM.update();
}
}
ttscommit;
}
catch(Exception::Error)
{
Throw(Exception::Error);
}
info(strFmt(“Total updated items = %1 out of %2”,updates,totalRecords));
}

Posted in Ax 2012, Dynamics Ax, File Handling, Uncategorized | Tagged , | Leave a comment

Count of records in a query

Here is a simple command which can be executed even in a job to take a count of records for a query.

querycount

 

Posted in Ax 2012, Uncategorized | Tagged | Leave a comment