As a business case for our brand new extension for Microsoft Dynamics 365 Business Central, we need to handle the categorization of customers and we need to handle some sales business processes according to the customer's category.
We need to define categories for customers and we need to have a field on the customer card to associate a category with a customer. We need a way to define a default category and assign this default category to a particular customer or to all customers.
Then, for each customer category, we can define whether this category has the possibility to receive gifts when the customer that belongs to that category makes a sales order for an item. For that, we need to have a table set up where for each customer category, we can associate an item with a minimum quantity to order and the associated quantity for a free gift. For example, we need to setup a record such as this:
Here...
We've structured our project folder as follows:
We have an Src
folder and under that we have a subfolder for every functionality and then for object type.
The name of each AL file is created using Microsoft's naming guidelines:
- Each file name must start with the corresponding type and ID, followed by a dot for full objects or a dash for extensions:
- Full objects:
<Type><Id>.<ObjectName>.al
, such as Tab.50100.MyTable.al
- Extensions:
<Type><BaseId>-Ext<ObjectId>.<ObjectName>.al
: page 50100 MyPage
extends Customer Card
such as Pag21-Ext50100.MyPage.al
- It is required to use a prefix or suffix for the name property of the fields in your extension. You would then use the
Caption/CaptionML
values for what to display to the user. This avoids the collision of fields between extensions:
- A tag must be at least three characters
- The object/field name must start or end with the tag
- If a conflict arises, the one who registered the tag always wins...
Handling translations with XLIFF files
Dynamics 365 Business Central is multi-language enabled, which means that you can display the user interface in different languages and you need to support that feature when developing extensions.
With classic NAV development in C/SIDE, you manage the multi-language captions by using the CaptionML
property: https://docs.microsoft.com/en-us/dynamics-nav/captionml-property.
As you've probably seen, in our previous extension, we haven't managed the translation of the captions that we have in our code. You can't find lines with the CaptionML
set, for example the following:
field(2; Description; Text[50])
{
DataClassification = CustomerContent;
CaptionML = ENU = 'Description', ITA = 'Descrizione';
}
But instead, you'll find the following:
field(2; Description; Text[50])
{
DataClassification = CustomerContent;
Caption = 'Description';
}
So, how we do handle multi-language support for...
The Headline is an interesting new object available in Dynamics 365 Business Central that can be used to immediately show up-to-date information on a Role Center page. A Headline is essentially a page that contains one or more text fields that can be formatted in a particular way. There are nine standard Headlines in Dynamics 365 Business Central:
Nine standard Headlines in Dynamics 365 Business Central
A Headline is a page with a new PageType
called HeadlinePart
:
The HeadlinePart Page
For our extension, we also want to customize the Dynamics 365 Business Central Headline (the Headline RC Business Manager
object) in order to show some statistical information's to users.
Note
Headlines will only appear in the web client; they will not be shown in other client types.
To create this customization, we need to add a pageextension
object to our project in order to extend the Headline RC Business Manager
page.
This is the complete code of our pageextension
for customizing the Headline...
Developing a custom report for our extension
Now, we want to create a report for our extension that prints the list of Customer Categories, and for every category, the number of associated customers.
To create a report in AL, we need to go to the Src\CustomerCategory\report
folder and create a new .al
file called Rpt50100-CustomerCategoryList.al
. In this file, we use the treport
snippet to create the report structure:
We need to define the report dataset by defining the data item and the associated fields.
In the report definition, we set two properties (RDLCLayout
and WordLayout
) that define the folders where the RDLC and word layout for this report are defined (here we have created a Layout
folder under our project):
In the OnAfterGetRecord
trigger of the report's data item, we calculate the FlowField
returning the number of customers associated with the current category. Our report definition is as follows:
report 50100 CustomerCategoryList
{
//DefaultLayout = Word;
RDLCLayout = 'Layout...
When developing extensions for Dynamics 365 Business Central, an important architectural aspect when planning for a solution is the extension's dependency.
Imagine you have developed and published extension A into your Dynamics 365 Business Central. Extension A adds new tables and pages and extends standard tables and pages. Now you need to create extension B (to handle another set of isolated functionalities), and extension B must interact with tables and fields added from extension A.
If you start developing extension B and try to reference a table defined in extension A, you will receive an error (table is missing because you don't have the symbols from extension A).
Extension B can see entities defined in extension A only if it declares that it depends on extension A.
To see this concept in action, let's create a very simple extension (new project with Visual Studio Code and AL:Go
!) for adding a new action button to the Customer Category List
page.
The core part here...
Installing and upgrading codeunits
When you develop an extension, there's also an important aspect to take care of: installation and upgrading operations. When an extension is installed or upgraded, you often need to perform certain operations on data, such as populating new data and restoring existing ones. These tasks can be achieved by writing extension-install-and-upgrade code.
In this type of code, you can access the extension properties (such as version, name, publisher, and dependencies) by using the NAVApp.GetCurrentModuleInfo()
and NAVAPP.GetModuleInfo()
methods.
The install logic can be written by creating an install codeunit, that is, a codeunit with SubType = Install
.
An install codeunit has two main system triggers:
OnInstallAppPerCompany()
: Includes code for company-related operations. Runs once for each company in the database.OnInstallAppPerDatabase()
: Includes code for database-related operations. Runs once in the entire install process.
This is an example of an Install Codeunit...
In this chapter, we looked at how to implement an extension for Dynamics 365 Business Central and how to create all the types of objects available in the Extension model. You're now able to create your first extension and you're ready to deploy it on Dynamics 365 Business Central.
In Chapter 6, Deploying Extensions, we'll see how to debug your extension during the development phases and how to publish your extension to a Dynamics 365 Business Central production tenant.