Tuesday, July 24, 2018

How to consume JSON Service(WebAPI) using POST method in Dynamics 365 FO


With the increasing scope of Microsoft Dynamics 365 Finance and Operations in the ERP Industry an efficient requirement is to perform its integration  with other applications.

One basic example is to perform an Integration with a JSON REST Service through a published WebAPI.

In the below example I have done the integration with Dynamics CRM where I am sending some values to CRM from Operations :-

The Code goes like this :-


    int                             find;
    real                           inventOnHandQtyval;
    str                             url,aosUri,activeDirectoryTenant;
    str                             activeDirectoryClientAppId;
    str                             activeDirectoryClientAppSecret,json;
    str                             postData,activeDirectoryResource;
    str                             aadClientAppSecret,oAuthHeader;
    str                             prdGUIDCode,prodnum;
    str                             returnValue,jsonString,jsondszstr;

    System.Net.HttpWebRequest       request;
    System.Net.HttpWebResponse      response;
    System.Byte[]                   byteArray;
    System.IO.Stream                dataStream;
    System.IO.StreamReader          streamRead;
    System.IO.StreamWriter          streamWrite;
    System.Net.ServicePoint         servicePoint;
    System.Net.ServicePointManager  servicePointmgr;
    System.Net.HttpVersion          version;
    System.Web.Script.Serialization.JavaScriptSerializer jsonSerializer;
    CLRObject                       clrObj;
    Newtonsoft.Json.JsonReader      reader;
    Newtonsoft.Json.Linq.JObject    prod;

    System.Text.Encoding            utf8;
    System.Exception                ex;
    Counter                         countCounter;
    Object                          obj;
    Map                             data;
    EcoResProduct                   ecoresproductfetch;
    EcoResProductTranslation        ecoresproductTranslation;
    InventTableModule               inventTableModule;




    try
    {
        InventTable     inventtable = sender as InventTable;

        System.Net.WebHeaderCollection  headers = new System.Net.WebHeaderCollection();
        var jsonSerializerobj = new  System.Web.Script.Serialization.JavaScriptSerializer();
        prod = new Newtonsoft.Json.Linq.JObject();
        inventOnHandQtyval = InventOnhand::newItemId(inventtable.ItemId).availPhysical();
        select inventTableModule where inventTableModule.ItemId==inventtable.ItemId;
        prod.Add("name",inventtable.itemName());
        prod.Add("productnumber",inventtable.ItemId);
        prod.Add("defaultuomscheduleid@odata.bind","/uomschedules(7F6F7338-1D80-4E90-9110-A70897C73834)");
        prod.Add("defaultuomid@odata.bind","/uoms(68A2E342-E1CA-4CC2-B430-C05057BCE7BC)");
        prod.Add("currentcost",0.00);
        prod.Add("description",inventtable.itemName());
        prod.Add("msdyn_fieldserviceproducttype",690970000);


        json=Newtonsoft.Json.JsonConvert::SerializeObject(prod);

        System.IO.MemoryStream mem = new System.IO.MemoryStream();



        new InteropPermission(InteropKind::ClrInterop).assert();



        headers = new System.Net.WebHeaderCollection();

        url = "https://abc.crm4.dynamics.com/api/data/v8.1/details";

        clrObj = System.Net.WebRequest::Create(url);

        aosUri = "https://login.windows.net/abcd1234/oauth2/authorize?";

        activeDirectoryTenant = "https://login.microsoftonline.com/abcd134/oauth2/token";

        activeDirectoryClientAppId = "xyz124";



        activeDirectoryResource = "https://abc.crm4.dynamics.com";

        Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authenticationContext =
                                new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(activeDirectoryTenant);



        var userCredential = new  Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential("abc@xyz.onmicrosoft.com", "abc@1234");

        Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult authenticationResult =
            authenticationContext.AcquireTokenAsync(activeDirectoryResource, activeDirectoryClientAppId, userCredential).Result;


        headers.Add("Authorization", authenticationResult.CreateAuthorizationHeader());

        headers.Add("Prefer", "return=representation");
        request = clrObj;

        request.Headers=headers;

        utf8 = System.Text.Encoding::get_UTF8();
        byteArray = utf8.GetBytes(json);
        request.set_Method("POST");
        request.set_KeepAlive(true);

        request.ContentType="application/json";

        request.set_ContentLength(byteArray.Length);







        servicePoint = request.get_ServicePoint();

        System.Net.ServicePointManager::set_Expect100Continue(false);

        System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12);



        dataStream = request.GetRequestStream();

        dataStream.Write(byteArray, 0, byteArray.get_Length());

        response = request.GetResponse();



            dataStream = response.GetResponseStream();


            streamRead = new System.IO.StreamReader(dataStream);

            jsonString = streamRead.ReadToEnd();



            data=RetailCommonWebAPI::getMapFromJsonString(jsonString);

            prdGUIDCode = data.lookup("productid");

            prodnum = data.lookup("productnumber");         

    }

    catch(Exception::CLRError)
    {
        ex = CLRInterop::getLastException().GetBaseException();
        error(ex.get_Message());
    }





    dataStream.Close();

    response.Close();

