Saturday, March 4, 2017

Common data model entities - overview

The Common Data Service is a cloud base business application platform. This platform provides a rich and productive development platform though Common Data Model which is a store of common business entities like customers, vendors, purchase orders, products and many more.
There are integration capabilities for importing data from multiple sources like Dynamics 365 for sales, Dynamics 365 for Operations, any other business application or data source. We can also create our own new custom entities and establish relation with existing entities. 
 
Common data model also act as a a platform for powerusers to leverage the tools like Power BI, Powerapps and Flow to Meausre, Act and Automate the business data. These are the three key objectives on which the whole new Microsoft innovation is based on.   
 
 
Lets do a quick walkthrough on creating a new entity in common data model and then publishing data in this entity from excel followed by exporting this data from CDM.
 
When you login to powerapps portal you will need to first create a new environment to access the CDM entities. To know more about environment refer to working with environments .
 
To create your own enviroment in powerapps portal click on the "get started" button
 
 
Click on create new environment and give a name and select a region. It takes around a minute to setup the new environemnt and once it is done you can see that your current environment is set to the one which you created.
 
 
Now we can view the available entities from the Entities button on the left hand pane . CDM ships around 60+ entities. The details of all the entities and there relationship can be found in the whitepaper available at CDMEntityReference document
 
 
To create a new entity click on "New entity" button and give it a name. Let's call it "Approved vendors" and enter a  description and click next. You will observe it is a very nice self guided experience.
 
 
 
 
 
 
Once the entity is created, it is visible in the list of entities.
 
Lets add new fields in this entity. To do this, click on "Add field" and enter the details. Let's call it Vendor approval code.
 
 
 
We can also specify additional properties as highlighted below.
 
 
Once the field is created, it is visible in the list of fields in the entity.
  
 
 
Now let's create a new field which is linked to the existing vendor entities. To do that we can go to relationship tab.
 
 
Add a new relation with the existing vendor entity.
 
 
 
 
Now you can see that the vendor ID is visible on the entity fields. The type of this field is a lookup due to the relationship created for it.
 
 
At this stage as we have only created the entity schema, there is no data in the entity. This can be seen from the "Data" group as shown below
 
 
Now we can open this entity in excel by clicking on the "open in excel" button. The powerapp office add-in will also load.
 
 
Here we can start entering the data. You will see that the add-in automatically pulls the current data in the related field of vendor ID.
 
 
After entering the data we can publish it to CDM by using the publish button.
 
 
 Once the data is published in CDM we can see the notification in the add in.
 
 
Lets go back to CDM portal and view the data in the entity.
 
 
Upon refreshing, the data we published from Excel can be seen.
 
 
We can also export data of  the current entity by clicking on export data button.
 
 
Once the data is exported you can download the package
 
 
In the package you get a csv file and 2 XML files as below.
 
 
Data exported in the csv file as shown below.
 
 
As you see, Microsoft has done an amazing job in making the whole experience self guided so that the CDM platform can be leverged by a large number of professionals and not just developers.
 

Wednesday, February 22, 2017

X++ code to read CSV files in Dynamics 365 for operations


Reading data from csv files is a very common development requirement for X++ developers. In Dynamics 365 for operations there are some interesting concepts, as opposed to AX2012. The application runs on cloud and the client is in web. In such scenarios the way to read files from local system is a 2 step process.
Step 1: Upload the file from local machine to Microsoft cloud (Azure) storage space called as Azure blob.
Step 2: Read the file from Azure blob to retrieve the data.
 
Microsoft has done an excellent job in creating out of the box classes to run this logic. So we are not required to re-invent the wheel and can leverage the existing API's. The below X++ code can be used to read a CSV file:

 
 
The standard API's are used here do the required magic. I have tried to breakdown the functionality of the calls.
Step 1 is done by the below command where the file is uploaded from local machine to azure blob


 
Step 2 is done by opening the IO stream from the Blob and reading it from the IO class

 

Rest of the job is almost similar to AX2012 pattern.
 
To test the job we create a sample csv file

 
 
On running the job a file picker will be shown, where you can browse the file.



 
The progress of uploading it to cloud space is shown in the progress bar


 
 
 
 
Infolog is shown with the data on the file


 
 

Worth mentioning that there are various other IO classes, provided out of the box which have the below associations
 

 
 
The file upload classes have different strategies and the below classes are available out of the box. For more information refer to nice articles mentioned in the references:


To quickly reuse the code here it goes

class RGReadSample
{       
    ///
    /// Runs the class with the specified arguments.
    ///

