Thursday, April 28, 2022

Use of Dictionary and List of Text Variable in Business Central

Hello Friends,

We can Lit of [Text] or Dictonaroty Variable for multiple business needs.

Here are example how we can use it practically

Use of Dictionary Variable to save Key and Value and Get from Index (List of text) List of Dictionary


Var
---
FieldValues: Dictionary of [Text, Text];

Add Code to for Key and Value
-----------------------------
Clear(FieldValues);
FieldValues.Add('InvoiceNumber', OriginalInvoiceNumber);

Below code will help to find all key and value and add in code
--------------------------------------------------------------
for i := 1 to FieldValues.Keys().Count() do
 if (FieldValues.ContainsKey(FieldValues.Keys().Get(i))) then
    NewInvoice := Replace(NewInvoice, FieldValues.Keys().Get(i),
FieldValues.Values().Get(i));

-------------------
Same way below code we use for get key and find value

LineHash: Dictionary of [Code[20], Decimal];

if not LineHash.ContainsKey(Rec."No.") then begin

    AvailableToSell := 0;

    if Rec.Type = Rec.Type::Item then begin

    Item.Get(REc."No.");

    If Item.Type = Item.Type::Inventory then

        AvailableToSell := ItemAvailability.GetAvailabletoSell(Item,
Rec."Location Code", Rec."Shipment Date");

    end;

    LineHash.Add(Rec."No.", AvailableToSell);

end;

exit(LineHash.Get(Rec."No."));

Use List of Text variable

field(LookUpCustomer; LookUpCustomer)
                    {
                        ApplicationArea = All;

                        trigger OnLookup(var Text: Text): Boolean
                        var
                            CustomerList_Page: Page "Customer List";
                            Customer_lRec: Record Customer;
                            i: Integer;
                        begin
                            Customer_lRec.Reset();
                            Clear(CustomerList_Page);
                            CustomerList_Page.Editable(false);
                            CustomerList_Page.LookupMode(true);
                            CustomerList_Page.SetTableView(Customer_lRec);
                            IF CustomerList_Page.RunModal = Action::LookupOK Then begin
                                CustomerList_Page.GetSelectionPIPE_gFnc(LookUpCustomer);
                                CustomListOfText_gList := LookUpCustomer.Split('|');

                                For i := 1 to CustomListOfText_gList.Count Do begin
                                    //Message(CustomListOfText_gList.Get(i));
                                    IF CustomListOfText_gList.Contains('CB000004') then
                                        Message('Yes')
                                    Else
                                        Message('No');
                                end;
                            end;
                        end;
                    }


    var
        LookUpCustomer: Text;
        CustomListOfText_gList: List of [Text];


https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/methods-auto/list/list-data-type

https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/methods-auto/dictionary/dictionary-data-type

Thank you for reading

I hope this will help someone

Keep Sharing...Keep Growing....

Thursday, April 21, 2022

Create Json Body - Multiple Level and Send Using HPPT Request in Business Central

Hello Friends,

Below is sample code to create multiple level Json Body Objects and send it on HTTP Request

Json Sample Body - need to generate:

{
        "type""media-notification",
        "mime""application/pdf",
        "link": http://454.356.45.467:7146/Attachment/OrderEntry_19_01_2022_17_00_01_2955.pdf,
        "body": {
            "to""919758642372",
            "ttl"200000,
            "type""template",
            "template": {
                "namespace""11382ca3_9ff1_467f_acab_c722c0920145",
                "language": {
                    "policy""deterministic",
                    "code""en"
                },
                "name""sales_invoice_update",
                "components": [
                    {
                        "type""header",
                        "parameters": [
                            {
                                "type""document",
                                "document": {
                                    "filename""Business-portal-connector-EULA.pdf"
                                }
                            }
                        ]
                    },
                    {
                        "type""body",
                        "parameters": [
                            {
                                "type""text",
                                "text""test"
                            },{
                                "type""text",
                                "text""{{text2}}"
                            },{
                                "type""text",
                                "text""{{text3}}"
                            },{
                                "type""text",
                                "text""{{text4}}"
                            },{
                                "type""text",
                                "text""{{text5}}"
                            },{
                                "type""text",
                                "text""{{text6}}"
                            }
                        ]
                    }
                ]
            }
        }
    }
================
Business Central AL Extension Code to Create Above body and send on HTTP Request

