Real things I’m asked – Add Test Users to a Business Central Docker Container

Q: How do I add test users to a Microsoft Dynamics 365 Business Central Docker Container?

A: You use the Setup-BcContainerTestUsers function in BCContainerHelper to load test users.

You can load either Essential or Premium users with the Setup-BcContainerTestUsers function.

When working with a Business Central Container that has the following Users:

New test users can be added with the Setup-BcContainerTestUsers function:

#set the userName, password and containerName values for your use
$userName = 'admin'
$password = 'password'
$containerName = 'your container'
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($userName, $securePassword)


# the $SecurePassword is the password  that the new test users will use when logging into Business Central
Setup-BcContainerTestUsers -containerName $containerName -select Essential -Password $securePassword -credential $Credential
Setup-BcContainerTestUsers -containerName $containerName -select Premium -Password $securePassword -credential $Credential  

After setting up the test users with the Setup-BcContainerTestUsers function in BCContainerHelper:

The new TestUsers can access the system using the password used in the Password parameter.

Note: You need to specify credentials when not using Windows Authentication.
The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online and BCContainerHelper Version 4.0.8. 

January 2023 Cumulative Updates for Dynamics 365 Business Central and Microsoft Dynamics NAV

The January updates for Microsoft Dynamics NAV and Microsoft Dynamics 365 Business Central are now available.

Before applying the updates, you should confirm that your implementation is ready for the upgrade and ensure compatibility with your modifications. Work with a Microsoft Partner to determine if you are ready and what is needed for you to apply the update.

Please note that SaaS customers will automatically be upgraded to 21.3 over the coming days/weeks and should receive an email notification when upgraded.

Direct links to the cumulative updates are listed here:

Dynamics 365 Business Central On-Premises 2022 Release Wave 2 Updates – Update 21.3 (January 2023)

Dynamics 365 Business Central On-Premises 2022 Release Wave 1 Updates – Update 20.9 (January 2023)

Dynamics 365 Business Central On-Premises 2021 Release Wave 2 Updates – Update 19.15 (January 2023)

Dynamics 365 Business Central On-Premises 2021 Release Wave 1 Updates – Update 18.18 (October 2022)

Dynamics 365 Business Central On-Premises 2020 Release Wave 2 Updates – Update 17.17 (April 2022)

Dynamics 365 Business Central On-Premises 2020 Release Wave 1 Updates – Update 16.19 (January 2022)

Dynamics 365 Business Central On-Premises 2019 Release Wave 2 Updates – Update 15.17 (April 2021)

Dynamics 365 Business Central On-Premises Spring 2019 Updates – Update 43 (January 2023)

Dynamics 365 Business Central On-Premises October’18 Updates – Update 18 (April 2020)

Microsoft Dynamics NAV 2018 – Update 60 (January 2023)

Microsoft Dynamics NAV 2017 – Update Update 61 (January 2022)

Microsoft Dynamics NAV 2016 – Update 67 (July 2021)

Dynamics 365 Business Central – TryFunction

The TryFunction attribute in AL, when developing for Microsoft Dynamics 365 Business Central, indicates that a method is a Try method.

A Try method in AL enables you to handle errors that occur in the application during code execution. For example, with try methods, you can provide more user-friendly error messages or manage the execution of code on an error.

A method in AL marked with TryFunction Attribute will execute any code within the method function as a Try [to execute the code] block. If the code executes without raising an error, it will return a true result and a false one in the case of an error.

In the following example, there are three separate methods for comparing integers. All three methods will generate an error if two integers are not equal.

var
    NotEqualErr: label 'Values must be equal.';

procedure CompareIntegers(a: integer; b: Integer)
begin
    if (a <> b) then
        Error(NotEqualErr);
end;

[TryFunction]
procedure TryCompareIntegers(a: Integer; b: integer)
begin
    if (a <> b) then
        Error(NotEqualErr);
end;

[TryFunction]
procedure TryCompareIntegersMulti(a: Integer; b: integer)
begin
    CompareIntegers(a, b);
end;

Calling the first method with two non-matching integers will generate an error:

CompareIntegers(6, 5);

The second and third methods are marked with the TryFunction Attribute, and we can code to check if the methods executed without error:

