Monday, May 25, 2020

Business Central Integration with Rest API – OnPrem - Part 2

Dear Reader’s, I am sharing simple REST API integration with Business Central 2020 Wave 1 release. This is based on Part 1, where I have used both Codeunit & DotNet. Here I am using only codeunits to simulate same thing without DotNet variables.

Thanks to "Arend-Jan Kauffmann" reply where he has mentioned why you have used DotNet where it all will be handled by AL Data Types & Methods (Wrapper Classes). He has also share detailed explanation in his blog. So, inspired and reconstructed my Part 1 into two samples:

Example 1: (Sample 1) Used codeunits to handle the request & response without any DotNet variable combination.

Example 2: (Sample 2) Used AL Data Types & Methods (Wrapper Classes) to handle the request & response without using any Codeunit & DotNet varibale. This sample will run on SaaS model as well.

Example 1: Below are example of calling API without using DotNet variable:

codeunit 50102 "Json API Test2"
{
    trigger OnRun()
    begin
        // Plesase fix below line in single line
        Url := 'http://samples.openweathermap.org/data/2.5/weather?zip=110001,in&
                        appid=b6907d289e10d714a6e88b30761fae22';
        HttpWebRequestMgt.Initialize(Url);
        HttpWebRequestMgt.DisableUI();
        HttpWebRequestMgt.SetMethod('GET');
        HttpWebRequestMgt.SetReturnType('application/json');

        Clear(TempBlob);
        TempBlob.CreateInStream(InStr);

        IF HttpWebRequestMgt.GetResponseStream(InStr) then begin

            InStr.ReadText(Json, MaxStrLen(Json));
            Message(Json);

            IF JSONMgmt.InitializeFromString(Json) then begin
                Temperature := JSONMgmt.GetValue('main.temp');
                Pressure := JSONMgmt.GetValue('main.pressure');
                Humidity := JSONMgmt.GetValue('main.humidity');
                TempMin := JSONMgmt.GetValue('main.temp_min');
                TempMax := JSONMgmt.GetValue('main.temp_max');
            end;

            MESSAGE(Text001, Temperature, Pressure, Humidity, TempMin, TempMax);
        end;
    end;

    var
        HttpWebRequestMgt: Codeunit "Http Web Request Mgt.";
        Url: Text;
        Json: Text;
        TempBlob: Codeunit "Temp Blob";
        InStr: InStream;
        Temperature: Text;
        Pressure: Text;
        Humidity: Text;
        TempMin: Text;
        TempMax: Text;
        JSONMgmt: Codeunit "JSON Management";
        // Plesase fix below line in single line
        Text001: Label 'Temperature: %1 \Pressure: %2 \Humidity: %3 
                            \Min Temperature: %4 \Max  Temperature: %5';
}


Example 2: (Sample 2) Using AL Data Types & Methods (Wrapper Classes) 

codeunit 50104 "Json API Test4"
{
    trigger OnRun()
    begin
        
        // Plesase fix below line in single line
        Url := 'http://samples.openweathermap.org/data/2.5/weather?zip=110001,in
                        &appid=b6907d289e10d714a6e88b30761fae22';
        HttpHeader := HttpWebClient.DefaultRequestHeaders;
        HttpHeader.Add('Accept''application/json');
        IF HttpWebClient.Get(Url, HttpWebResponse) then
            IF HttpWebResponse.IsSuccessStatusCode then begin
                HttpWebResponse.Content.ReadAs(Json);
                Message(Json);
                JObject.ReadFrom(Json);
                IF JObject.SelectToken('main.temp', JToken) then
                    Temperature := JToken.AsValue().AsText();
                IF JObject.SelectToken('main.pressure', JToken) then
                    Pressure := JToken.AsValue().AsText();
                IF JObject.SelectToken('main.humidity', JToken) then
                    Humidity := JToken.AsValue().AsText();
                IF JObject.SelectToken('main.temp_min', JToken) then
                    TempMin := JToken.AsValue().AsText();
                IF JObject.SelectToken('main.temp_max', JToken) then
                    TempMax := JToken.AsValue().AsText();

                MESSAGE(Text001, Temperature, Pressure, Humidity, TempMin, TempMax);
            end;
    end;

    var
        Url: Text;
        Json: Text;
        Temperature: Text;
        Pressure: Text;
        Humidity: Text;
        TempMin: Text;
        TempMax: Text;
        HttpWebClient: HttpClient;
        HttpHeader: HttpHeaders;
        HttpWebResponse: HttpResponseMessage;
        JObject: JsonObject;
        JToken: JsonToken;
// Plesase fix below line in single line
        Text001: Label 'Using Wrapper Class:\Temperature: %1 \Pressure: %2 
            \Humidity: %3 \Min Temperature: %4 \Max  Temperature: %5';
}

