Friday, July 27, 2018

D365FO - How not to select Fleet Management modules in package creation

Want assurance that you never select/include fleet management modules in package creation or build all module together. Just rename the Descriptor folder from all these three locations and refresh models in VS first time to reflect the changes.

<Service volume drive>:\AosService\PackagesLocalDirectory\FleetManagement
<Service volume drive>:\AosService\PackagesLocalDirectory\FleetManagementExtension
<Service volume drive>:\AosService\PackagesLocalDirectory\FleetManagementUnitTests


Friday, July 6, 2018

D365FO - Get list of obsolete data entities

Find which data entity is obsolete after every new update. Here are the steps.

For example; Customers V2 data entity is obsolete with version 8.0








For developers: Type the below in the metadata search in VSTS:
type:dataentityview property:isobsolete=yes


Saturday, January 6, 2018

D365 platform update 12 (7.3): Admin access changes

The Microsoft team did release platform update 12 for Dynamics 365 for Finance and Operations, Enterprise Edition 7.3. There have been few changes concerning accessibility (admin access on VMs).

Starting with platform update 12 users do not have admin access to D365 VMs hosted on the Microsoft subscription.

Which means:

1.    You can only log in with the "builtin\Userxxxxxxxxx" account and not the “builtin\axlocaladmin” account anymore.
Prior to PU12 7.3

With PU12 7.3

2.    IIS Express is used as the web server instead of IIS

3.    IIS Express runs when Visual Studio is running 

4.    Visual Studio cannot be run as Administrator anymore (you are not the local admin anymore on your development VM L ). Just double click Visual Studio shortcut or run it from start.

Admin access to development virtual machines can only be achieved with following options;

1.    Host a development VM on a separate Azure subscription

2.    Deploy VM with an older platform update than PU12 and then upgrade platform update (This option will not work for 7.3)

Reference: https://community.dynamics.com/ax/b/newdynamicsax/archive/2018/01/05/restricted-admin-access-on-development-vms-with-platform-update-12-what-you-need-to-know

Monday, December 18, 2017

Newly created data entity is not visible in data management entity list?

If you created a new data entity and it's not visible in your data management entity list. 

Open Data Management workspace -> Framework parameters -> Entity Settings and hit the "Refresh Entity List" button


Sunday, December 17, 2017

D365FO: How to debug a non-development and a non-production environment

This post outlines the steps how to debug an issue which is happening in non-development or non-production environments e.g. UAT environment.




1.    RDP to your environment where you want to debug the issue, with this example I am connecting to UAT (Sandbox). 
2.    Connect to SQL server
a.     Get the server name from LCS database accounts
b.    Use .database.windows.net to connect to database


3.    Create a new SQL sign-in that the developer can use. This step lets the system administrator maintain the security of the sandbox environment. The developer will have access to one database for only a limited time. Use the following code to create the new SQL sign-in.

CREATE USER devtempuser WITH PASSWORD = 'pass@word1'
EXEC sp_addrolemember 'db_owner', 'devtempuser'

4.    Stop following services in development box
a.     IIS or world wide web publishing service development box
b.    Microsoft Dynamics 365 unified Operations: Batch Management service

5.    Go to J:\AosService\WebRoot\web.config.
6.    Save a copy of the original web.config file, so that you can switch back later. I copied file in the same directory and renamed the web.config to webDev.config and copied one to web.config
7.    Edit the following section in the web.config file.
Before your changes
<add key="DataAccess.Database" value="AxDB" />
<add key="DataAccess.DbServer" value="devDbServerName" />
<add key="DataAccess.SqlPwd" value="password" />
<add key="DataAccess.SqlUser" value="axdbadmin" />
After your changes
<add key="DataAccess.Database" value="sandboxdatabaseServerName" />
<add key="DataAccess.DbServer" value=" sandboxdbName.database.windows.net" />
<add key="DataAccess.SqlPwd" value="P@ssw0rd" />
<add key="DataAccess.SqlUser" value="devtempuser" />

8.    Start IIS or world wide web publishing service
9.    Do not start batch service otherwise your batch jobs of development box will start writing into UAT environment. Be careful with this step!!!
10.  Now, connect to your development box from browser. Oops!!! It does not connect and throw an error. Don’t worry let’s jump into event log and see what’s in there



Okay; so it is an access issue and here is the resolution for it.

11.  Execute the following command against Master database in UAT database server. IP address you get from the event viewer.

exec sp_set_firewall_rule N'PPDEV01', '13.70.85.22', '13.70.85.22'



Note: Restart IIS and make sure application pool is started

12.  Connect to development URL again from browser and this time it works. You can now access UAT database (all legal entities etc.)
13.  Restart or your start your VS in development box and attach to Process w3wp.exe to troubleshoot the issue(s)