codeunit 76676 APIMgmt
{
    PROCEDURE TestWhatsapp(): Boolean
    VAR
        Win_lDlg: Dialog;


        FinalJobject: JsonObject;
        bodyJobject: JsonObject;
        templateJobject: JsonObject;
        languageJobject: JsonObject;
        componentsJArray: JsonArray;
        componentsHeaderJObject: JsonObject;
        componentsBodyJObject: JsonObject;
        parametersJArray: JsonArray;
        parametersJObject: JsonObject;
        DocumentJObject: JsonObject;
        parametersBodyJArray: JsonArray;
        parametersBodyJObject: JsonObject;

        ltext: Text;
        lheaders: HttpHeaders;
        lurl: Text;
        gcontent: HttpContent;
        gHttpClient: HttpClient;
        gheaders: HttpHeaders;
        greqMsg: HttpRequestMessage;
        gResponseMsg: HttpResponseMessage;
        JSONResponse: Text;
        JObject: JsonObject;
        Jtoken: JsonToken;
        JValue: JsonValue;

    BEGIN

        IF NOT CONFIRM('Do you want to Create API?', FALSE) THEN
            EXIT;

        Win_lDlg.OPEN('Processing...');

        Clear(FinalJobject);
        Clear(bodyJobject);
        Clear(templateJobject);
        Clear(languageJobject);
        Clear(componentsJArray);
        Clear(componentsHeaderJObject);
        Clear(componentsBodyJObject);
        Clear(parametersJArray);
        Clear(parametersJObject);
        Clear(DocumentJObject);
        Clear(parametersBodyJArray);
        Clear(parametersBodyJObject);

        //Main Body Objects
        FinalJobject.Add('type', 'media-notification');
        FinalJobject.Add('mime', 'application/pdf');
        FinalJobject.Add('link', 'http://XXXX.....1960_01_2955.pdf');

        //Body Objects
        bodyJobject.Add('to', '919426481901');
        bodyJobject.Add('ttl', 200000);
        bodyJobject.Add('type', 'template');

        templateJobject.Add('namespace', '11382ca3_9ff1_445f_acab_c722c0920173');

        languageJobject.Add('policy', 'deterministic');
        languageJobject.Add('code', 'en');

        templateJobject.Add('language', languageJobject);
        templateJobject.Add('name', 'sales_invoice_update');

        //Header Component
        componentsHeaderJObject.Add('type', 'header');
        parametersJObject.Add('type', 'document');
        DocumentJObject.Add('filename', 'Business-portal-connector-EULA.pdf');
        parametersJObject.add('document', DocumentJObject);
        parametersJArray.Add(parametersJObject);
        componentsHeaderJObject.Add('parameters', parametersJArray);

        componentsBodyJObject.Add('type', 'body');
        Clear(parametersBodyJObject);
        parametersBodyJObject.Add('type', 'text');
        parametersBodyJObject.Add('text', 'test');
        parametersBodyJArray.Add(parametersBodyJObject);
        Clear(parametersBodyJObject);
        parametersBodyJObject.Add('type', 'text');
        parametersBodyJObject.Add('text', '{{test2}}');
        parametersBodyJArray.Add(parametersBodyJObject);
        Clear(parametersBodyJObject);
        parametersBodyJObject.Add('type', 'text');
        parametersBodyJObject.Add('text', '{{test3}}');
        parametersBodyJArray.Add(parametersBodyJObject);
        Clear(parametersBodyJObject);
        parametersBodyJObject.Add('type', 'text');
        parametersBodyJObject.Add('text', '{{test4}}');
        parametersBodyJArray.Add(parametersBodyJObject);
        Clear(parametersBodyJObject);
        parametersBodyJObject.Add('type', 'text');
        parametersBodyJObject.Add('text', '{{test5}}');
        parametersBodyJArray.Add(parametersBodyJObject);
        Clear(parametersBodyJObject);
        parametersBodyJObject.Add('type', 'text');
        parametersBodyJObject.Add('text', '{{test6}}');
        parametersBodyJArray.Add(parametersBodyJObject);


        componentsBodyJObject.Add('parameters', parametersBodyJArray);


        componentsJArray.Add(componentsHeaderJObject);
        componentsJArray.Add(componentsBodyJObject);
        templateJobject.Add('components', componentsJArray);
        bodyJobject.Add('template', templateJobject);
        FinalJobject.Add('body', bodyJobject);


        FinalJobject.WriteTo(ltext);

        MESSAGE(FORMAT(ltext));

        lurl := 'https://app.yellowmessenger.com/integr80225396';

        gcontent.WriteFrom(ltext);
        greqMsg.SetRequestUri(lurl);
        lheaders.Clear();
        gcontent.GetHeaders(lheaders);




        lheaders.Add('x-auth-token', '231910d304bcad66eeb83b3770');

        lheaders.Remove('Content-Type');
        lheaders.Add('Content-Type', 'application/json');
        gcontent.GetHeaders(lheaders);
        greqMsg.Content(gcontent);
        greqMsg.GetHeaders(lheaders);
        greqMsg.Method := 'POST';
        if not gHttpClient.Send(greqMsg, gResponseMsg) then
            Error('API Authorization token request failed...');

        JSONResponse := '';
        gResponseMsg.Content().ReadAs(JSONResponse);

        Message(JSONResponse);

        if not JObject.ReadFrom(JSONResponse) then
            Error('Invalid response, expected a JSON object');



        Win_lDlg.CLOSE;
        EXIT(TRUE);
    END;
}


