04 May 2020

How to use a custom SystemId when inserting a record through an API

Have you tried to insert a record to Microsoft Dynamics 365 Business Central through a Custom API and pass a custom SystemId with the record? 

Basically what I trying to achieve is when an Account is created in the D365 Sales system, I want to pass that record to D365 Business Central. I can easily do that using D365 Business Central APIs. However one of the challenges I faced was how I going to do the mapping between D365 Sales records and D365 Business Central Records. 

I can use intermediate tables and maintain record mapping. This is the solution most of the implementations used. This will still be the ideal solution if you have multiple D365 Sales systems connecting to D365 Business Central. 

If you have a one to one mapping between D365 Sales and D365 Business Central you can use a different approach. You can directly create a mapping between records without going through an intermediate mapping table. 

D365 Sales use a GUID as the record primary key and in 
most of the time, D365 Business Central use Code 20 field. How I'm going to create a mapping between records without modifying D365 Business Central or D365 Sales system? 

I can use SystemID in the D365 Business Central to handle this situation. 

So now what I'm trying to achieve is pass the Dynamics Sales Account ID into Business Central Customer System Id field. This will allow me to update the records back to Dynamics 365 Sales without maintaining a separate mapping table.

As a first step, I created a custom API for customer entity in D365 Business Central and exposed few fields. 

Then make a POST request with a sample JSON body and pass the No, Name, Email and D365 Sales Entity Record ID as SystemId. 

Strangely first error encountered was "systemId is read-only". Looks like platform automatically set the Editable property of the SystemId field to FALSE as a safety precaution. 

I set the editable property of the SystemId field to editable in the API page.

Then I tried the POST API call again and this time D365 Business Central accepted my POST request. However, the SystemId was different from the one that I used in the POST request. 

It is due to the platform is overriding the SystemId I pass through the POST request. To handle this new challenge of D365 Business Central generating the SystemID at the insert event, I can handle the insert within the API page by adding below event trigger. 

Some of you might be wondering "why Insert trigger is called with two boolean values?"

The Insert(Boolean, Boolean) lets you specify the SystemId value for a record, instead of using one assigned by the platform:
 myRec.SystemId := '{B6666666-F5A2-E911-8180-001DD8B7338E}';   
 myRec.Insert(true, true);  

Also, since we already inserted the record by calling Insert trigger, I should exit the function by returning FALSE. If I did return TRUE system will try to insert the same record again and we will get an error saying the record already exists.

This time when I call the POST method (of course I deleted the record inserted in the previous call) it did insert the customer record with the systemId I passed in the JSON body. 

The final result of the API page looks like below: 

If you want to access the AL files and the extension related to this blog please use below GitHub Repo: 

Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara
Read more »

24 April 2020

Navigate directly to a symbol of a file in VS Code

How would feel about if you can directly navigate to a symbol of a file? It is now possible in VS Code. 

All you need to do is press "Ctrl" + P and type the object name you want to navigate to and then press @, it will list down all the fields, functions and triggers within the object. You can simply select the place you want to jump into. 

Thank you, AJ (Arend-Jan Kauffmann) for the tip.
Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara
Read more »

08 March 2020

Object types is case sensitive in TenantWebServiceCollection

Last week while I was working on an integration project, I wanted to call a Business Central function from Azure Logic Apps. I had few options with APIs but I went ahead with creating a CodeUnit with a function and expose it as a web service.

Rather than exposing the CodeUnit by manually inserting an entry in the Web Service table, I used the new TenantWebServiceCollection option. I created below XML under my extension repo and published the extension with the expectation to see a ManageBCWSCall web service on the published web service page.
 <?xml version="1.0" encoding="utf-8"?>  

Things didn't go well with me on that day and adding more to that I could not find my published Web Service. 

After a few minutes, my colleague (Can Ates) suggests that object type might be case sensitive. To try out his theory we change the object type to "CodeUnit" and published the extension. This time it worked. 

 <?xml version="1.0" encoding="utf-8"?>  

Thank you Can Ates. 

