Business Events Code Templates
Complete AL code templates for implementing external business events in Business Central.
Table of Contents
- Enum Extension - Event Category
- Business Events Codeunit Structure
- Event Subscriber Pattern
- External Business Event Procedures
- Integration Event Publishers
- Complete Working Example
- Advanced Patterns
Enum Extension - Event Category
Every business event requires a custom EventCategory. BC does not allow using standard categories for custom business events.
Basic Enum Extension
enumextension 50100 "MyExt EventCategory" extends EventCategory
{
value(50100; "My Custom Events")
{
Caption = 'My Custom Events';
}
}
Multiple Categories
If you have multiple business areas, consider multiple categories for better organization:
enumextension 50100 "MyExt EventCategory" extends EventCategory
{
value(50100; "Sales Management")
{
Caption = 'Sales Management';
}
value(50101; "Inventory Operations")
{
Caption = 'Inventory Operations';
}
value(50102; "Financial Processes")
{
Caption = 'Financial Processes';
}
}
Naming conventions:
- Use descriptive category names that business users understand
- Avoid technical jargon
- Keep caption concise (appears in Power Automate)
Business Events Codeunit Structure
The business events codeunit contains both event subscribers (listening to internal events) and external business event procedures.
Basic Structure
codeunit 50100 "MyExt Business Events"
{
// Event Subscribers listen to internal BC events
[EventSubscriber(ObjectType::Table, Database::"Your Table", OnSomeEvent, '', false, false)]
local procedure OnYourTableEvent(var YourTable: Record "Your Table")
begin
// Extract business data and call external business event
OnYourBusinessEventHappened(YourTable.SystemId, YourTable."No.", YourTable.Description);
end;
// External Business Events are the public API
[ExternalBusinessEvent('yourEventName', 'Your Event Display Name', 'Triggered when something business-relevant happens', EventCategory::"My Custom Events")]
procedure OnYourBusinessEventHappened(EntityID: GUID; EntityNo: Code[20]; Description: Text[100])
begin
// Leave empty - external invocation handled by attribute
end;
}
Multiple Events Structure
codeunit 50100 "Sales Mgmt Business Events"
{
// ======================================
// Event Subscribers
// ======================================
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post", OnAfterSalesOrderPost, '', false, false)]
local procedure OnAfterSalesOrderPost(var SalesHeader: Record "Sales Header"; SalesInvHeader: Record "Sales Invoice Header")
begin
OnSalesOrderPosted(
SalesInvHeader.SystemId,
SalesInvHeader."No.",
SalesInvHeader."Sell-to Customer No.",
SalesInvHeader."Order No.",
SalesInvHeader.Amount
);
end;
[EventSubscriber(ObjectType::Table, Database::Customer, OnAfterModifyEvent, '', false, false)]
local procedure OnCustomerModified(var Rec: Record Customer; var xRec: Record Customer)
begin
// Only fire event if blocked status actually changed
if Rec.Blocked <> xRec.Blocked then
OnCustomerBlockedStatusChanged(
Rec.SystemId,
Rec."No.",
Rec.Name,
Format(Rec.Blocked)
);
end;
// ======================================
// External Business Events
// ======================================
[ExternalBusinessEvent('salesOrderPosted', 'Sales Order Posted', 'Triggered when a sales order is successfully posted and invoiced', EventCategory::"Sales Management")]
procedure OnSalesOrderPosted(InvoiceID: GUID; InvoiceNo: Code[20]; CustomerNo: Code[20]; OrderNo: Code[20]; Amount: Decimal)
begin
end;
[ExternalBusinessEvent('customerBlockedStatusChanged', 'Customer Blocked Status Changed', 'Triggered when customer blocked status is modified', EventCategory::"Sales Management")]
procedure OnCustomerBlockedStatusChanged(CustomerID: GUID; CustomerNo: Code[20]; CustomerName: Text[100]; BlockedStatus: Text[50])
begin
end;
}
Organization:
- Group event subscribers at top
- Group external business events below
- Add comments for section clarity
- Keep all events for one business area in one codeunit
Event Subscriber Pattern
Event subscribers bridge internal BC events to external business events. They extract relevant business data and invoke the external business event procedure.
Subscribing to Table Lifecycle Events
For custom table extensions with IntegrationEvent publishers:
[EventSubscriber(ObjectType::Table, Database::"Statistical Account", OnAfterInsertStatisticalAccount, '', false, false)]
local procedure OnAfterInsertStatisticalAccount(var StatisticalAccount: Record "Statistical Account")
begin
OnStatisticalAccountCreated(
StatisticalAccount.SystemId,
StatisticalAccount."No.",
StatisticalAccount.Name
);
end;
Subscribing to Standard BC Posting Events
For standard BC posting codeunits:
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Stat. Acc. Jnl. Line Post", OnBeforeInsertStatisticalLedgerEntry, '', false, false)]
local procedure OnBeforeInsertStatisticalLedgerEntry(
var StatisticalAccJournalLine: Record "Statistical Acc. Journal Line";
var StatisticalLedgerEntry: Record "Statistical Ledger Entry"
)
begin
OnBeforeStatisticalLedgerEntryPosted(
StatisticalLedgerEntry.SystemId,
StatisticalAccJournalLine."Statistical Account No.",
StatisticalAccJournalLine."Posting Date",
StatisticalAccJournalLine.Amount,
StatisticalAccJournalLine."Document No.",
StatisticalLedgerEntry."Entry No."
);
end;
Conditional Event Firing
Only fire business events when business conditions are met:
[EventSubscriber(ObjectType::Table, Database::Item, OnAfterModifyEvent, '', false, false)]
local procedure OnItemModified(var Rec: Record Item; var xRec: Record Item)
begin
// Only fire if inventory below reorder point
if (Rec.Inventory < Rec."Reorder Point") and (xRec.Inventory >= xRec."Reorder Point") then
OnInventoryBelowReorderPoint(
Rec.SystemId,
Rec."No.",
Rec.Description,
Rec.Inventory,
Rec."Reorder Point"
);
end;