Monday, April 30, 2018

How to configure Visual Studio for development in Dynamics 365 FO

A very important step is to configure Visual Studio for the development purpose. A properly configured IDE can enhance your development skills avoiding any time consuming prospects.


After you have downloaded the VM from Life Cycle Services :-


1) Mount the VM on either HyperV or VirtualBox whichever suits your requirement.

2) Login into the machine by using the standard password :- pass@word1

3) On the desktop you will find an icon of Admin Provisioning Tool such as below :-

4) Open this tool and enter your Office 365 subscription address and click Submit :-



5) Once done go to All Programs-->Visual Studio 2015-->Right click-->Run as Administrator











6) Once Visual Studio opens go to Dynamics 365 Menu and select Options then select Dynamics 365  Category


















7) As we can see that as per the standards of Microsoft Best Practice all the options are already enabled

8) Now only we have enable some options for the smooth and well categorized functioning of our future projects. So under Dynamics 365 section go to Projects subcategory.


9) As you can see that we have selected the first and last option its not necessary to select these options before starting your development but if we do it will make our job whole lot easier and organized and selecting the Synchronize database on build for newly created project will help us to avoid extra efforts for Full Database Synchronization every time we create any Data Dictionary Object such as Extended Data Types or Tables.


10) That's it now we are ready to get started with Dynamics 365 Finance and Operations customizations.

Tuesday, April 24, 2018

How to Post Sales Order Invoice through X++ in Dynamics 365 FO


A very common requirement these days is to automate the Invoice Posting for Sales Orders.


Follow the below mentioned steps :-


Step 1) Add a new Runnable class in your Project














Step 2) Write the following code :-


 SalesFormLetter         letter      = SalesFormLetter::construct(DocumentStatus::Invoice);
 SalesTable                   salestbl;

salestbl=SalesTable::find('000814');
 
 
letter.update(salestbl,SystemDateGet(),SalesUpdate::All,AccountOrder::None,false,true);

 info('Success');


Wednesday, February 21, 2018

Important Ebooks for Microsoft Dynamics 365 FO

Hi folks,


Microsoft Dynamics 365 Finance and Operations is shifting to a totally new paradigm  and we need to be aware of the patterns and trends included in this massive shift.


So here are few books for all of you which might help you a little.

Click on the below links or copy and paste it in your address bar.


1) Implementing Microsoft Dynamics 365 Finance and Operations

    https://drive.google.com/file/d/1pCYbQCxVE6z_r9mmR9NIl794sJxP_u43/view?usp=sharing


2) Microsoft Dynamics 365 for Finance and Operations Development Cookbook

    https://drive.google.com/file/d/1TuFa0SJYq7kxbH6cYW7pCNQ1_OS7HsON/view?usp=sharing


3) Extending Microsoft Dynamics 365 Finance and Operations

    https://drive.google.com/file/d/15hbtwl5B9ND2CQ9TBwVSw3NVsDStGEgQ/view?usp=sharing



   Happy Learning!!!!

Monday, February 12, 2018

How to access Table Buffer through Web Url in D365 FO


Traditionally the procedure of accessing a Table Buffer was very simple but as the evolution happened from Standard AX 2012 to Dynamics 365 Operations various ways came into existence such as accessing a Table Browser from Web URL.


Technically even here you can go to Application Explorer and access your desired Table Browser but sometimes it shows an error like given below in Point No 2.


1) Accessing a Table Browser now















2) Error is shown :-














