Continuing with our series about Business Events in Microsoft Dynamics 365 for Finance and Operations, it’s the turn to talk about the possibility of developing our own business events to be able to notify or interact with external applications in those cases that are not covered by the business events catalog.
Before creating the Business Event itself, there are some topics we must take care about:
- Business events must be durable, that is, if an external application receive a notification because an action has occurred, this notification must be reliable. A transactional design must be made to ensure this aspect.
- Business events must be targeted, avoiding sending payloads (business event content) in which the recipient has to deduce the objective of the business event.
- Business events must avoid noise, to achieve this you must try to trigger the business event at a specific point in the code to avoid excessive filtering operations.
Once these points are clear enough, we can start developing, which is today’s objective! For this specific example, we will develop a business event that is triggered when a user unblocks a customer.
The first step will be the creation of the data contract, which will conform the content of the payload that we will send abroad. To do this, we create a class that inherit from the BusinessEventContract class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
[DataContract] class JATCustUnblockedBusinessEventContract extends BusinessEventsContract { private CustAccount custAccount; private CustName custName; private Email email; private LegalEntityDataAreaId legalEntity; private void initialize(CustTable _custTable) { custAccount = _custTable.AccountNum; custName = _custTable.name(); email = _custTable.email(); legalEntity = _custTable.DataAreaId; } public static JATCustUnblockedBusinessEventContract newFromCustTable(CustTable _custTable) { JATCustUnblockedBusinessEventContract contract = new JATCustUnblockedBusinessEventContract(); contract.initialize(_custTable); return contract; } private void new() { } [DataMember('CustAccount'), BusinessEventsDataMember("@SYS7149")] public CustAccount parmCustAccount(CustAccount _custAccount = custAccount) { custAccount = _custAccount; return custAccount; } [DataMember('CustName'), BusinessEventsDataMember("@SYS80991")] public CustName parmCustName(CustName _custName = custName) { custName = _custName; return custName; } [DataMember('Email'), BusinessEventsDataMember("@SYS5845")] public Email parmEmail(Email _email = email) { email = _email; return email; } [DataMember('LegalEntity'), BusinessEventsDataMember("@SYS129100")] public Email parmLegalEntity(LegalEntityDataAreaId _legalEntity = legalEntity) { legalEntity = _legalEntity; return legalEntity; } } |
In this class we add the private properties that conform the payload, as well as the parm methods to access them and the newFromCustTable and initialize methods to initialize the values of the properties with the data of the customer that we are unblocking. As you can see, the parm methods are decorated with two attributes to establish the name and the description of the fields that will be visible in the body of the business event.
The second step will be the creation of a class that will inherit from the BusinessEventBase class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
[BusinessEvents(classStr(JATCustUnblockedBusinessEventContract), "@jatomas:CustomerUnblocked", "@jatomas:CustomerUnblocekdDesc", ModuleAxapta::Customer)] public public class JATCustUnblockedBusinessEvent extends BusinessEventsBase { private CustTable custTable; static public JATCustUnblockedBusinessEvent newFromCustTable(CustTable _custTable) { JATCustUnblockedBusinessEvent businessEvent = new JATCustUnblockedBusinessEvent(); businessEvent.parmCustTable(_custTable); return businessEvent; } private CustTable parmCustTable(CustTable _custTable = custTable) { custTable = _custTable; return custTable; } private void new() { } [Wrappable(true), Replaceable(true)] public BusinessEventsContract buildContract() { return JATCustUnblockedBusinessEventContract::newFromCustTable(custTable); } } |
As you can see, we decorate the buildContract methods with the Wrappable(true) and Replaceable(true) attributes to allow its extensibility. This method is only executed when a business event is enabled or activated in a company.
Finally, we would only have to establish the specific point at which the business event will be triggered and add the following lines of code in it:
1 2 3 4 |
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(JATCustUnblockedBusinessEvent))) { JATCustUnblockedBusinessEvent::newFromCustTable(this).send(); } |
In this way, the business event be will only triggered if it is enabled in the company in which we are working.
With all these steps done, we are going to see the business event in the business event catalog. We just have to go to System administration > Setup > Business events > Business events catalog. Once there, click in the Manage > Rebuild business event catalog menu. If the business event does not appear in the catalog, a full database sync may be needed because the Business event catalog is built during the full database sync.
Once finished, it will be available to be consumed in the same way we saw in the previous post.
Hi thanks for sharing demo. I have tried the same steps for Customer group and created the event and contract class. However, I am not able to see my event name in the business event catalog, I have also done the rebuild business event catalog still no update.
Hi Pooja, thanks for reading and commenting.
I guess you have decorated properly the Event class with the Attributes, and you have extended from the BusinessEventsBase class right?
Hi again Pooja,
Have you tried synching the full database?. The Business event catalog is built during the full database sync, so probably it will help 😉