Stay tuned, next blog is coming soon...

Sunday, May 24, 2020

Dynamics 365 Business Central 2020 release wave 1 Capability

New capability highlights

The 2020 release wave 1, brings to market significant new services and capabilities to enable digital transformation for businesses. For Dynamics 365 Business Central, these new capabilities include:

Improved usability

• Search for features in the role explorer

• Enable non-interactive printing

• Import profiles and UI customizations

• Show parts that are hidden on pages

• Go to related records from list pages

• Improve pages that have multiple parts

• Bookmark reports

• Categorize data

• Enter data more easily

• Filter data and create views

Enhanced application features

• Use resources in purchase documents

• Send the right documents to your contacts

• Receive more goods than you ordered

• Undo shipment or receipt lines for non-items

Better tool for admins and partners

• Integrate with Common Data Service

• Manage permissions with deeper insight

• Sync users with the Microsoft 365 admin center

• View data sizes per table

• Cancel sessions

• Use AL interface objects

 

Improved usability

Search for features in the role explorer: The Business Central Role Explorer has a new addition that complements manual navigation and expanding or collapsing menu groups. Users can now open the Role Explorer, with either the "hamburger" icon or the Shift-F12 keyboard shortcut, and then start typing what they are looking for.

The Role Explorer does not filter the results but instead highlights the hits, as shown in the next image. Also, when a result is contained in a collapsed group, the Find function annotates that group using a teal-colored circle. Users can browse through the results using arrows or Ctrl+Up/Down keyboard keys. The Esc key closes the Find box and removes the value typed, so that new searching or browsing can be started. Note also that switching to the Explore all view retains the find value making it easy to navigate.

Enable non-interactive printing: Users can print reports directly from the desktop using the predefined printers configured on the Printer Management page. If the printers are selected and set up properly, then no additional steps, such as downloading files or navigating through previews, are necessary. In addition, administrators can have the power to configure print jobs for specific tasks, users, orfor more complex printer setups.

Complex printing scenarios where labels must be sent to one printer and a packing slip to another are common in many businesses. Users expect to be able to configure, save, and retain certain properties describing such flows, and they expect to print each report directly to a predefined printer.

Printing directly to a printer is now possible from the modern desktop clients. The setup that you make on the Printer Management page allows you to control which device to print to, including to cloud printers as defined by extensions. Using the Business Central modern clients, users who work in the browser can set up a printer selection for each report so that documents, labels, and other content are printed automatically on the selected printer. Administrators can manage a list of printers (including cloud printers), for example, by creating a friendly name for each and setting defaults. Additionally, for on-premises installations, any network printer that the server has access to will be available on the Printer Management page.

Import profiles and UI customizations: Administrators and consultants benefit from a rich toolset that supports role-tailoring in Business Central. By having both an export and import function for profiles (organizational roles) and their corresponding user interface customizations, customers can easily back up their profile customizations before making further changes, replicate profiles across environments, or safely explore possibilities in an online sandbox before importing into production. All this without requiring the assistance of developers.

Show parts that are hidden on pages: Business Central is able to adapt to the unique needs of the user, department, or organization.

When personalizing pages in Business Central, users can show a hidden part on any page, such as a

FactBox on a sales document. This unlocks two common scenarios:

Business users can personalize their pages and bring back a part that they have previously hidden. Similarly, power users and consultants can unhide parts that they have previously hidden.

Developers can now choose to place secondary content on a page object and hide it, giving their customers a simple starting point with the page and the ability to unhide that content if it is relevant to their business processes.