If not TryCompareIntegers(6, 5) then
            Message('Try Failed.');

When a method is marked with the TryFunction Attribute it will allow for catching of errors with the callstack as with the third method:

If not TryCompareIntegersMulti(6, 5) then
            Message('Try Multi Failed.');

Note: Calling the TryFunction methods without checking for an error in execution will result in normal error processing.

You can learn more about the TryFunction Attribute in Dynamics 365 Business Central here.

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.

Dynamics 365 Business Central – JSON Object into a Dictionary Data Type

The Dictionary Data Type represents an unordered collection of keys and values and is optimized for fast lookup of values. Each addition to the dictionary consists of a value and its associated key. Every key in a Dictionary must be unique. It is on my list of favorite “new” AL Data Types, and I find it often easier to work with a dictionary than another object type.

In this example, a JSON Object’s value keys (not the array or object keys) are copied into a Dictionary Data Type variable.

procedure JsonObjectValuestoDictionary(JObject: JsonObject; var ObjectDictionary: Dictionary of [Text, Text])
var
    IsHandled: Boolean;
    JsonToken: JsonToken;
    DuplicateKeyErr: label 'Duplicate Key %1', Comment = '%1 Key Name';
    ObjectKeys: List of [Text];
    JKey: Text;
    JValue: Text;
begin
    Clear(ObjectDictionary);

    OnBeforeJsonObjectValuestoDictionary(JObject, ObjectDictionary, IsHandled);
    if IsHandled then
        exit;

    ObjectKeys := JObject.Keys();
    foreach JKey in ObjectKeys do begin
        JObject.Get(Jkey, JsonToken);
        if JsonToken.IsValue then begin
            if ObjectDictionary.ContainsKey(JKey) then
                Error(DuplicateKeyErr, JKey);
            JsonToken.WriteTo(JValue);
            ObjectDictionary.Add(DelChr(JKey, '=', '"'), DelChr(JValue, '=', '"'));
        end;
    end;

    OnAfterJsonObjectValuestoDictionary(JObject, ObjectDictionary);
end;

[BusinessEvent(false)]
local procedure OnAfterJsonObjectValuestoDictionary(JObject: JsonObject; var ObjectDictionary: Dictionary of [Text, Text])
begin
end;

[BusinessEvent(false)]
local procedure OnBeforeJsonObjectValuestoDictionary(JObject: JsonObject; var ObjectDictionary: Dictionary of [Text, Text]; var Handled: Boolean)
begin
end;
You can learn more about Dictionary Data Types in Dynamics 365 Business Central here.

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.

Dynamics 365 Business Central – Read a JSON File with AL

A JSON (JavaScript Object Notation) file is a standard text file used to store data in a structured, organized way. It is a simple, human-readable format often used for transmitting data between a server and a web application or between different systems.

A JSON file consists of a series of key-value pairs separated by commas. The keys are always strings, and the values can be strings, numbers, booleans, arrays, or objects.

I had previously discussed an example demonstrating a basic model with enough information to create a simple JSON file with AL for Microsoft Dynamics 365 Business Central. The example created a JSON file displayed here:

{
    "Customer": {
        "No": "10000",
        "Address": "192 Market Square",
        "Address_2": "",
        "City": "",
        "County": "NJ",
        "Country_Region": "US",
        "Post_Code": "",
        "Ship-to": [
            {
                "Code": "LEWES ROAD",
                "Address": "2 Lewes Road",
                "Address_2": "",
                "City": "Atlanta",
                "County": "GA",
                "Post_Code": "31772"
            },
            {
                "Code": "PARK ROAD",
                "Address": "10 Park Road",
                "Address_2": "",
                "City": "Atlanta",
                "County": "GA",
                "Post_Code": "31772"
            }
        ]
    }
}

The example below shows a basic model to provide enough information to get started reading a simple JSON, resembling the file above, with AL for Microsoft Dynamics 365 Business Central using Codeunit 5459 “JSON Management.”

There are many ways to code a solution, and opinion or situation determines the best (including the Json datatypes). Codeunit 5459 “JSON Management” has many methods for working with JSON files. I encourage you to explore the codeunit.

