While Business Central accommodates a large variety of records and transactions, clients often want additional fields, tables, and custom business logic. Developers create extensions to add this functionality to Business Central. Developing basics for Business Central and some considerations are discussed in this article.
Business Central Objects
Pages and Page Extensions – They display the underlying table data. Like the Table Extension, the Page Extension is used to modify pages that already exist in Business Central. Pages generally manifest as Lists and Cards. Lists show general information for many records, whereas the Card will show more detail for one record. Parts are pages that can be embedded into other pages. For instance, the Sales Order is a card for the header detail and the Sales Order Subform is a part that displays each of the Sales Lines of that selected Sales Header.
Factboxes – Factboxes often appear on pages as a right-pane that provides supplemental information for the selected record. One Factbox can be used in multiple pages assuming they are appropriately linked to the record supplying the information.
Codeunits – While procedures can be created on the table and page level to add business logic, Codeunits separate functionality and allow for a level of encapsulation to a developer’s code.
Reports – Reports consist of a dataset and at least one layout. They Dataset relates records and prompts for filter inputs. The Layout can be either RDLC or a Word layout.
Queries – Like report datasets, queries provide information on multiple related records. These queries can be deployed as SOAP/ODATA web services for automation and custom reporting.
With knowledge of the basic objects, there are a few best practices and concerns worth identifying before development commences.
Licensing – It is important to identify if the extension is developed for an On-Premises or Software as a Service (SaaS) client. On-Premises require the purchase and allocation of objects (e.g. Table Data, Code Units) before the extension can be deployed to production. A developer license is necessary for the application deployment (as well as setting up a Docker Image for test). The Software as a Service variant of Business Central does not currently have this requirement.
Nomenclature – Users must take steps to prevent collisions with other extensions. In addition to the Object ID (a number range), the Object Name must be unique per extension. Currently, partners can reserve prefix and suffix letters to prevent collision (MS Documentation here).
Object Ranges – While there are whispers of Object Range obsoletion down the road, these numerical values are a type of identifier for all objects (tables, pages, etc.). The Object Ranges are also reserved based on the type of extension (MS Documentation here). Customizations tailored per client will generally be 50,000-99,999. In other words, I would use Table Object 50,100 for the Container table, or Table Extension.
Automation – Job Queues and integrations come screeching to a halt there are User Interface prompts and messages. Special care should be taken to ensure that such UI can be bypassed. The HideDialog bool is generally added as a parameter to global procedures and passed to the related local procedures for this reason.
While AL is not a fully-fledged Object-Oriented Programming (OOP) language, there are some effective OOP principals that should be reflected in extension development.
Encapsulation – Encapsulation is the combination of procedures to restrict direct access to object components. Instead of creating one giant procedure directly on a Table or Page that handles all business logic, the procedure should instead call a code unit that handles the heavy lifting. These procedures will be local to restrict direct access and mutation of the extension. That code unit will consist of the global procedure called from the table/page as well as a series of local procedures that perform the following operations.
Decoupling – This is the compartmentalization of code such that an update in one section does not require a change in another section. As discussed in Encapsulation, it is common to see a procedure on a Page or Table that invokes another procedure from a separate code unit to perform the business logic. By splitting this out, developers can make further changes to the business logic in the code unit without necessarily changing the procedure on the Table or Page.
Extensibility – It is the ability to extend code without having to start from scratch. Business Central has Integration and Business Events to which a user can subscribe to add code before or after certain procedures. They are consistently prefixed with OnBefore and OnAfter, and they will be invoked before and after the method(s) that perform the main business logic. The same events can be created in extensions.
When designed correctly, the OnBefore events can also bypass the main procedures by setting the bool, Handled, to true. Because multiple applications and customizations can exist on one Business Central tenant, extensibility is extremely important. Creating Business and Integration Events will allow developers to interface with one another’s code without necessarily having full access to the source code.
Best practices and considerations are reflected in this generic example. From a page or table, a global procedure, SomeProc, is invoked from a codeunit variable. Amongst its parameters is the HideDialog bool, which determines if the User Interface will engage with prompts and messages.
Global Procedure – The following pattern describes a global procedure, SomeProc, that can be called externally from a page or table. HideDialog and other parameters are passed to this procedure:
User Interface – ConfirmSomeProc prompts the user to proceed with the overall procedure, and AckSomeProc displays a success message as the last step of SomeProc:
Both procedures refer to the HideDialog bool to identify if prompts and messages should display. When enabled, no messages or prompts should interrupt processing the related procedures. This is especially important when working with integrations that lack users interfacing with Business Central.
Integration/Business Events – OnBeforeSomeProc and OnAfterSomeProc are Business or Integration Events that other developers can call to extend this code:
With the OnBeforeSomeProc, developers can enable the Handled bool to bypass DoSomeProc, or they can leave the bool false to continue to the original logic developed in the solution.
Main Procedure – The first part of the DoSomeProc should exit if the Handled bool is set to true:
While it may be relatively easy to add a field to a table and page, following the patterns and practices described in this blog will go a long way to future-proof extensions and make them compatible with other extensions.