Business Events in BC

Business Events in BC

It’s been almost three weeks since the Directions EMEA conference in Lyon and impressions have finally settled a bit. Once again, I shared a stage with my colleague Renato Fajdiga. Our presentation about capabilities of connecting Dataverse with a Business Central went really well; the audience showed interest, especially about Business Events, and that’s why we decided to write blog posts about it. The plan is for the blog to consist of two parts, or rather two separate blog posts. The first part is mine, where I write about the Business Events from developers perspective. On the other hand, Renato will follow up on this blog and demonstrate how to use a custom business events. Let’s start first with describing what the Business events are.

Business central in general

Similar to Integrations Events or even Trigger Events, Microsoft decided to introduce new type of events which are in preview from Business Central 2023 release wave 1. (External) Business events are raised by AL code and then all of the subscribed external systems are notified. Let’s say there is a scenario where after a sales invoice is posted, external system will need to do some extra logic. Instead of pinging Business Central to get info whether invoice is posted or not, we can just create a custom Business Event, external system will subscribe to it so when the event is triggered, the system will be notified.

But how it works? How BC will know which environment to notify?

That’s easy. There is something called event subscription. With event subscription we basically tell Business Central which external system it should notify, for which event and also for which company. Yes, you read it correctly, you can specify whether you like to subscribe to events only for specific company or for all companies. If you are wondering where this data is stored, the answer is in system table with ID 2000000240 called “External Event Subscription”. In the image below you can see some fields from this table.

Notice that “Company Name” value is empty. In other words, we are notifying external system for raised event from any company in our environment.

The other important thing here is to know that we can notify as much external systems as we want for the same business event. Also, we can specify the company for trigger events.

If we are using PowerAutomate Flow, then we don’t need to create a record in event subscriptions. It will be created automatically by PowerAutomate. On the other hand, if external system is some web application or Azure Function, in order to subscribe to any of Business Events we will first need to manually add a record in “External Event Subscription” table, i.e. we can do it with an API call.

Standard Business Events

Microsoft has already added some standard Business events. Currently there are not that many of them, but since this is a new feature we can assume that in the next versions more of standard events will come. If you are interested in what the standard events are you can find it here. But now let’s get to the fun part, let’s create a custom business event.

Creating a custom business event

Imagine that our customer wants to be notified when user status changes, for example some of the
employees are not working anymore for the company and their user accounts in BC are disabled. In order to notify other departments about this we can simply add a business event which will be fired when the user status is changed. Then the external system can use this event to track whether some of the actions from their side should be performed. How can we do it? Actually pretty simple. First we need to extend the standard Enum EventCategory with our group.

enumextension 50150 "RM Event Category" extends EventCategory
{
    value(50150; "RM User Status Events")
    {
        Caption = 'User Status';
    }
}

As you can see above, I just added a new category “RM User Status Events”. Now I will use trigger OnAfterValidateEvent for a field Status on a User record and every time when Status is changed we will fire the event.

Codeunit 50151 "RM User Status Business Event"
{
    [EventSubscriber(ObjectType::Table, Database::User, 'OnAfterValidateEvent', 'State', false, false)]
    local procedure OnAfterValidateState(var Rec: Record User; var xRec: Record User)
    var
        User: Record User;
    begin
        if Rec.State = xRec.State then
            exit;

        BusinessEventUserState(Rec.SystemId, Rec."User Security ID", Rec."Full Name", Rec.State = Rec.State::Enabled);
    end;

    [ExternalBusinessEvent('UserState', 'Change User State', 'This business event is triggered when a user state is changed', Enum::EventCategory::"User Status Events", '1.0')]
    local procedure BusinessEventUserState(UserId: Guid; UserSecurityId: Guid; FullName: Text[80]; IsEnabled: Boolean)
    begin
    end;
}

And that’s it. Simple as that. Now any external system which wants to track changes in user state could simply subscribe to this “UserState” business event. If you are wondering how you can achieve this with a PowerAutomate Flow then you should read this post from Renato: https://www.fajdiga.info/blog/2023/11/21/how-to-use-d365-business-central-business-events-with-power-platform.

Cheers!