Go to related records from list pages: Navigating through your business data, jumping from one context to the other or simply drilling through data is essential fora busy professional.

We are adding capabilities for users to navigate via links to even more places than today. This allows you to open a related card from a list, such as a customer or item card from a sales order.

Improve pages that have multiple parts: Some business tasks require advanced screen layouts that reflect the nature of the task and the volume of data associated with the task. By having highly optimized layouts, users get the best overview of their data to quickly make decisions and act, reducing the need to scroll and navigate to get the task done.

Improvements to pages composed of multiple parts

The desktop client adds full support for page objects that are composed of multiple parts, such as ListParts or CardParts. This capability was already possible on a Role Center or FactBox pane. But the canvas of other page types wasn't optimal for displaying parts alongside other content, resulting in overlapping UI elements or unreachable data.

Developers are now able to implement pages by choosing from prescribed AL patterns that give predictable outcomes. For example, they can display two lists side by side on a ListPlus page. Or, have multiple dependent lists shown above each other on a Document page. Pages already using these control patterns will automatically benefit from this change with no further development effort needed.

Available April 2020: Optimizations for ListParts as used on List pages, Document pages, Card pages, and ListPlus pages.

Available after April 2020: Optimizations for List Parts as used on Worksheet pages, and CardParts as used on various page types.

Categorize data: Users get a better overview of their data when it is grouped into categories. Some data is best represented as a deep hierarchical list. Business Central empowers developers to design pages for both of these scenarios, so that users can get the best possible overview and navigate to the relevant records.

On page objects where a repeater control has the Show As Tree property set to True, users will experience a new level of efficiency when working with the data tree. Users can easily drill down and back out again, using a keyboard or mouse, by expanding and collapsing groups or by using the Expand all and Collapse all actions.

Developers can also specify if a tree should start as fully expanded or fully collapsed.

Enter data more easily: Back-office workers often need to capture information or digitize paper material at high speed. For some users, this is their main activity for the whole workday. When this cannot be automated through means like OCR and AI, users require an efficient interface that does not get in the way of quickly typing in data.

Various adjustments that enhance typing or navigating fields in a list.

In editable lists, users will be able to use the left and right arrow keys to navigate to the previous or next cell in a row. This provides a consistent experience between editable and non-editable lists and increases the speed and agility of exploring data in a list or worksheet.

Similar to Microsoft Excel, we've introduced the F2 key that toggles between selecting the entire value of a field and placing the cursor at the end of the value. This allows users to quickly replace the value or add to it. The F2 key is available for editable fields and editable cells in lists.

When typing to fill in a row of data, the Tab key no longer sets focus to the ellipses that bring up the context for the row. This improves efficiency when rapidly entering data and ensures that Tab key presses are predictable. The context menu remains reachable using the left or right arrow keys.

Filter data and create views: As the business grows, so does table data in the database, making quick analysis of the data or even finding records more challenging without the right tools. Defining the perfect set of filters can be a time-consuming, iterative process where the ability to persist filters will save having to recreate them the next time they are needed.

The 2019 release wave 2 eliminated the need to recreate commonly used filters by allowing users to permanently save filters as a view in the web client. Based on community feedback, we're now improving the filter experience further:

When authoring filters that use expressions, such as date ranges or filter tokens, you can toggle the filter field to display either the expression or the corresponding value. To view the expression, simply set the focus to the filter field using a keyboard or mouse. This is particularly useful when saving list views so that date-or time-sensitive expressions can easily be modified when needed.

While on a list page, saving the URL as a browser favourite will include the current view, allowing you to link directly to the view when you navigate to that favourite. Note that the web client URL will only include views and filters that have been saved.

When working with lists, Business Central will help you pick up where you left off if you are disconnected or you reload the web page by trying to return to the last view you visited.


Enhanced application features

Use resources in purchase documents: Most businesses tend to outsource or hire external, named resources on a temporary basis, such as for a particular project or job. The ability to purchase resources allows you to track and process such transactions.

You can now use Resource as a line type of purchase documents. For example, you can add resources on purchase orders, invoices, and credit memos and post purchase transactions for them. You can correct purchase documents with resource lines, copy them, or use resource extended text.