Keep in mind that object type in the TenantWebServiceCollection is case sensitive. 
Please provide your feedback with a comment.
Thank you and Regards,
Tharanga Chandrasekara
Read more »

01 March 2020

Obsoleting Microsoft Dynamics 365 Business Central Events

If you are working on the extension development, then I'm sure that you already have published and subscribed to many events. There are some rules that you should strictly follow around events if your extension is eventually be used by another partner to build their solution on top of yours. 

Business Central has two types of events it's vital to decide which type of event you want to create. 

Business Events: A business event is a custom event that is raised by the AL code. It defines a formal contract that carries an implicit promise not to change in future releases. It is the expectation that business events are published by solution ISVs, including Microsoft.
Integration Event: An integration event is also a custom event that is raised by AL code, like a business event, except that it does not carry the same promise of not changing, nor does it have the restriction not to expose implementation details. The main purpose of integration events is to enable the integration of other solutions with Dynamics 365 Business Central without having to perform traditional code modifications.
In simple words, a Business Event is a promise made to the outer world that it will not be changed. 

If you have defined below two events in an earlier release of your extension and after a few releases you realize you must change the definition of the event or completely want to remove the event. 

Even though you have made a promise to the outer world, still you have to change the defined business event. 

If you just went ahead and change the event signature or remove the event and deploy the extensions, it will definitely break the other dependent extensions that have subscriber implementation to the event you just changed. 

See the example below, Subscriber in the extension B cannot find the "MyBusinessEvent" event in the extension A anymore. This will break extension B and force partner to rework on their extension B. 

This will definitely question your extension credibility and other partners might look for another more credible extension to use. 

Then don't you have an option to change this event? The simple answer is NO. 
You should never change the current event signature or remove the published events from your extension. 

BUT if you really want to change it then you should select a path that will not cause issues immediately to the other dependant extensions. Microsoft has introduced a way to handle these type of changes. 

You can obsolete your current business event and create a new business event with a new signature (MyBusinessEvent01)

Extension B will get a warning like below and this gives enough time for the developer of the Extension B to switch the subscriber to new implementation. 

You can give enough time for the other partners and also update your release documents with the breaking changes before you permanently remove the initial implementation of the event. 

Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara
Read more »

Microsoft Dynamics 365 Business Central Wave 1 2020: Release note explained.

A few weeks ago Microsoft published the 2020 release wave 1 plan for Dynamics 365 and Microsoft Power Platform document. This document contains details about many new interesting functionalities and features. Below are some of the features that got my attention.

