Wednesday, January 24, 2024

Update environment admin

Update environment admin in d365 fo


Update environment admin in d365 fo


Prerequisite for Update environment admin in d365 fo

To Update environment admin in d365 fo, you must be a project owner in the LCS project roles.


Steps to Update environment admin in d365 fo:

In LCS, go to your project, and open your environment details page.

Select Maintain > Update environment admin.

In the dialog box that appears, select another Project Owner or Environment Admin user from your LCS project.

Select Save.

All steps are completed Update environment admin in d365 fo


Please Note:

To Update environment admin in d365 fo would cause downtime in the target finance and operations apps environment. Therefore, use this capability in the appropriate way and only after you schedule the downtime in your organization. The new administrator account must be a member of the same tenant that the environment belongs to.


Microsoft Reference:

Update the environment administrator


I hope this blog on Update environment admin in d365 fo was helpful

Tuesday, January 23, 2024

OData Dynamics 365 FO

OData in Dynamics 365 Finance and Operations


Available query options OData

1. Definition:

   - OData is a standard protocol for creating and consuming data APIs. It allows for the easy sharing and editing of data through web technologies, making it straightforward to access Dynamics 365 data from other systems, mobile apps, and web applications.


2. Use Case:

   - Integration: Easily integrates Dynamics 365 F&O with other systems or applications. For instance, it can help pull data from Dynamics into a business intelligence tool for advanced analytics.

   - Real-time Access: Provides real-time access to the data, which is essential for timely decision-making and reporting.


3. How to Create:

   - In Dynamics 365 F&O, you can expose data through OData by creating data entities. These entities represent tables or views that aggregate data from various sources within the ERP system.

   - You configure these data entities in the AOT (Application Object Tree) and specify properties that determine how the data is exposed through the OData service.


4. How to Use:

   - Consumption from External Applications: External applications can consume these OData services using standard web protocols (HTTP requests), allowing them to read or write data.

   - Querying: Supports querying using standard URL conventions. You can filter, sort, and manipulate data directly through the URL, which is quite powerful for custom applications.

Example for OData query


5. Order in which methods are called:


Method Order for OData in Dynamics 365 FO


Microsoft blog for reference:

Open Data Protocol (OData)

Friday, January 19, 2024

Business Events

In this blog of Dynamics Community 101 we will learn about Business Events in D365 FO


A mechanism for detecting and responding to important situations in the business process.

Triggering Mechanism for business events in d365 fo:

The system sends external signals when specific events occur, such as the full invoicing of a sales order or the completion of a batch job.

Applications of business events in d365 fo:

Integrations with other systems via Microsoft Power Automate or custom web services. Example: Sending alerts to users.

Design and Performance of business events in d365 fo:

Business events are designed to be minimally intrusive.(Light weight design)


Minimal Performance Impact: 

Ensures efficient operation without burdening the system.

Purpose: 

Facilitates real-time integration scenarios and automates business processes, reducing the need for extensive customization.


Path for business event:

Business event form path

Contract class 1 for business events in d365 fo:

[DataContract]

public final class LSAPIINTSPAPIOrderOrderCallBEContract extends BusinessEventsContract

{

    private str ResponseJSON;

    private str UniqueID;

    private LegalEntityDataAreaId legalEntity;


    public static LSAPIINTSPAPIOrderOrderCallBEContract newFromInventTable(LSAPIINTSPAPIOrderOrderCall _LSAPIINTSPAPIOrderOrderCall)

    {

        var contract = new LSAPIINTSPAPIOrderOrderCallBEContract();

        contract.initialize(_LSAPIINTSPAPIOrderOrderCall);

        return contract;

    }


    [DataMember('UniqueID'), BusinessEventsDataMember("UniqueID")]

    public str parmUniqueID(str _UniqueID = UniqueID)

    {

        UniqueID = _UniqueID;

        return UniqueID;

    }


    [DataMember('ResponseJSON'), BusinessEventsDataMember("ResponseJSON")]

    public str parmResponseJSON(str _ResponseJSON = ResponseJSON)

    {

        ResponseJSON = _ResponseJSON;

        return ResponseJSON;

    }


    [DataMember('LegalEntity'), BusinessEventsDataMember("@SYS315616")]

    public LegalEntityDataAreaId parmLegalEntity(LegalEntityDataAreaId _legalEntity = legalEntity)

    {

        legalEntity = _legalEntity;

        return legalEntity;

    }


    private void initialize(LSAPIINTSPAPIOrderOrderCall _LSAPIINTSPAPIOrderOrderCall)

    {

        ResponseJSON   = _LSAPIINTSPAPIOrderOrderCall.ResponseJSON;

        UniqueID       = _LSAPIINTSPAPIOrderOrderCall.UniqueID;

        legalEntity    = _LSAPIINTSPAPIOrderOrderCall.DataAreaId;

    }


}



Business Event Class 2 for business events in d365 fo:

//LSAPIINTSPAPIOrderOrderCallBusinessEvent

[BusinessEvents(classStr(LSAPIINTSPAPIOrderOrderCallBEContract),

    "LSAPIINTSPAPIOrderOrderCall data inserted",

    "This business event is triggered when a user inserts data into LSAPIINTSPAPIOrderOrderCall",

    ModuleAxapta::ProductInformationManagement)]

