Tuesday, January 12, 2016

Step by Step guide to deploy Microsoft Dynamics AX 2012 R3/AX7 (Rainer) on Azure using lifecycle services

This article explains how to deploy AX 2012 R3 and AX7 (Rainer) environments on Azure by using the Cloud-hosted environments tool in Microsoft Dynamics Lifecycle Services.The deployment of AX7 and AX 2012 R3 on Azure using Lifecycle services is similar, In this article I will deploy Dynamics AX 2012 R3 as an example.

Here is a step by step guide to deploy AX 2012 R3 or AX7 on Azure using lifecycle services.

Login to Azure and copy subscription id (In my case I got a free trail of Windows Azure).


Create a new or use existing live id to login to azure. here is the link to login into Azure management portal.



Click setting button on the bottom left highlight your subscription id and copy it.



Login into Lifecycle services, Create project and download management certificate.

Use the same live id used in step one to login into Lifecycle services. Here is the link for life cycle services.



Create a new project.






After creating the project scroll right and go to client hosted environments



Go to Azure connections and select add. Provide name and subscription id copied in step one from Azure management portal and click next.



Download management certificate (don’t install).


Upload management certificate.


Switch back to Azure management portal, go to Settings -> Management certificates and add management certificate.




Setup region and deploy Demo/development or test environment.


Switch back to Lifecycle services and go to “Cloud hosted environments” and click next



Select your region and click next,



Go back to Cloud hosted environments page, click ‘+’ near the top left and. Click the Demo on the right side panel and click deploy and select environment topology. 






Name you instance, check accept license check box and click next. Select deployment server from a list of servers (select according to your region for quick deployment).





After this the deployment status will be “Queued” or “in progress” for few hours and will be changed to “Complete” once deployment will be completed, normally it takes around 3 to 4 hours to complete deployment.






After the deployment is done, Lifecycle services will take few minutes to configure few services on Azure including a storage container and a VM. Once done you can download .rdp file for your VM and login using the credentials provided in LCS deployment page (screenshot above).



Your MS Dynamics AX deployment is done and you VM is ready to use.
Cheers!



Getting started with Dynamics AX7

Tuesday, November 17, 2015

Hiding Dynamics AX modules for a specific role

As you may know there is an option to customize the navigation pane (which shows or hides modules), screenshots below.




From here you can hide/display multiple modules, now we can achive the same functionality from code for a specific role.

For this create a new class and within this new class 'HideAXModules' create a static method 'HideModulesForRole' and add following code within the static method,

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);
    }
}

Cheers!

Monday, November 16, 2015

Calculating sales price

To calculate sales price of an item first you need to setup few things in Retail.

1) Ensure your login is linked to one of the retail channels.

2) 1.      If you want any price or discounts to appear on the sales line then affiliation and product setup needs to be performed
a.      Affiliation: Ensure the customer is linked to an affiliation

a.      Ensure that the item is linked to a proper product category.


Now use code sample mentioned in this blog to calculate sales price of an item.

Cheers!


Thursday, September 3, 2015

Creating and retrieving document notes through AIF

Document notes are not accessible from outside AX client(EP, AIF etc) if the restriction property is set as internal, while creating document note through AIF you can specify restriction property to do this set Restriction property as "External" and set  RestrictionSpecified to True.

To set restriction on header specify these two properties,
and to set restriction on line,


Cheers!

Thursday, July 2, 2015

Invalid data container type

You might get this issue while working on web service(.NetTcp adopter) in VS or during execution of AIF document service generation wizard.

To fix this issue you have to merge the macro from the several layers so every DataContainerType of both standard AX and your custom services are mentioned.If you still see this error after merging DataContainerTypes macro do compile forward for "AfStronglyTypedDataContainer" class.

Cheers!

Monday, June 8, 2015

Reference lookup for Customer delivery address

Before writing custom lookup first you have to add reference control in your form and you have to specify some properties as shown in the screen shot below,

Now override "lookupReference" method of your reference control and add following code,

public Common lookupReference()
{
    CustTable                   custTable;
    DirPartyTable               dirPartyTable;
    DirPartyLocation            dirPartyLocation;
    LogisticsPostalAddress      logisticsPostalAddress;
    SysReferenceTableLookup     sysRefTableLookup;
    Query                       lookupQuery = new Query();
    QueryBuildDataSource        lookupQueryDataSource;

    // Construct the SysRefTableLookup object
    sysRefTableLookup = SysReferenceTableLookup::newParameters(tableNum(LogisticsPostalAddress), ReferenceGroup);

    // Add the field list that will be displayed on the lookup form
   // You can Change/Add more fields in lookup based on your requirement.

    sysRefTableLookup.addLookupfield(fieldNum(LogisticsPostalAddress, Address));
    sysRefTableLookup.addLookupfield(fieldNum(LogisticsPostalAddress, Location));

    // Construct the query's data source
    lookupQueryDataSource = lookupQuery.addDataSource(tableNum(LogisticsPostalAddress));

// To add multiple values in range.
    while select  Location from LogisticsPostalAddress
        join DirPartyLocation
        join dirPartyTable
        join custTable
            where logisticsPostalAddress.Location == dirPartyLocation.Location
                && dirPartyLocation.Party == custTable.Party
                && custTable.Party == DirPartyTable.RecId
                && custTable.AccountNum == ADCAutodesaCustomerInfo.CustAccount
    {
        // Add ranges to the query data source
        lookupQueryDataSource.addRange(fieldNum(LogisticsPostalAddress, Location)).value(queryValue(LogisticsPostalAddress.Location));
    }


    // Pass the query to the lookup object
    sysRefTableLookup.parmQuery(lookupQuery);

    return sysRefTableLookup.performFormLookup();
}

after adding this code compile your form/project to reflect the changes on form.


Cheers!