    /// The specified arguments.
    public static void main(Args _args)
    {       
        AsciiStreamIo                                   file;
        Array                                           fileLines;
        FileUploadTemporaryStorageResult                fileUpload;

        fileUpload = File::GetFileFromUser() as FileUploadTemporaryStorageResult;
        file = AsciiStreamIo::constructForRead(fileUpload.openResult());
        if (file)
        {
            if (file.status())
            {
                throw error("@SYS52680");
            }

            file.inFieldDelimiter(',');
            file.inRecordDelimiter('\r\n');
        }

        container record;
        while (!file.status())
        {
            record = file.read();

            if (conLen(record))
            {
                info(strFmt("%1 - %2",conPeek(record,1),conPeek(record,2)));
            }
        }

        info("done");
    }

}

Feel free to comment on any feedback/suggestions in case I have missed any important part of this framework  but this code works nicely on reading csv files. Thanks for reading the blog and have a great day.

More references:
https://ax.help.dynamics.com/en/wiki/file-upload-control/
http://dev.goshoom.net/en/2016/03/file-upload-and-download-in-ax-7/

 

Tuesday, January 24, 2017

Extension methods in X++

In Dynamics 365 for operations (D3FO), one of the main emphasis of Microsoft is to develop extensions and avoid doing any customization to standard objects shipped by Microsoft. A new X++ feature called  Extension Methods is introduced to enable developers to create new methods for standard AX objects without customising them.

Extension methods comes from C# where they enable you to "add" methods to existing types without modifying the original type. These are a special kind of static method which are called as if they were instance methods on the extended type.  MSDN reference Extension methods in C#

In context of AX, extension methods have similar characterstics. Lets take a very common exmaple. If we have to create a new method on a  customer table which returns the customer name and telephone number as one concatened string. Normally we would create a new method on a standard CustTable object which will return the required result somehting like below.




Now there is nothing wrong in such method till AX2012 version but in the new AX (D3FO) doing this will fall under the umbrella of customising the standard AX object. This is not recommended in D3FO as it comes with lot more pains on managing such developments when installing new updates and upgrading the system.

Now in order to do this as an extension we will need to do the following:

1. Create a new static class. The class name should end with suffix _Extension
2. Creat a new static method which returns the type of data you want.
3. In this method definition the first parameter will be the CustTable object as shown below.


Now we can use this method as a table method when writing code. See below the intellisense will show the new method as a list of available method for that object.



By taking the above approach we can develop new methods and reference them via standard objects in our code without customising the objects. This is in alignment with Microsoft's recommendations for development via extensions.
 

Sunday, May 15, 2016

Using X++ Delegates in the new Dynamics AX (aka AX 7)


In this post lets walk through an example on how we can use delegates in the new AX to develop customizations.

Quick summary of delegates: X++ delegates expose the publisher - subscriber pattern where a delegate defines a clear contract in a publisher class. It is a great way of encapsulating a piece of code. Delegates were introduced in AX 2012 couple of years back. With the new AX release delegates are the recommended way for customizing standard AX classes.

Let’s jump into action and customise standard AX sales order confirmation process. To keep it simple we will the change value of a field in confirmation journal table. The idea here is how to develop delegates and call them.

Confirmation journal header data is stored in CustConfirmJour table and it is initialised in the below class method during the sales confirmation posting process. Let’s modify it using delegates.



First we create a new delegate method in this class. This serves the purpose of defining a contract between the delegate instance and the delegate handler. There is no business logic inside the delegate method. Also notice that the delegates have return type as Void. In order to access the result value we have to pass EventHandlerResult object as a parameter.
 
 

 

 
Now we modify the actual method, declare the Event handler result object and call the delegate with the parameters in the method which we need to customise . The only customization in this method is 2 lines of code as highlighted below:
 
 

 
The class structure looks as below:



 Now we create the event handler method and this is where MS has done really nice stuff in moving the AX development environment to Visual Studio. Right click on the delegate method and copy the handler method definition.




Create a new class which will be used to subscribe to the delegate. So we create a new class, let call is salesConfirmJournalExt and paste the copied clipboard text
 
 

 


The delegate handler definition is automatically added with the below information:
 
 

Now we can add our custom code in this method. I just changed the purchase order field value and added some Infolog. Note that I am actually not returning anything in this method and not using the eventHandlerResult object really.


 So we are done. The see it wokring let's build the solution and confirm a sales order.



During the process the  Infolog messages we added in the delegate handler method are shown


The confirmation journal has the custom text appended to it in the field we used in our new class method.
 
 

Microsoft strongly recommends to use Delegates for customization due to all the good reasons of having minimum code changes in standard product. So try to use delegates to have a cleaner and manageable solutions.

Feel free to share your feedback.  Below are some good online references on Delegates:
 
https://ax.help.dynamics.com/en/wiki/delegates-for-migration/