local procedure ReadJSON(JsonObjectText: Text)
    var
        Customer: Record Customer;
        ShiptoAddress: Record "Ship-to Address";
        ArrayJSONManagement: Codeunit "JSON Management";
        JSONManagement: Codeunit "JSON Management";
        ObjectJSONManagement: Codeunit "JSON Management";
        i: Integer;
        CodeText: Text;
        CustomerJsonObject: Text;
        JsonArrayText: Text;
        ShipToJsonObject: Text;
    begin
        JSONManagement.InitializeObject(JsonObjectText);
        if JSONManagement.GetArrayPropertyValueAsStringByName('Customer', CustomerJsonObject) then begin
            ObjectJSONManagement.InitializeObject(CustomerJsonObject);

            Customer.Init();
            ObjectJSONManagement.GetStringPropertyValueByName('No', CodeText);
            Customer.Validate("No.", CopyStr(CodeText.ToUpper(), 1, MaxStrLen(Customer."No.")));
            ObjectJSONManagement.GetStringPropertyValueByName('Address', CodeText);
            Customer.Validate("Address", CopyStr(CodeText, 1, MaxStrLen(Customer."Address")));
            Customer.Insert();

            JSONManagement.InitializeObject(CustomerJsonObject);
            if JSONManagement.GetArrayPropertyValueAsStringByName('Ship-to', JsonArrayText) then begin
                ArrayJSONManagement.InitializeCollection(JsonArrayText);
                for i := 0 to ArrayJSONManagement.GetCollectionCount() - 1 do begin
                    ArrayJSONManagement.GetObjectFromCollectionByIndex(ShipToJsonObject, i);
                    ObjectJSONManagement.InitializeObject(ShipToJsonObject);

                    ShiptoAddress.Init();
                    ShiptoAddress.Validate("Customer No.", Customer."No.");
                    ObjectJSONManagement.GetStringPropertyValueByName('Code', CodeText);
                    ShiptoAddress.Validate("Code", CopyStr(CodeText.ToUpper(), 1, MaxStrLen(ShiptoAddress.Code)));
                    ShiptoAddress.Validate("Address", CopyStr(CodeText, 1, MaxStrLen(ShiptoAddress.Address)));
                    ShiptoAddress.Insert();

                end;
            end;
        end;
    end;

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.

Dynamics 365 Business Central – Manage Purchase Prices

In Microsoft Dynamics 365 Business Central, the purchase price is the price at which a business purchases goods or services from a vendor. The purchase price is used to track the cost of goods or services that a business acquires.
The purchase price in Microsoft Dynamics 365 Business Central is important for determining the business’s profitability and calculating the gross margin for each product or service.

The purchase price may be a fixed price agreed upon between the business and the vendor or based on market conditions or other factors. It may also vary based on the number of goods or services purchased, with larger quantities often receiving a lower purchase price.

Working with Purchase Prices

In Microsoft Dynamics 365 Business Central, the simplest way to see the purchase price of an item is on the item card. When an item is entered on a purchase document, the value in the Last Direct Cost field determines the purchase price. The Last Direct Cost specifies the item’s most recent direct unit cost. The Last Direct Cost value is updated as purchase documents for the item are posted.

If you need more complex purchase pricing you can setup Purchase Prices for Items and Vendors.

Setup Purchase Prices

  • Open the Purchase Prices page from the Item Card by selecting the Purchases Prices action from the Prices & Discounts Menu.

     

  • On the Purchase Prices page, enter the Vendor specific pricing information
    • Vendor No. Specifies the number of the Vendor to which the purchase price applies.
    • Item No. – Specifies the number of the item to which the purchase price applies.
    • Unit of Measure Code – Specifies the purchase unit of the item to which the purchase price applies.
    • Minimum Quantity – Specifies the minimum purchase quantity of the item you must buy from the Vendor to get the purchase price.
    • Direct Unit Cost – Specifies the purchase price (cost) of one unit of the selected item to which the purchase price applies.
    • Starting Date – Specifies the date from which the purchase price is valid.
    • Ending Date – Specifies the date to which the purchase price is valid.

 

You can learn more about Managing Purchase prices in Dynamics 365 Business Central here.

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.

Real things I’m asked – add a field to the DropDown

  • Q: Can you add the “Search Description” to the Item DropDown?