So the simple solution is accessing the Table Browser by writing this url in the address bar and then lets see the result :-


https://usnconeboxax1aos.cloud.onebox.dynamics.com/?mi=SysTableBrowser&prt=initial&cmp=USMF&tablename=MyTable&limitednav=true



Et Voila!!!!











Sunday, February 11, 2018

How to import Data From Excel into an AX Table using x++ in D365 FO

A very basic functionality needed nowadays to import data from Microsoft Excel but the way X++ has been redesigned including all the new functions for immense operations.
Now the SysExcelApplication and all other classes for Excel with "Sys" prefix is not used now.

Let's see how it gets worked out now :-



Step 1 :-  In your Dynamics 365 Operations Project. Add a new Class :-





Step 2 :-  Name your class























Step 3 :- Write the following code :-


class ImportExcelData extends RunBase
{
    str fileUrl;
    MyTable     myTb;
 
    public Object dialog()
    {
     
        Object                  dialog;

        FormBuildButtonControl    buttonControl;

        DialogGroup                    dlgGroup;

        FormBuildGroupControl    buttonGroup;

     

        dialog = super();

           

        dlgGroup       = dialog.addGroup('');

        buttonGroup    = dialog.formBuildDesign().control(dlgGroup.formBuildGroup().id());

        buttonControl  = buttonGroup.addControl(FormControlType::Button, 'Upload');

        buttonControl.text("Upload file");



        buttonControl.registerOverrideMethod(methodStr(FormButtonControl, clicked),

                                        methodStr(ImportExcelData , uploadClickedEvent),

                                        this);

        return dialog;
    }

    private void uploadClickedEvent(FormButtonControl _formButtonControl)

    {
     
        FileUploadTemporaryStorageResult result = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

        if (result && result.getUploadStatus())

        {

            result.getFileContentType();

            fileUrl = result.getDownloadUrl();

        }

    }

    public container  readExcelData(System.IO.Stream      _stream)

    {
        container conRow,conData;
        OfficeOpenXml.ExcelWorksheet _worksheet;

        OfficeOpenXml.ExcelPackage package = new OfficeOpenXml.ExcelPackage(_stream);

        int iRowCount,iCellCount;

        anytype        anyData;

     

        try

        {

            if(package)

            {

                _worksheet = package.get_Workbook().get_Worksheets().Copy("Sheet1","ABC");

                var cells = _worksheet.get_Cells();

                iRowCount = _worksheet.get_Dimension().get_End().get_Row();



                iCellCount = _worksheet.get_Dimension().get_End().get_Column();



                for (int i=2;i<=iRowCount;i++)

                {

                    conRow = conNull();

                    for (int j=1;j<=iCellCount;j++)

                    {

                        anyData= cells.get_Item(i, j).get_Value();

                        if(!anyData && j ==1)

                           break;



                        if(anyData)

                           conRow += anyData;

                        else

                           conRow += "";

                     

                    }

                    if(conRow)

                    {

                        conRow += iRowCount;

                        conData = conIns(conData,i,conRow);

                    }

                 
                    myTb.Field1=cells.get_Item(i, 1).get_Value();
                    myTb.Field2=cells.get_Item(i, 2).get_Value();
                    myTb.Field3=cells.get_Item(i, 3).get_Value();
                    myTb.Field4=cells.get_Item(i, 4).get_Value();
                    myTb.Field5=cells.get_Item(i, 5).get_Value();
                    myTb.insert();
                 
                 
                     

                }
             
         
             

            }

         

        }

        catch (Exception::CLRError)

        {

            throw error("@SYS135884");

        }

        return conData;

    }

    Public  void   run()

    {

        System.Byte[] byteArray;

        System.IO.Stream     stream;

        try

        {

            stream = File::UseFileFromURL(fileUrl);

            this. readExcelData(stream);

            //info("Done");

        }

        catch(Exception::Error)

        {

            info(strFmt("%1 %2",Exception::Error,fileUrl));

        }

    }

    public static void main(Args args)
    {
        ImportExcelData objimport=new ImportExcelData();

        if(objimport.prompt())
        {
            objimport.run();
        }
    }

}

Demystifying the SysOperation Framework in D365 F&O: Building Scalable and Maintainable Batch Jobs

 If you've been developing in Dynamics 365 Finance and Operations for a while, chances are you've either worked with or heard about ...