That's it
It is very simple to create Json Object and send it on using HTTP Request

Thank you for reading...
Keep Sharing....Keep Growing....

Tuesday, April 19, 2022

OAuth 2.0 API call from Business Central

 

Hello Friends,

 Below is sample code to call Auth 2.0 API in BC

Auth 2.0 using client credential method 

Microsoft provide all the different authentication method of Auth2.0 in standard codeunit (Codeunit OAuth2)

First we check our Key and Client Credential details Postman to verify it.



































BC Sample code to call oAuth2.0 API of BC

procedure GetActivationKey(var INTSetup: Record "CRM Integration Setup";
ShowDialog: Boolean)
    var
        gcontent: HttpContent;
        gHttpClient: HttpClient;
        gheaders: HttpHeaders;
        greqMsg: HttpRequestMessage;
        gResponseMsg: HttpResponseMessage;
        ltext: Text;
        lheaders: HttpHeaders;
        lurl: Text;
        Jobject: JsonObject;
        jarray: JsonArray;
        FlowResponse: Text;
        CRMIntegrationFlowLinks: Record "CRM Integration Flow Links";
        TotalCount: Integer;
        i: Integer;
        Jtoken: JsonToken;

        AccesstokenText: Text;
        Scopes: List of [Text];
        Accesstoken: Text;
        oAuth2: Codeunit OAuth2;
    begin
        if ShowDialog then
            if not Confirm('Do you want to Activate and update Activation Serial Key ?', false) then
                exit;

        INTSetup.TestField("Product Code");
        Scopes.Add('https://api.businesscentral.dynamics.com/.default');
//OAuth2.AcquireTokenWithClientCredentials(rec.clientid, rec.clientsecret,
rec.MicrosoftOAuth2Url, '', Scopes, Accesstoken);
        OAuth2.AcquireTokenWithClientCredentials('a2438b84-6537-486a-83af-7a158049b963',
'kCt7Q~hYhPLBXPpEmaYJleFTv9VvWw8d-~CSH',
'https://login.microsoftonline.com/f116a1e5-8088-46f5-a938-4360d60a8472/oauth2/v2.0/token',
'', Scopes, Accesstoken);

        lurl := 'https://api.businesscentral.dynamics.com/v2.0/f116a1e5-8088-46f5-a938-4360d60a8472/
Sandbox2/ODataV4/Company%28%27CRONUS%20USA%2C%20Inc.%27%29/
CustomerProductDetails?$filter=Product_Type%20eq%20%27'
+ INTSetup."Product Code" + '%27%20and%20Tenant_ID%20eq%20%27'
+ TenantId() + '%27%20and%20Blocked%20eq%20false';


        greqMsg.SetRequestUri(lurl);
        greqMsg.Method := 'get';
        gHttpClient.DefaultRequestHeaders.Add('Authorization', 'Bearer ' + AccessToken);
        gHttpClient.Send(greqMsg, gResponseMsg);


        FlowResponse := '';
        gResponseMsg.Content().ReadAs(FlowResponse);
        if not JObject.ReadFrom(FlowResponse) then
            Error('Invalid response, expected a JSON object \Response: \%1', FlowResponse);

        JObject.Get('value', Jtoken);

        if not Jarray.ReadFrom(Format(Jtoken)) then
            Error('Array not Reading Properly');

        if Jarray.Count = 0 then begin
            INTSetup."Serial Key" := '';
            INTSetup.Modify(true);
            Message('No Activation key found with Product Code: %1 and Tenant ID: %2',
INTSetup."Product Code", TenantId());
            exit;
        end;

        Jarray.Get(0, Jtoken);
        if Jtoken.AsObject.Get('Serial_Key', Jtoken) then begin
            INTSetup.validate("Serial Key", Jtoken.AsValue().AsCode());
            INTSetup.Modify(true);
            if ShowDialog then
                Message('Serial Key Updated!');
        end else begin
            INTSetup."Serial Key" := '';
            INTSetup.Modify(true);
            message('Activation API Failed: %1', FlowResponse);
        end;
    end;