A: Yes. In Microsoft Dynamics 365 Business Central, the DropDown fieldgroup determines the fields displayed when showing records on a dropdown page. 

Additional fields can be added to the DropDown fieldgroup using the addlast keyword in an AL Table Extension. Base table and new fields can be added to the DropDown fieldgroup.

tableextension 50100 "DVLPR Item Ext" extends Item
{
    fields
    {
        field(50100; "DVLPR New Field"; Boolean)
        {
            Caption = 'New Field';
            DataClassification = CustomerContent;
        }
    }

    fieldgroups
    {
        addlast(DropDown; "DVLPR New Field", "Search Description")
        { }
    }
}

Note: The syntax for using a DropDown must be exactly DropDown with the correct capitalization. The server will remove the duplicates if multiple extensions attempt to add the same field more than once. Fields can only be added to the field group once. Fields can only be added with addlast and fields cannot be removed through a Table Extension.

Click here to learn more about Field Groups (DropDown Controls) in Microsoft Dynamics 365 Business Central.

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.

Dynamics 365 Business Central – Manage Sales Prices

In today’s price-sensitive market, a business needs flexibility when setting selling prices for products. A flexible sales price model is important for businesses because it allows them to tailor their pricing strategy to meet the needs of their customers and the market. A flexible sales price model can also help businesses be more competitive in the market. For example, if a business can offer lower prices for larger quantities of an item, it may attract more customers and increase sales. Similarly, if a business can offer customized pricing for different customer groups, it can retain customers and build loyalty.

Microsoft Dynamics 365 Business Central provides several price strategies, allowing a business to offer flexible and competitive pricing strategies. Sales Prices can be for all customers, specific customers, customer price groups, or sales campaigns. These prices may include conditions such as order date, unit of measure, or minimum quantity purchased.

Working with Sales Prices

In Microsoft Dynamics 365 Business Central, the simplest way to set an item’s sales price is on the item card. The unit price on the item card is an item’s price based on its unit of measure. The unit price is manually or calculated automatically based on the cost of the Item and the desired markup or margin by setting the Price/Profit Calculation value.

If a business requires more flexible Sales Price options, such as a price for a specific Customer or Order Date range:

  • Open the Sales Prices page from the Item Card by selecting the Sales Prices action from the Prices & Discounts Menu.
  • Enter the Sales Type for the price
    • Customer – the price is for a specific Customer
    • Customer Price Group – the price is for Customers assigned to a Price Group.
    • All Customers – the price is for All Customers.
    • Campaign – the price for a Sales Campaign
  • Sales Code – enter the value related to the Sales Type value for the Sales Price. 
    •  Sales Type of Customer – Enter the Customer No for the Customer that receives the Sales Price
    • Sales Type of Customer Price Group – Enter the Price Group for the Group that receives the Sales Price
    • Sales Type of All Customers – no value entered
    • Sales Type of Campaign – Enter the Campaign that receives the Sales Price
  • Item No. – enter the Item No. for the Sales Price 
  • Minimum Quantity – if the Sales Price is applicable for a minimum quantity ordered for the Item, enter the minimum quantity needed to receive the Sales Price.
  • Starting Date and Ending Date – If the Sales Price is effective for a specific date range, enter the starting and ending date for the date range the Sales Price is valid
  • Unit Price – the Sales Price for the Item, for the Sales Price options.

When working with Sales Prices for a Customer Price Group, a Customer is assigned to a Price Group by setting the Customer Price Group value on the Invoicing Fast Tab on the Customer Card.

When working with Sales Prices for a Campaign, Sales Documents assigned to a specific Campaign will receive a Campaign specific sales price.

Sales Prices are also accessible from the Prices action on the Prices & Discounts menu on the Customer Card. Opening the Sales Prices page from the Customer Card allows setting prices for a specific customer.

Business Central applies the best price principle. This means that the lowest price for an item is used on a sales line, but only if all conditions are met.

You can learn more about Managing Sales prices in Dynamics 365 Business Central here.

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.

Dynamics 365 Business Central 2022 Wave 2 – January 2023