https://blogs.msdn.microsoft.com/x/2011/08/02/how-to-use-x-delegates-in-dynamics-ax-2012/

https://en.wikipedia.org/wiki/Observer_pattern


 

Tuesday, November 3, 2015

AX2012 : Tip when using date effective tables as a reference data source

Hi Friends,
Reference data sources is a powerful feature in AX 2012. A reference data source enables you to add the replacement fields for a surrogate foreign key replacement to a form design. It is used extensively on standard AX forms.

It becomes more interesting, when we reference date effective tables . In such scenarios we need to perform some steps to make sure that the date effective tables are queried correctly.

We can find a good example on sales table form. Let us have a look:

1. The date effective data sources are added under the sales table datasoure node as reference data sources.


 
2. The below piece of code on form init() method to check the validity:
 
 
 
3. The below piece of code is added on sales table datasource  >> init() method, to set the valid time state range criterions:
 


If you doing some development task and plan to add date effective tables as reference data source, then make sure to model it the same way. Not doing so will cause an issue that the expired records will display a "Unknown" value in the reference data source record. A similar problem has been reported on Microsoft dynamics AX community forum. Detail can be found at this link. The below image reference is taken from the link:


Whitepaper to use date effective framework can be downloaded from here, however this information is not mentioned there.

Thanks for reading the blog.
 

Monday, September 7, 2015

AX2012 : Adding text translations to entities using X++ [Technical walk-through]

Hi Friends,
Microsoft dynamics AX provides text translation possibilities on some standard entities like products, ledger accounts, financial dimension and few more. Text translations are displayed on documents where a language code is applied for example packing slips and invoices. Also, when the system language for the user corresponds to the translations, the translations are displayed in Enterprise Portal for Microsoft Dynamics AX.


A simple way to store the translations is to open the translations form , select the translation language and then save the translated text. For example to store translations for a product name, open the translations screen from product list page as shown below :



Select the language from the drop down which comes on clicking on the + button


Enter and save the translated text.


There can be instances where you want to extend this capability to other existing or new entities in the system to make your solution flexible and rich. From technical point of there is a standard AX class called SysTransalationHelper which provides capabilities to achieve this. In order to understand how we can use this class, let's do a quick walk-through and extend the standard AX's Questionnaire entity to have ability to set-up text translation.

The standard AX form for questions can be found at Home >> Common >> Questionnaires >> Design >> Questions




PS --> For demonstration purpose, I am just creating the minimum required methods and objects. In real time make sure you follow development best practise recommendations. I will be prefixing new objects with DEM_ to distinguish from standard AX objects.

Step 1 : Create a new table. I called it DEM_KMQuestionTranslation. Now add 2 foreign key relations as shown below, one relation with KMQuestion table and another with LanguageTable. KMQuestion table stores the Questions information and the Language table is used to store list of all languages available on the system. Additionally add a Description field. The table structure should look as shown below:


Add the below 2 methods in this table:

createOrUpdateTransalation() --> This method is used to create or update a question translation record. The implementation is quite straightforward. Refer to standard AX method \Data Dictionary\Tables\EcoResProductTranslation\Methods\createOrUpdateTranslation() to view a similar implementation.




findByQuestionLanguage() --> This method is used to find the specified record in the DEM_KMQuestionTranslation table by using the specified question language. Similar standard AX method implementation can be found at \Data Dictionary\Tables\EcoResProductTranslation\Methods\findByProductLanguage()





Step 2: Now we need to add below line of code in standard AX KMQuestion table insert() method. This is to create a default translation record in our new table whenever a new question record is created in the system.




Step 3 : Now we need to create a new class. Let's call this class DEM_QuestionnairesTranslationHelper  and add couple of methods as shown below:

Class declaration , declare two variables as shown below


Create parm methods to get and set the values





Now here comes the interesting part. Create a method to construct a new object of SysTransalationHelper class and use the tablenum of the main entity table and the new table which is storing the language translation details as shown below


Secondly create a method to launch the translation detail form. To do this we need to create a method as shown below which uses SysTranslationHelper class object as a parameter and calls it’s launch translation form method:


The last method required in this class is to instantiate the class . To do this create a new method as shown below:


Step 4 : Now we create a new menu item for this class



Step 5 : Plug this menu item on the questions form as shown below:


We are done and ready to test drive this. Now on opening the Questions form we can see the transalations button . When we click it,system launches the translation helper form where we can store our translated texts using all standard AX functions as shown below:



You can also download the XPO from  HERE to have quick access to code.

So in this post we saw how we can make our solutions flexible and more intuitive by adding the translation texts capabilities to any existing or new entities.

Thanks for reading the blog.