Saturday, April 16, 2022

Error - The Windows account specified in 'Service Account' does not have permission to run services on this computer.

 Hello Friends,


While install Business Central on-prime version, If you setup servie user login account in installation than it will give error for user account if the user not added in Log in as service account

Below Error Message normally come

The Windows account specified in 'Service Account' does not have permission to run services on this computer. Please use another account or add the right to log on as a service to the current account

We can simply solve this error by adding service user on group policy

Below are simple steps to do this.

1. Go to start and serach for Local Security Policy












2.  Go To Local Policies --> User Rights Assignment --> Log on as a Service --> Add Your Service User here

3. Done Now you can install BC with user account
Thank you for reading...
I hope this help someone
Keep Sharing.....Keep Grwoing....



Tuesday, April 12, 2022

NAV 2016 Crash - Windows Application Not Working

Hello Friends,

Sunddenly in All User PC (with Windows 10) start crash NAV 2016 version

We face same issue with multiple custom in last one week

NAV working fine before on same machine and suddenly on next day it was stop working.

It is look like some new windows 10 update not compatible with NAV 2016 Version

Total 40+ User PC face same issue (all the users from different customers)

If we restore PC with one week back restore point than it is start working.... else next option is format PC and install again everything

Below error coming in event viewer while start NAV

Issue:

Application: Microsoft.Dynamics.Nav.Client.exe

Framework Version: v4.0.30319

Description: The process was terminated due to an unhandled exception.

Exception Info: System.NullReferenceException

   at Microsoft.Dynamics.Nav.Client.WinClientExcelExportService.FindMajorVersion(Microsoft.Win32.RegistryKey)

   at Microsoft.Dynamics.Nav.Client.WinClientExcelExportService.<.ctor>b__0(Microsoft.Win32.RegistryKey)

   at Microsoft.Dynamics.Nav.Client.WinClientExcelExportService.FindRegistryKey(Microsoft.Win32.RegistryHive, System.String, System.Action`1<Microsoft.Win32.RegistryKey>)

   at Microsoft.Dynamics.Nav.Client.WinClientExcelExportService.FindFirstRegistryKey(System.String, System.Action`1<Microsoft.Win32.RegistryKey>)

   at Microsoft.Dynamics.Nav.Client.WinClientExcelExportService..ctor(Microsoft.Dynamics.Framework.UI.UISession)

   at Microsoft.Dynamics.Nav.Client.WinClient.NavWinFormsClientSession.<AddServices>b__6(Microsoft.Dynamics.Framework.UI.UISession)

   at Microsoft.Dynamics.Framework.UI.ClientSessionCore.AddUIService(System.Func`2<Microsoft.Dynamics.Framework.UI.UISession,Microsoft.Dynamics.Framework.UI.IUIService>)

   at Microsoft.Dynamics.Nav.Client.WinClient.NavWinFormsClientSession.AddServices()

   at Microsoft.Dynamics.Framework.UI.ClientSessionCore.Prepare()

   at Microsoft.Dynamics.Nav.Client.WinClient.StartWinFormsClient.SetupClientSession()

   at Microsoft.Dynamics.Nav.Client.WinClient.StartWinFormsClient.RunCore()

   at Microsoft.Dynamics.Nav.Client.WinClient.StartWinFormsClient.Run(Boolean)

   at Microsoft.Dynamics.Nav.Client.Program.Main(System.String[])




Solution:

This issue seems either a Windows update or an Office update.

Please try the below mitigation steps:
1. Do an online repair of the Office 365, as this will correct the security setting of these DLL after the update was done.

2. Doing manually changes to the security settings seems to work as well, but will be reverted after some time as were notified.
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\App Paths\excel.exe in regedit and add value to the (Default) key with C:\Program Files (x86)\Microsoft Office\root\Office16\Excel.exe. 

We do have updated the blog (99+) Windows Client crashes with System.NullReferenceException after Windows Update - Dynamics 365 Business Central Forum Community Forum for the same.

 NOTE: PG will only fix NAV 2018 and BC 14.x. Platform hotfix is contained in the upcoming May CUs (ETA 6th May). 

All other versions that are out of support or out of mainstream support will not have any out of band hotfix. 

Solution for these is to upgrade to a supported version or create a scheduled task with a script that add the registry key at startup (or something on this flavor).

============

Done.

Thank you for reading

Keep Sharing....Keep Growing.....