With each Wave update of Dynamics 365 Business Central, Microsoft publishes a list of What’s new and planned for Dynamics 365 Business Central. Not all published features are “generally available” upon the initial wave release. Some features “roll in” during the wave. Here is a listing of what is published to “wave in” January 2023.

Application

Feature Enabled for Public preview General availability
Reverse payment reconciliation journal entries Users, automatically Jan 2023 Jan 2023

Governance and administration

Feature Enabled for Public preview General availability
Get more visibility into service interruptions Users, automatically Jan 2023 Jan 2023
Get more, better communications as admin Admins, makers, marketers, or analysts, automatically Jan 2023 Jan 2023
Restore deleted environments Admins, makers, marketers, or analysts, automatically Jan 2023 Jan 2023
Restore environments to point in time Admins, makers, marketers, or analysts, automatically Jan 2023 Jan 2023
Restrict traffic on system integrations with service tags Admins, makers, marketers, or analysts, automatically Jan 2023 Jan 2023

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft documents published at the time of this posting.

Dynamics 365 Business Central – Create a JSON File with AL

JSON (JavaScript Object Notation) is an open standard file format that uses human-readable text to store and transmit data objects consisting of attribute–value pairs and arrays (or other serializable values).

In today’s digital age, the exchange of data between Microsoft Dynamics 365 Business Central and other systems is often necessary. In a previous post, I covered a basic example of creating an XML file with AL. Along with XML files, I am often asked how to generate JSON files. Here is an example of creating a basic JSON file in AL.

The  example below demonstrates a basic model to provide enough information to create a simple file; consider it “Getting Started.” There are many ways to code a solution, and opinion or situation determines the best. Within Microsoft Dynamics 365 Business Central, JSON can be processed codeunit 5459 “JSON Management.” I  do use this codeunit often and may cover this example using the codeunit in the future.


    local procedure CreateJSON(Customer: Record Customer)
    var
        ShiptoAddress: Record "Ship-to Address";
        JArray: JsonArray;
        CustObject: JsonObject;
        JsonObject: JsonObject;
        ShiptoObject: JsonObject;
        JsonData: Text;

    begin
        Clear(JsonObject);
        Clear(CustObject);

        CustObject.Add('No', Customer."No.");
        CustObject.Add('Address', Customer.Address);
        CustObject.Add('Address_2', Customer."Address 2");
        CustObject.Add('City', Customer.City);
        CustObject.Add('County', Customer.County);
        CustObject.Add('Country_Region', Customer."Country/Region Code");
        CustObject.Add('Post_Code', Customer."Post Code");

        ShiptoAddress.SetRange("Customer No.", Customer."No.");
        if ShiptoAddress.FindSet() then begin
            Clear(JArray);
            repeat
                Clear(ShiptoObject);
                ShiptoObject.Add('Code', ShiptoAddress.Code);
                ShiptoObject.Add('Address', ShiptoAddress.Address);
                ShiptoObject.Add('Address_2', ShiptoAddress."Address 2");
                ShiptoObject.Add('City', ShiptoAddress.City);
                ShiptoObject.Add('County', ShiptoAddress.County);
                ShiptoObject.Add('Post_Code', ShiptoAddress."Post Code");
                JArray.Add(ShiptoObject);
            until ShiptoAddress.Next() = 0;
            CustObject.Add('Ship-to', JArray);
        end;

        JsonObject.Add('Customer', CustObject);

        JsonObject.WriteTo(JsonData);

    end;

The above code creates the JSON file displayed here:

{
    "Customer": {
        "No": "10000",
        "Address": "192 Market Square",
        "Address_2": "",
        "City": "",
        "County": "NJ",
        "Country_Region": "US",
        "Post_Code": "",
        "Ship-to": [
            {
                "Code": "LEWES ROAD",
                "Address": "2 Lewes Road",
                "Address_2": "",
                "City": "Atlanta",
                "County": "GA",
                "Post_Code": "31772"
            },
            {
                "Code": "PARK ROAD",
                "Address": "10 Park Road",
                "Address_2": "",
                "City": "Atlanta",
                "County": "GA",
                "Post_Code": "31772"
            }
        ]
    }
}

Note: The code and information discussed in this article are for informational and demonstration purposes only. This content was created referencing Microsoft Dynamics 365 Business Central 2022 Wave 2 online.