Send the right documents to your contacts: Businesses deal with multiple customer and vendor contacts who are responsible for different areas of operation, such as accountants, purchasers, and warehouse people. Each of these contacts must be sent different sets of documents generated by Business Central.

You can now save time while sending documents to different customer or vendor contacts by setting up specific contacts to use with specific documents. For example, customer statements will be sent to accountant contacts, sales orders to your customers' purchasers, and purchase orders to vendors' salespeople or account managers.

You can now populate the Document Layouts page for vendors and customers based on settings on the Report Selection page. To send specific documents to specific company contacts, choose the company contacts to use for specific document layouts.

The Document Layouts page for a customer now contains additional usage options for reminders and posted shipments. The Document Layout page for a vendor now contains additional usage options for purchase orders and posted return shipment.

Receive more goods than you ordered: When you receive more goods than you ordered and it's cheaper not to return such goods or your vendor offers you a discount, order processors and warehouse workers must be able to handle such receipts without going through a lengthy process of preparing and getting approval for a new purchase order.

You can now receive a quantity higher than the ordered quantity on purchase orders according to an over-receive policy that you set up on the Over-Receipt Codes page. Here you can fill in the Over-Receipt Tolerance % field and select a policy to be used by default.

If your company uses purchase order approval, over-receiving can trigger a re-approval. You define this on the Over-Receipt Codes page. The Approve Over-Receipt workflow response is available in the workflow engine for this purpose.

On the cards for items and vendors, you can select in the Over-Receipt Code field which policy to use by default on purchases.

When you have selected an over-receipt code, you can enter a higher-than-ordered quantity in the Quantity to Receive field on released purchase orders and warehouse receipts.

 

Better tools for admins and partners

Integrate with Common Data Service: A new Common Data Service on boarding experience will be provided, where users will be able to connect to a Common Data Service environment and associate a Business Central company with a Common Data Service business unit. This will allow for multiple companies to connect to a Common Data Service instance. During setup, the Common Data Service connection entities from the default Common Data Service database will be synchronized.

This provides extensibility support for developers developing integrations for Common Data Service.

Common Data Service is at the center of the Dynamics 365 suite. Common Data Service enables users to have a 360-degree view of their business as data is available in Common Data Service. Once data is in Common Data Service, users will have a shared, consistent view of data across the Dynamics 365 solution. Dynamics 365 Business Central will support a set of entities in the Common Data Service default database provided in a "Business Central CDS Base Solution," which other integrations will depend on. The base solution will bring the capability to map a Company entity to a Business Unit entity in Common Data Service.

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.

Get telemetry in Application Insights: Partners can monitor performance of web service requests and reports.

The Business Central server will emit telemetry about the execution time and timeouts of web service requests and reports.

Partners and customers can use this to monitor their environments for performance issues caused by web service requests and reports and be more proactive in preventing these issues from occurring.

AL interfaces: An interface is used when you want to decide which capabilities need to be available for an object, while allowing actual implementations to differ, as long as they comply with the defined interface.

This allows for writing code that reduces the dependency on implementation details, makes it easier to reuse code, and supports a polymorphic way of calling object methods, which again can be used for substituting business logic.

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 Quick Fix Code Action can be used to insert interface stubs, if the compiler errors on one or more interface implementations are missing.

You can declare variables as a given interface to allow passing objects that implement the interface, and then call interface implementations on the passed object in a polymorphic manner.

Performance tuning guide: Understand and improve the performance of Business Central. The content is centred on the different ways a functional consultant, a developer, or an administrator can make changes with a performance impact. 

Visit: aka.ms/bcperformancefor more details.

View data sizes per table: When troubleshooting performance issues, sometimes it is necessary to see the distribution of data size across tables. This feature makes it easy for an administrator to look up this information.

A new page called Table Information shows the following:

Company Name

Table Name

Table No.

No. of Records

Record Size

Size (KB)

Information is shown for all companies for which the user has SUPER permissions.

Cancel sessions: Sometimes, cancelling a session is the only way to unblock a customer. For example, a long-running report is locking data in a table, preventing warehouse employees from working.