Done with your debugging and got the resolution J

14.  Now it is time to remove devtempuser from UAT database, this prevents having the permanent access to the sandbox database. Right-click on the devtempuser user under Sabndoxdatabase | Security | Users and delete it.

15.  Stop IIS.

16.  Revert changes from the web.config file or simply delete the copied one and rename the original one from WebDev to Web.

17.  Start IIS.

18.  Start batch service 

19.  Connect to development environment URL and make sure it is connected to development database.

Reference: 
https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/dev-tools/debugx-issue-against-copy-of-production

Monday, November 27, 2017

Read excel through X++ in D365FO




Sample code to read an excel file, all it need file stream as a parameter.


public boolean importFromExcelfiles(System.IO.Stream _stream)
{
   OfficeOpenXml.ExcelWorksheet        worksheet;
   OfficeOpenXml.ExcelRange            cells;
   OfficeOpenXml.ExcelPackage          package = new OfficeOpenXml.ExcelPackage(_stream);
       
   int totalRows,totalCells,rowCounter,cellCounter;

   if(package)
   {
      worksheet       = package.get_Workbook().get_Worksheets().get_Item(1);
      cells           = worksheet.Cells;
      totalRows       = worksheet.Dimension.End.Row ;
      totalCells      = worksheet.Dimension.End.Column;

      for (rowCounter = 2; rowCounter<= totalRows; rowCounter++)
      {
          for (cellCounter=1; cellCounter<=totalCells; cellCounter++)
          {
              //Do something with the values
              info(cells.get_Item(rowCounter, cellCounter).value);
          }
      }
   }

   return true;
}

This method can be called like this;

FileUploadTemporaryStorageResult    fileUploadResult;

fileUploadResult = FileUploadControl.getFileUploadResult();

public void importFromFile()
{
    if(fileUploadResult)
    {
        using(System.IO.Stream stream  = fileUploadResult.openResult())
        {
            Filename    filename;

            if(stream)
            {
                try
                {
                    filename = fileUploadResult.getFileName();

                    if(this.importFromExcelfiles(stream))
                    {
                        info(strFmt("File %1 has been imported successfully", filename));
                    }
                }
                catch(Exception::Error)
                {
                    warning("File import failure");
                }
            }
        }
    }

}

Wednesday, July 5, 2017

D365FO - Method wrapping and chain of command

Another most awaiting Extensibility feature (Chain of Command) is going to come with one of the next platform updates. 

This enables you to call/use protected members and methods without making them hookable and using pre/post event handlers. 



More details are here https://blogs.msdn.microsoft.com/mfp/2017/07/04/extensible-x-chain-of-command/ and also here https://roadmap.dynamics.com/?i=296a1c89-ce4e-e711-80c0-00155d2433a1#.WVw1llbSw-M.linkedin

Stay tuned on above road map site to find more on this feature.

Thursday, June 8, 2017

D365O - How to get current worker through X++

The current user or worker could be retrieved through following code since AX 2012

DirPersonUser::currentWorker()

However, In Dynamics 365 for operation this has refactored to;

HcmWorkerLookup::currentWorker()

Saturday, April 15, 2017

AX 2012 : Remove an XML node through X++

Following code snippet may help you to remove an XML node from an XML message string.


private str removeXMLTag(str xml)
{
    XmlDocument         doc = new XmlDocument();
    XmlElement          nodeScript;
    XmlNode             parentNode, childNode;
    XmlNodeList         xmlScriptList,
                        parentNodeList,
                        childNodeList;

    int                 i,j;

    doc.loadXml(xml);

    // Get the root element and its child nodes
    nodeScript = doc.getNamedElement("SalesOrder");
    xmlScriptList = nodeScript.childNodes();

    for(i=0; i < xmlScriptList.length(); i++)
    {
        parentNode = xmlScriptList.item(i);
        childNodeList = parentNode.childNodes();

        for (j=0; j < childNodeList.length(); j++)
        {
            childNode = childNodeList.item(j);
            if (childNode.selectSingleNode("Notes"))
            {
                parentNode.removeChild(childNode);
            }
        }
    }

    return doc.outerXml();
}

This will remove DocuRef node along with its child nodes. 

Original XML message

<?xml version="1.0" encoding="utf-8"?>                            
<SalesOrder xmlns = "http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">                                        
<DocuRef class = "entity">
        <Notes>Business Name</Notes>
</DocuRef>

</SalesOrder>

XML message after node being removed

<?xml version="1.0" encoding="utf-8"?>                            
<SalesOrder xmlns = "http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">                                  
</SalesOrder>