Look up events and insert event subscribers in code
One challenge most developers face each day is to find the correct event and generate an event subscriber signature. With this newly added feature, develoepr can easily search through the available event list and generate subscriber signature and insert it into code context. 
Use the new Shift+Alt+E shortcut in the AL code editor to invoke a list of all events. You can use type ahead to dynamically search and filter the event list, and when pressing return to select an event entry, an event subscriber for the event will be inserted at the cursor position in the active AL code editor window. 
Multiple variable declarations of the same type in the same line
I was looking forward to this from the day I saw it during NAVTechDays. No more lengthy list of variable declaration.  
Declare multiple variables of the same type in the same line, using a comma to separate variable names. For example, "foo, bar : Integer;
Ability to refactor a field from a table to a table extension 
This would be good news for most of the On-premise customers who are looking forward to migrating to SaaS. With this new feature, the developer can move the custom fields to a table extension without writing any upgrade code. However, think very well before creating table extensions as it will have an effect on application performance. 
Using Sync-NAVApp, a developer can move a field from a table to a table extension without the need to write upgrade code
API for continuous delivery of the AppSource apps via Azure DevOps services
This will allows partners to manage their apps and orchestrate the steps of the app release. This will not be available for all partners immediately. 
The partners will use a new API (fixed app management endpoint, of FAME) and Azure DevOps services to manage their apps and orchestrate the steps of the release (release pipeline). Once a partner app has been tested in a Docker container and has passed automated AppSource validation checks, the production-ready app will be submitted for the AppSource automatic and additional manual validation via the Microsoft Partner Center portal as usual. When the app is approved, the ISV will proceed with a phased rollout of the app to all of its customers, using the previous version of the ISV app, across multiple countries. New versions of the partner apps will be made available to the customers to upgrade to on the Extension Management page so that customers can install or upgrade to those when they see fit. 
Business Central integration with Common Data Service
This was first demonstrated during NAV TechDays and I was very much looking forward to this. The new feature will allow to connect to CDS and associate a Business Central company with the CDS business unit. Not sure how this is been added to the product but hopefully it will not be similar to the current CRM connector which runs based on Job queues and has very limited capabilities. 
When developing extensions that integrate with Common Data Service, Business Central 2020 release wave 1 will bring extensibility capabilities, where Common Data Service tables and Common Data Service table extensions can be created. This will allow for any custom attribute to be synchronized
Read scale-out
No more system performance issue when a selected API, Report or Web Service runs to read the data from Business Central. Selected API, Report or Web Service can read the data from a replica of the database and this will helps to improve active user experience. This means there will be no impact on the primary database while pulling large sets of data. 
Business Central artifacts (Reports, API Pages, and Queries) now can get access to a read-only replica of the database. The Page, Report and Query objects have a new property called “DataAccessIntent” that can take values ReadOnly or ReadWrite. This property works as a hint for the server, which will connect to the secondary replica if possible. When a workload is executed against the replica, insert/delete/modify operations are not possible, so a new validation is introduced for ReadOnly objects. Any of these operations will throw an exception at runtime (new compile-time validation will be added in the future)
AL interfaces
Waldo and Tobias already wrote about this new feature soon after the NAV TechDays. I would suggest you read those above mention blog posts for more information. This is a one-step forwards towards the OOP.
Use the new interface object to declare an interface name along with its methods, and apply the implements keyword along with the interface names on objects that implement the interface methods. The interface object itself does not contain any code, only signatures, and cannot itself be called from code, but must be implemented by other objects. The compiler checks to ensure implementations adhere to assigned interfaces. A new QuickFix CodeAction can be used to insert interface stubs, if the compiler errors on one or more interface implementations are missing.

There are many more new functionalities available and read my next blog posts to know how to get access to the new Business Central version 16 environment. 

Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara
Read more »

Notes from Directions EMEA 2019

Below are some notes I took during Directions EMEA 2019. A bit late to publish but didn't want to just delete them. 

Treat extensions as products.
    • Which means releasing them to customers periodically.
    • Allow proper testing with proper test cases (Preferably automated testing).
    • Try to run all the customers on the same version.
    • Proper code freeze before testing starts. 
    • Configs should be in installation codeunits, upgrade codeunits or in Config packages
      • It can be automated during the installation
Customer extensions
    • The release should be periodic (Can make an exception if the fix is urgent).
    • Data changes should be in upgrade codeunits.
    • Should NEVER merge extensions together just because to avoid dependency.
    • If the dependency is troubling the deployment then try to restructure the extension.
  • CI/CD is a must with extensions as it makes life easy for the developers and also for consultants.
  • If you are not an expert on DevOps, then do not try to reinvent the wheel.
    • Try to implement a simple pipeline with available extensions and add-ons.
    • Once your company is compatible with the CI/CD and has a better understanding then invest in finding a solution that is perfect for your organization.
Number of objects
  • The number of objects in an extension should be less than 100 (not a rule, but if the objects exceed 100 then it is a good idea to rethink the design).
  • If the object count is going more than 100 that means (in most cases) this extension can be split into different modules.
  • Once the extension is split into different modules, it is easy to manage and implement.
  • New Logic Apps, Flow and PowerBI connectors allow selecting the environment.
Power Apps
  • To make the user’s life easy, try to use PowerApps for data entering.
  • Create dashboards for Extensions using available new telemetry APIs.
  • This allows partners to monitor the extensions and take actions before it ran into issues.
Try to go global not only local
  • BC is an online platform so partners get the opportunity to go global.
  • Whoever starts first wins.
  • Get your apps to the market and make your mark.
Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara
Read more »