Prior to this feature, partners would need to contact support to locate and terminate the session.

In the Business Central administration centre, an administrator can see a list of active sessions on an environment and cancel one or more of them. All existing resources consumed by a session will also be cancelled.

For more details, please visit Microsoft’s Business Central page & below are few links which might helpful to understand above in details:

https://www.youtube.com/watch?v=2jqzveL_Nu4&feature=youtu.be

https://docs.microsoft.com/en-gb/dynamics365-release-plan/2020wave1/dynamics365-business-central/planned-features

 


Business Central Integration with Rest API – OnPrem - Part 1

Dear Reader’s, I am sharing simple REST API integration with Business Central 2020 Wave 1 release.

Business Central itself is more powerful and having wide range to methods stored in Codeunits to easily integrate to third party Application / System.

I am demonstrating with sample example how you will connect and read a REST API (JSON) data.

There is sample Open Weather Map API, URL: https://samples.openweathermap.org/data/2.5/weather?zip=94040,us&appid=b1b15e88fa797225412429c1c50c122a1 which I will use to demonstrate my example.

When you will paste this URL in browser, you will get below data in JSON format:

{"coord":{"lon":-122.09,"lat":37.39},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"base":"stations","main":{"temp":280.44,"pressure":1017,"humidity":61,"temp_min":279.15,"temp_max":281.15},"visibility":12874,"wind":{"speed":8.2,"deg":340,"gust":11.3},"clouds":{"all":1},"dt":1519061700,"sys":{"type":1,"id":392,"message":0.0027,"country":"US","sunrise":1519051894,"sunset":1519091585},"id":0,"name":"Mountain View","cod":200}

 

Copy this sample and paste in any of JSON formatter to understand the nodes, array & data in it. I have used jsonlint.com to format above data. You may chose as per your choice. So, below are formatted data looks like.

{

          "coord": {

                   "lon": -122.09,

                   "lat": 37.39

          },

          "weather": [{

                   "id": 500,

                   "main": "Rain",

                   "description": "light rain",

                   "icon": "10d"

          }],

          "base": "stations",

          "main": {

                   "temp": 280.44,

                   "pressure": 1017,

                   "humidity": 61,

                   "temp_min": 279.15,

                   "temp_max": 281.15

          },

          "visibility": 12874,

          "wind": {

                   "speed": 8.2,

                   "deg": 340,

                   "gust": 11.3

          },

          "clouds": {

                   "all": 1

          },

          "dt": 1519061700,

          "sys": {

                   "type": 1,

                   "id": 392,

                   "message": 0.0027,

                   "country": "US",

                   "sunrise": 1519051894,

                   "sunset": 1519091585

          },

          "id": 0,

          "name": "Mountain View",

          "cod": 200

}

 

From above sample, I will try to read below data thru AL codes:

          "main": {

                   "temp": 280.44,

                   "pressure": 1017,

                   "humidity": 61,

                   "temp_min": 279.15,

                   "temp_max": 281.15

          }

Now we have enough information & input to start our development. Here we go, below are steps:

Step 1: Update app.json file and add tag as "target": "OnPrem". Example

{
  "id""e43cc46f-a3fb-41f9-89c4-4c8cfcf84f38",
  "name""JsonAPITest",
  "publisher""Gaurav",
  "version""1.0.0.0",
  "brief""",
  "description""",
  "privacyStatement""",
  "EULA""",
  "help""",
  "url""",
  "logo""",
  "dependencies": [
    {
      "id""63ca2fa4-4f03-4f2b-a480-172fef340d3f",
      "publisher""Microsoft",
      "name""System Application",
      "version""16.0.0.0"
    },
    {
      "id""437dbf0e-84ff-417a-965d-ed2bb9650972",
      "publisher""Microsoft",
      "name""Base Application",
      "version""16.0.0.0"
    }
  ],
  "screenshots": [],
  "platform""16.0.0.0",
  "idRanges": [
    {
      "from"50100,
      "to"50149
    }
  ],
  "contextSensitiveHelpUrl""https://SocialMedia.com/help/",
  "showMyCode"true,
  "target""OnPrem",
  "runtime""5.0"
}