public class LSAPIINTSPAPIOrderOrderCallBusinessEvent extends BusinessEventsBase

{

    private LSAPIINTSPAPIOrderOrderCall LSAPIINTSPAPIOrderOrderCall;

    


    static public LSAPIINTSPAPIOrderOrderCallBusinessEvent newFromInventTable(LSAPIINTSPAPIOrderOrderCall _LSAPIINTSPAPIOrderOrderCall)

    {

        LSAPIINTSPAPIOrderOrderCallBusinessEvent businessEvent = new LSAPIINTSPAPIOrderOrderCallBusinessEvent();

        businessEvent.parmLSAPIINTSPAPIOrderOrderCall(_LSAPIINTSPAPIOrderOrderCall);

        return businessEvent;

    }


    private void new()

    {

    }


    private LSAPIINTSPAPIOrderOrderCall parmLSAPIINTSPAPIOrderOrderCall(LSAPIINTSPAPIOrderOrderCall _LSAPIINTSPAPIOrderOrderCall = LSAPIINTSPAPIOrderOrderCall)

    {

        LSAPIINTSPAPIOrderOrderCall = _LSAPIINTSPAPIOrderOrderCall;

        return LSAPIINTSPAPIOrderOrderCall;

    }


    [Wrappable(true), Replaceable(true)]

    public BusinessEventsContract buildContract()

    {

        return LSAPIINTSPAPIOrderOrderCallBEContract::newFromInventTable(LSAPIINTSPAPIOrderOrderCall);

    }


}





Now call the class in insert of the table as shown below so that the business events in d365 fo will hit the moment data is inserted in this table


public class LSAPIINTSPAPIOrderOrderCall extends common

{

    public void insert()

    {

        super();

        if(this)

        {

            LSAPIINTSPAPIOrderOrderCall LSAPIINTSPAPIOrderOrderCall;

            select * from LSAPIINTSPAPIOrderOrderCall

                where LSAPIINTSPAPIOrderOrderCall.RecId == this.RecId;

            LSAPIINTSPAPIOrderOrderCallBusinessEvent::newFromInventTable(LSAPIINTSPAPIOrderOrderCall).send();

        } 

    }

}


After building and syncing


Now for the last step to be performed for finalizing business events in d365 fo

Go to Business events and Rebuild the business event catalog

business events catalog

Best business events in d365 fo reference:


Deserialize json list

Deserialize JSON list Dynamics 365 FO

JSON:

{

    "data": [

        {

            "BuyerEmail": "6x7n35tz50m0byz@marketplace.amazon.co.uk",

            "AmazonOrderId": "204-1744774-4556347"

        },

        {

            "BuyerEmail": "hnfgtmnkrgfh3v7@marketplace.amazon.co.uk",

            "AmazonOrderId": "204-4589988-8749964"

        }

    ]

}



Class LSAPIINTSPAPIOrderOrderCallResponseDataContract:

[DataContract]

class LSAPIINTSPAPIOrderOrderCallResponseDataContract

{

    List subList;

    [DataMemberAttribute('data'),

        DataCollectionAttribute(Types::Class, classStr(LSAPIINTSPAPIOrderOrderCallResponseContract)),sysoperationdisplayorderattribute('1')]

        public List parmSubList(List _subList = subList)

    {

        subList = _subList;

        return subList;

    }

}



Class LSAPIINTSPAPIOrderOrderCallResponseContract:

[DataContract]

class LSAPIINTSPAPIOrderOrderCallResponseContract

{

    str BuyerEmail;

    str AmazonOrderId;

    [DataMemberAttribute('BuyerEmail')]

    public str parmBuyerEmail(str _BuyerEmail = BuyerEmail)

    {

        BuyerEmail = _BuyerEmail;

        return BuyerEmail;

    }

    [DataMemberAttribute('AmazonOrderId')]

    public str parmAmazonOrderId(str _AmazonOrderId = AmazonOrderId)

    {

        AmazonOrderId = _AmazonOrderId;

        return AmazonOrderId;

    }

}





Below code for deserialize:

LSAPIINTSPAPIOrderOrderCallResponse             LSAPIINTSPAPIOrderOrderCallResponseLocal;

        LSAPIINTSPAPIOrderOrderCallResponseDataContract LSAPIINTSPAPIOrderOrderCallResponseDataContract;

        List                                            listValues = new List(Types::Class);

        ListEnumerator                                  listEnumerator;

        LSAPIINTSPAPIOrderOrderCallResponseDataContract = FormJsonSerializer::deserializeObject(classNum(LSAPIINTSPAPIOrderOrderCallResponseDataContract), _record);

        listValues = LSAPIINTSPAPIOrderOrderCallResponseDataContract.parmSubList();

        listEnumerator = listValues.getEnumerator();

        while(listEnumerator.moveNext())

        {

                LSAPIINTSPAPIOrderOrderCallResponseContract _Contract = listEnumerator.current();

                LSAPIINTSPAPIOrderOrderCallResponseLocal.POAmazonOrderId        = _Contract.parmAmazonOrderId();

                LSAPIINTSPAPIOrderOrderCallResponseLocal.POBuyerInfoBuyerEmail  = _Contract.parmBuyerEmail();

                LSAPIINTSPAPIOrderOrderCallResponseLocal.insert();

        }