Extending the Dynamics 365 Business Central plugin-unit
The Dynamicweb D365 Business Central Plugin-Unit is a component in an integration between a Dynamicweb solution and a Dynamics 365 Business Central installation.
In this article you will learn how to extend this plugin - which is, in fact, an extension app in itself - using the AL programming language.
Extending the plugin-unit in this manner empowers ERP partners to create customer and project-specific code, whilst ensuring that you can always run the latest version of Dynamicweb Plug-In Unit on the latest version of Dynamics 365 Business Central.
Video Guide
This video guide covers the basics of extension development for Microsoft Dynamics 365 Business Central - it shows you:
- How to use Docker and NavContainerHelper to setup a dev-sandbox
- How to create a simple Hello World app
- How you can create an app that extends Dynamicweb Plug-In Unit (which is itself an extension app)
The example in the video is a simple Ping request which can send Pong responses.
Of course, your needs are likely to be more advanced. The rest of this article contains examples of common tasks such as adding fields to a contact or overriding user groups.
Events
There are 70+ events available in the standars plug-in unit to subscribe to - all placed into appropriate codeunits that have a prefix of Dynamicweb and a suffix of Publisher:
- DynamicwebPublisher contains global events such as:
- OnBeforeExecuteRequest: Occurs before any request is processed
- OnAfterExecuteXmlRequest: Occurs after request that returns xml is processed
- OnAfterExecutePdfRequest: Occurs after request that returns pdf is processed
- OnBeforeSendXmlResponse: Occurs before sending response content
- DynamicwebUsersPublisher contains events for handling customers, contacts, sales persons, their addresses, impersonations, user groups, exporting users
- DynamicwebOrdersPublisher contains events for handling exporting orders, writing order notes, Live integration calculate order and create order requests, sales header and sales line objects extensibility, discounts, shipping fees, etc.
- DynamicwebEcomDataPublisher contains events related to countries, currencies, manufacturers, languages, and units
- DynamicwebProductsPublisher contains events for handling products, product groups, stock, Live integration product info request, etc.
- DynamicwebCustomerCenPublisher contains Customer Center related events for creating PDF-generation, orders lists, and order details
To subscribe to these events choose the appropriate publisher and the events from it.
For a quick overview of the many extensibility events, check the UML diagram appendix at the bottom of the page.
The example project
The example project contains the example code for a wide range of notifications. In fact, our ambition is to always subscribe to all available notifications in the example project. That way the example project is a complete demonstration of any extensibility point in the Dynamicweb Plug-In Unit. The example project ultimately serves as our documentation of what is possible to extend.
The project tree looks like Figure 4.1.
You can use the example project as an inspiration and create a new app and use only the notifications subscribers that you need - or you can comment out/delete the examples subscribers from this project and use it.
For more information about Events and extending Microsoft Dynamics 365 Business Central apps you can read this: https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-subscribing-to-events
To subscribe to an event you need to use AL syntax like this to create a codeunit with a property EventSubscriberInstance = StaticAutomatic:
To subscribe to the event you need to type [EventSubscriber(ObjectType::Codeunit, Codeunit:: and then choose the needed code unit - the subscriber method could look like this:
You can now add your code inside this method. Note that the parameters event, parameters types, and their order cannot be changed as it will give a compile error.
Microsoft Visual Studio code setup
Much of this section is covered in the Video Guide linked above but for the sake of completeness, you also get a text description of what to setup in Visual Studio Code.
If you are new to VS Code and AL please read this: https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-extension-example
If you want to create an app which extends Dynamicweb Plug-In Unit then you need to add a reference to the Dynamicweb base app in the app.config file and also references to MS base apps:
For editing/opening the source code of the example app start Visual Studio Code and choose Open Folder and then select the folder with a sources like this:
After that you need to edit the file .vscode\launch.json - In the “configurations” section add your Business Central server connection info. If you are using MS docker image with Sandbox environment your configuration section may look like this:
Where “Server” is a url to your Business Central server and instance is your server instance name.
This information is shown in the powershell script once you have installed MS docker image
So from this image my config sever name is http://test and the instance name is NAV. If you have an on-premise server setup your config section will be the same except your server name and instance.
You can read more about JSON config file here and about docker containers and AL development on this blog.
After you have completed the configuration section you can try to connect your app with the Business Central server from VS code by calling Ctrl + Shift + P and choose command AL:Download Symbols and select your configuration server from the drop-down:
Once symbols are downloaded click F5 to compile your app. If the compilation is OK your app will be published in the selected server and you will be redirected to the opened Business Central website in your browser.
You can now use the Dynamicweb Test tool to connect to the Business Central server and run sample requests and check responses.
Publishing the example project
To publish the app just compile the project from VS code and once it is compiled under your D365BC server it will be published there automatically. If you cannot use the VS code you can use powershell and commands that are described here. If you already have the compiled app and want to publish it on the Cloud server you can use the standard functionality from “Extensions” page and choose “Upload extension” (Figure 8.1).
Then select your app and click Deploy:
After that track your deployment status in the Extensions -> Manage -> Deployment status:
Example 1: Add fields to a contact
Subscribe to the OnAddContactXmlNode event:
The code above will add the xml like this with contact Email2 value for each contact:
Example 2: Add fields to an address
Subscribe to the OnAddAddressXmlNode event:
The code above will add the xml like this for each contact address:
Example 3: Add fields to Sales Users
Subscribe to the OnAddSalesPersonXmlNode event:
The code above will add the xml like this to each sales person:
Example 4: Override user groups
Customers example:
Instead of creating one group 'Customers' and placing all users there, then create two groups 'Customers1' and 'Customers2'. Place users in these two groups with a function.
In our example this function just randomly assigns users to each of the two groups. In a real implementation you would add logic which segmented customers into different groups. It could be a grouping from external systems, but it could also be a segmentation based on a field/property of the users.
Sales example:
Instead of creating one group 'Sales' and placing all sales users there, then create two groups 'Senior Sales' and 'Junior Sales'. Place sales users in these two groups based on function.
Again, a real implementation would be more advanced. Either using a grouping from an external system or some kind of sorting/filtering function.
Subscribe to the OnAddGroupXmlNode event:
Here is the code for AddGroupXmlNode method:
Then you need to change the contact and sales persons user groups association logic like this:
Example 5: Override which contacts a sales user can sign in as
In this example you want the relation between sales users and their customers/contacts to come from an external system. Subscribe to the OnAddImpersonationXmlNode:
The code above will override the impersonations behavior: if contact name contains a letter ‘a’ in its name the impersonating user id will be set to ExternalImpersonatorId and the xml will look like this:
Example 6: Add custom fields to a product
Adding custom fields is the norm in any integration project, so it needs to be simple. Subscribe to the OnAddProductXmlNode event:
The code above will add the xml like this for each product:
Example 7: Custom Request-Response
The Video Guide covers the creation of a Ping-request and a Ping-response. For this example let’s assume you want to implement a new Get method to get the Company from the D365BC Company list that shows all companies (Figure 15.1).
Lets define the new Dynamicweb request as <GetCompanies></GetCompanies>.
Next we need to add logic in the subscriber to handle that new request and fill the response xml with our Companies xml:
And then add our xml to the response using private procedure like this:
After publishing this code and requesting the data with <GetCompanies></GetCompanies> the response will look like this:
Appendix: UML diagrams
You can acces diagrams of all extensibility events through the links below.
The diagrams provide a searchable overview of all the possible extensibility events.
- All extensibility events
- Batch integration extensibility events
- Ecom data extensibility events
- Integration customer center extensibility events
- Live integration orders extensibility events
- Products extensibility events
- Users extensibility events