Step 2: Update settings.json and add "al.assemblyProbingPaths" with its path for assemblies. For example:

{
    "al.defaultLaunchConfigurationName""Your own server",
    "al.assemblyProbingPaths": [
        "./.netpackages",
        "C:/Windows/assembly/",
        "C:/Program Files/Microsoft Dynamics 365 Business Central/160/Service/Add-ins/"
    ]
}

Step 3: Build AL method to connect above URL and decode the desired output. I am using a codeunit to demonstrate the solution. You can copy the code and test the solution.


codeunit 50101 "Json API Test"
{
    trigger OnRun()
    begin
        Url := 'http://samples.openweathermap.org/data/2.5/weather?zip=110001,in&appid=b6907d289e10d714a6e88b30761fae22';
        HttpWebRequestMgt.Initialize(Url);
        HttpWebRequestMgt.DisableUI();
        HttpWebRequestMgt.SetMethod('GET');
        HttpWebRequestMgt.SetReturnType('application/json');

        Clear(TempBlob);
        TempBlob.CreateInStream(InStr);

        IF HttpWebRequestMgt.GetResponse(InStr, HttpStatusCode, ResponseHeader) then
            IF HttpStatusCode.ToString() = HttpStatusCode.OK.ToString() THEN begin
                InStr.ReadText(Json, MaxStrLen(Json));
                Message(Json);

                IF JSONMgmt.InitializeFromString(Json) then begin
                    Temperature := JSONMgmt.GetValue('main.temp');
                    Pressure := JSONMgmt.GetValue('main.pressure');
                    Humidity := JSONMgmt.GetValue('main.humidity');
                    TempMin := JSONMgmt.GetValue('main.temp_min');
                    TempMax := JSONMgmt.GetValue('main.temp_max');
                end;

                MESSAGE(Text001, Temperature, Pressure, Humidity, TempMin, TempMax);
            end;
    end;



    var
        HttpWebRequestMgt: Codeunit "Http Web Request Mgt.";
        Url: Text;
        Json: Text;
        TempBlob: Codeunit "Temp Blob";
        InStr: InStream;
        HttpStatusCode: DotNet HttpStatusCode;
        ResponseHeader: DotNet NameValueCollection;
        Temperature: Text;
        Pressure: Text;
        Humidity: Text;
        TempMin: Text;
        TempMax: Text;
        JSONMgmt: Codeunit "JSON Management";
        Text001: Label 'Temperature:%1\Pressure:%2\Humidity:%3\Min Temperature:%4\Max  Temperature: %5';
}

Step 4: Call this codeunit by extending any page. I am using customer card to extend and call this codeunit to display the message.

pageextension 50110 "CRONUS Social Media Card" extends "Customer Card"
{
    actions
    {
        addlast("&Customer")
        {
            Action(APITest)
            {
                ApplicationArea = All;
                Caption = 'API Test';
                Image = Web;
                // Run page to test how actions work
                RunObject = codeunit "Json API Test";
            }
        }
    }
}

That’s all folks. You may give a try. No matter you are using above codeunit in an action button or in a report or whatever you want.

Please share your feedback…


Tuesday, May 5, 2020

How safe is Calling & Video Conferencing APP?

Do not put your data on risk…
Lot of articles are floating on web. Most of are belongs to Privacy and personal information stored in device (email, photos, etc.), device access, etc.

The world we are leaving is now more advance and vulnerable. Below are vital security data are at risk:

Video & Facial Recognition Pattern: Anyone face video and their facial recognition patter can be breached. Most of devices are having high definition camera. These data can be misused or used. No need to mention, what facial recognition pattern can do. Some of high definition camera are able to capture Eye Retina to some extent.

Voice: Another important data which can be morphed & doctored. Voice unlock command can be breached. To identify the person from voice. There are lots of way to misuse and use the data.

So, we have to make sure what APP we are going to use. What are the guidelines by Info Security / IT authority?

Mantra is “Better than Ever”. Both technology & users are more advance. Do not put your data on risk. 

Think before use/install any APP. Do search, get suggestion, check reviews, and check it is from trusted publisher.

Let’s share you suggestion, experience & note…