Extending Business Central SaaS: Plant Tracking Using AL Extensions
1️⃣ Problem Statement
In many manufacturing and service-oriented organizations, sales transactions need to be associated with a Plant (or operational unit).
Out of the box, Microsoft Dynamics 365 Business Central SaaS does not provide a standard Plant dimension on Sales documents that automatically flows through:
-
Sales Orders
-
Posted Sales Shipments
-
Posted Sales Invoices
-
Customer Ledger Entries
Challenges
-
No standard Plant master table
-
No Plant selection on Sales Orders
-
No automatic propagation during posting
-
SaaS environment prohibits base object modification
MicroCloud360 needed a clean, upgrade-safe, SaaS-compliant extension to address this requirement.
2️⃣ Functional Requirements
FR-01: Plant Master
-
Maintain a list of Plants
-
Each Plant contains:
-
Plant Id (uppercase, unique)
-
Plant Name
-
FR-02: Sales Order Integration
-
Add Plant Id field to Sales Order header
-
Field must be optional
-
Users can select only valid Plant Ids (dropdown lookup)
FR-03: Posting Behaviour
When a Sales Order is posted:
-
If Plant Id is blank → do nothing
-
If Plant Id is populated → copy it to:
-
Sales Shipment Header
-
Sales Invoice Header
-
Customer Ledger Entry
-
FR-04: Visibility
Plant Id must be visible on:
-
Posted Sales Shipment
-
Posted Sales Invoice
-
Customer Ledger Entries
3️⃣ High-Level Architecture Diagram
Explanation
-
Implemented as a pure AL extension
-
No modification of base application objects
-
Uses:
-
Custom tables
-
Table extensions
-
Page extensions
-
Event subscribers
-
-
Fully SaaS and upgrade safe
4️⃣ Data Model Diagram
Tables Involved
| Table | Purpose |
|---|---|
| Plant (Custom) | Master data |
| Sales Header (36) | Capture Plant Id |
| Sales Shipment Header (110) | Persist Plant Id |
| Sales Invoice Header (112) | Persist Plant Id |
| Customer Ledger Entry (21) | Financial traceability |
Relationship Concept
5️⃣ Posting Flow Diagram
Flow Description
Plant Id flows only if populated.
6️⃣ Event-Driven Design (Why This Matters)
Business Central SaaS does not allow direct modification of standard posting codeunits.
MicroCloud360 Approach
-
Subscribe to standard posting events
-
Inject logic after standard processing
-
Avoid breaking changes during upgrades
Events Used
| Event | Purpose |
|---|---|
| OnAfterInsertShipmentHeader | Copy Plant Id |
| OnAfterInsertInvoiceHeader | Copy Plant Id |
| Cust. Ledger Entry OnAfterInsert | Populate ledger |
This follows Microsoft’s recommended SaaS extension pattern.
7️⃣ Key Code Snippets
Plant Id on Sales Header
Posting Event Subscriber (Example)
8️⃣ Testing & Results
Test Scenarios
| Scenario | Result |
|---|---|
| Plant creation | Saved in uppercase |
| Sales Order without Plant | Posts successfully |
| Sales Order with Plant | Plant copied to all posted records |
| Ledger review | Plant Id visible |
Outcome
-
No posting errors
-
No performance impact
-
No base code changes
-
Fully SaaS compliant
9️⃣ Best-Practice Notes
AL & SaaS Best Practices Used
-
One object per file
-
Unique object IDs
-
Shared field ID across tables
-
Event subscribers instead of code modification
-
No COMMIT statements
-
Optional business logic (non-blocking)
Naming Conventions
| Item | Convention |
|---|---|
| Prefix | Company prefix (MicroCloud360) |
| Object names | Meaningful & < 30 chars |
| Field IDs | Consistent across tables |
| Extension name | Business-driven |
Upgrade Safety
-
Uses published events only
-
No breaking dependencies
-
Ready for future BC releases
🔚 Technical Implementation
Recommended .al objects
Here is a clean, safe ID plan inside 50500–50599:
Tables
-
50500 = table
"MC360 Plant"
TableExtensions
-
50501 = Sales Header Ext
-
50502 = Sales Shipment Header Ext
-
50503 = Sales Invoice Header Ext
-
50504 = Cust. Ledger Entry Ext
PageExtensions
-
50520 = Sales Order Ext
-
50521 = Customer Ledger Entries Ext
-
50522 = Posted Sales Shipment Ext
-
50523 = Posted Sales Invoice Ext
Pages
-
50510 = Plant List
-
50511 = Plant Card
Codeunit
-
50540 = Plant Posting Subs
PermissionSet
-
50550 = MC360 PLANT
Files to be created under src folder
├── Tables/MC360Plant.Table.al
├── TableExtensions/MC360SalesHeaderExt.TableExt.al
├── TableExtensions/MC360SalesShipmentHeaderExt.TableExt.al
├── TableExtensions/MC360SalesInvoiceHeaderExt.TableExt.al
├── TableExtensions/MC360CustLedgerEntryExt.TableExt.al
├── PageExtensions/MC360SalesOrderExt.PageExt.al
├── PageExtensions/MC360CustLedgerEntriesExt.PageExt.al
├── PageExtensions/MC360PostedSalesShipmentExt.PageExt.al
├── PageExtensions/MC360PostedSalesInvoiceExt.PageExt.al
├── Pages/MC360PlantList.Page.al
├── Pages/MC360PlantCard.Page.al
└── PermissionSets/MC360Plant.PermissionSet.al