Tuesday, 3 January 2023

Integration between D365FO (AX) and D365CE using API x++

Hello Folks,

I am going to explain customer Asynchronous integration between D365 Finance and operation(F&O) and D365 Customer engagement (CE).

When new D365 F&O customer created or updated or deleted, same information will be available in CE. Every time new token required to access CE.

Prerequisites

  • CE app need to be registered in Azure active directory

Use below snippet of the code and trigger below methods in D365 F&O customer insert/update/delete methods.

using Microsoft.IdentityModel.Clients.ActiveDirectory;

 

class ENCCECustomerIntegration

{

    CustTable   custTable;

    str         url                 = "https://dev.crm.dynamics.com/api/data/v9.2"//CE URL 

    str         aadTenant           = "https://login.microsoftonline.com/b81812e7-dfea-42ed-872e-ed8cf3b20e9f/oauth2/v2.0/token";

    str         aadResource         = "https://dev.crm.dynamics.com";

    str         aadClientAppId      = "";

    str         aadClientAppSecret  = "";

    str         contentType         = 'application/json';

 

    public CustTable parmCustTable(CustTable _custTable = custTable)

    {

        custTable = _custTable;

        return custTable;

    }

 

    public str getAccessToken()

    {

        AuthenticationContext authenticationContext = new AuthenticationContext(aadTenant);       

        var creadential = new ClientCredential(aadClientAppId, aadClientAppSecret);

        AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync(aadResource, creadential).Result;

        return authenticationResult.AccessToken;

    }

 

    public RetailWebResponse createCustomer()

    {

        System.IO.StringWriter          stringWriter;

        Newtonsoft.Json.JsonTextWriter  jsonWriter;

        RetailCommonWebAPI              webApi;

        RetailWebResponse               response;

        str                             data;

        str                             postURL;

        str                             header;

        str                             rawResponse;

 

        postURL     = url + "/accounts?$select=cssp_firstname,cssp_lastname,accountnumber,emailaddress1";

 

        //Get access token

        header      = strFmt('Authorization: Bearer %1', this.getAccessToken());

 

        //Format json data

        stringWriter       = new System.IO.StringWriter();

        jsonWriter         = new Newtonsoft.Json.JsonTextWriter(stringWriter);

        DirPersonName   dirPersonName   = DirPersonName::find(custTable.Party);

 

        jsonWriter.WriteStartObject();

        jsonWriter.WritePropertyName("cssp_firstname");

        jsonWriter.WriteValue(dirPersonName.FirstName);

        jsonWriter.WritePropertyName("cssp_lastname");

        jsonWriter.WriteValue(dirPersonName.LastName);

        jsonWriter.WritePropertyName("accountnumber");

        jsonWriter.WriteValue(custTable.AccountNum);

        jsonWriter.WritePropertyName("emailaddress1");

        jsonWriter.WriteValue(custTable.email());

        jsonWriter.WriteEndObject();

 

        data = stringWriter.ToString();

 

        //Call API

        webApi      = RetailCommonWebAPI::construct();

        response    = webApi.makePostRequest(postURL, data, header, contentType);

        rawResponse = response.parmData();

 

        Info("Customer created in the portal.");

 

        return response;

    }

 

    public RetailWebResponse updateCustomer()

    {

        System.IO.StringWriter          stringWriter;

        Newtonsoft.Json.JsonTextWriter  jsonWriter;

        RetailCommonWebAPI              webApi;

        RetailWebResponse               response;

        str                             data;

        str                             patchURL;

        str                             header;

        str                             rawResponse;

 

        patchURL = url + "/accounts(accountnumber='";

        patchURL = patchURL + custTable.AccountNum + "')?$select=cssp_firstname,cssp_lastname,emailaddress1";

 

        //Get access token

        header      = strFmt('Authorization: Bearer %1', this.getAccessToken());

 

        //Format json data

        stringWriter       = new System.IO.StringWriter();

        jsonWriter         = new Newtonsoft.Json.JsonTextWriter(stringWriter);

        DirPersonName   dirPersonName   = DirPersonName::find(custTable.Party);

 

        jsonWriter.WriteStartObject();

        jsonWriter.WritePropertyName("cssp_firstname");

        jsonWriter.WriteValue(dirPersonName.FirstName);

        jsonWriter.WritePropertyName("cssp_lastname");

        jsonWriter.WriteValue(dirPersonName.LastName);

        jsonWriter.WritePropertyName("emailaddress1");

        jsonWriter.WriteValue(custTable.email());

        jsonWriter.WriteEndObject();

 

        data = stringWriter.ToString();

 

        //Call API

        RetailWebRequest request = RetailWebRequest::newUrl(patchURL);

        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

 

        request.parmMethod("PATCH");

        request.parmHeader(header);

        request.parmContentType(contentType);

        if (strLen(data) > 0)

        {

            request.setContentBytes(encoding.GetBytes(data));

        }

 

        webApi      = RetailCommonWebAPI::construct();

        response = webApi.getResponse(request);

 

        Info("Customer updated in the portal.");

 

        return response;

    }

 

    public RetailWebResponse deleteCustomer()

    {

        System.IO.StringWriter          stringWriter;

        Newtonsoft.Json.JsonTextWriter  jsonWriter;

        RetailCommonWebAPI              webApi;

        RetailWebResponse               response;

        str                             data;

        str                             deleteURL;

        str                             header;

        str                             rawResponse;

 

        deleteURL = url + "/accounts(accountnumber='";

        deleteURL = deleteURL + custTable.AccountNum + "')?$select=cssp_firstname,cssp_lastname,emailaddress1,statecode";

 

        //Get access token

        header  = strFmt('Authorization: Bearer %1', this.getAccessToken());

 

        //Format json data

        stringWriter       = new System.IO.StringWriter();

        jsonWriter         = new Newtonsoft.Json.JsonTextWriter(stringWriter);

        DirPersonName   dirPersonName   = DirPersonName::find(custTable.Party);

 

        jsonWriter.WriteStartObject();

        jsonWriter.WritePropertyName("cssp_firstname");

        jsonWriter.WriteValue(dirPersonName.FirstName);

        jsonWriter.WritePropertyName("cssp_lastname");

        jsonWriter.WriteValue(dirPersonName.LastName);

        jsonWriter.WritePropertyName("emailaddress1");

        jsonWriter.WriteValue(custTable.email());

        jsonWriter.WritePropertyName("statecode");

        jsonWriter.WriteValue(1);

        jsonWriter.WriteEndObject();

 

        data = stringWriter.ToString();

 

        //Call API

        RetailWebRequest request = RetailWebRequest::newUrl(deleteURL);

        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

 

        request.parmMethod("PATCH");

        request.parmHeader(header);

        request.parmContentType(contentType);

        if (strLen(data) > 0)

        {

            request.setContentBytes(encoding.GetBytes(data));

        }

 

        webApi      = RetailCommonWebAPI::construct();

        response = webApi.getResponse(request);

 

        Info("Customer deactivated in the portal.");

 

        return response;

    }

}