JSON Reader

 


codeunit 50390 "JSon Mgt.1.0"
{
    trigger OnRun()
    begin

    end;


    procedure GetJsonValue(var json_Object: JsonObject; Property: Text; var json_Value: JsonValue): Boolean
    var
        json_Token: JsonToken;
    begin
        if not json_Object.Get(Property, json_Token) then
            exit;
        json_Value := json_Token.AsValue();
        exit(true);
    end;



    procedure GetJsonValueAsText(var json_Object: JsonObject; Property: Text) Value: Text
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsText;
    end;

    procedure GetJsonValueAsBoolean(var json_Object: JsonObject; Property: Text) Value: Boolean
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsBoolean();
    end;

    procedure GetJsonValueAsInteger(var json_Object: JsonObject; Property: Text) Value: Integer
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsInteger();
    end;

    procedure GetJsonValueAsDecimal(var json_Object: JsonObject; Property: Text) Value: Decimal
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsDecimal();
    end;

    procedure GetJsonValueAsDateTime(var json_Object: JsonObject; Property: Text) Value: DateTime
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsDateTime();
    end;

    procedure GetJsonValueAsDate(var json_Object: JsonObject; Property: Text) Value: Date
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsDate();
    end;

    procedure GetJsonValueAsTime(var json_Object: JsonObject; Property: Text) Value: Time
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsTime();
    end;

    procedure GetJsonValueAsCode(var json_Object: JsonObject; Property: Text) Value: Code[2000]
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsCode();
    end;

    procedure GetJsonValueAsDuration(var json_Object: JsonObject; Property: Text) Value: Duration
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsDuration();
    end;

    procedure GetJsonValueAsChar(var json_Object: JsonObject; Property: Text) Value: Char
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsChar();
    end;

    procedure GetJsonValueAsByte(var json_Object: JsonObject; Property: Text) Value: Byte
    var
        json_Value: JsonValue;
    begin
        if not GetJsonValue(json_Object, Property, json_Value) then
            exit;
        Value := json_Value.AsByte();
    end;


    procedure GetJsonToken(json_Object: JsonObject; tokenKey: Text) json_Token: JsonToken;
    begin
        if not json_Object.Get(tokenKey, json_Token) then
            Error('Token not found with key %1', tokenKey);
    end;

    procedure SelectJsonToken(json_object: JsonObject; path: Text) json_Token: JsonToken;
    begin
        if not json_object.SelectToken(path, json_Token) then
            Error('Token not found with path %1', path);

    end;

    /***********************************************************xml************/

    procedure CreateBaseXMLDoc(NamespacePrefix: Text; NamespaceUri: Text): XmlDocument
    var
        XMLDoc: XmlDocument;
        XMLDec: XmlDeclaration;
        XMLElem: XmlElement;
        XMLElem2: XmlElement;
        XMLAtr: XmlAttribute;
    begin
        XMLDoc := XmlDocument.Create();

        XMLDec := XmlDeclaration.Create('1.0', 'UTF-8', 'yes');
        XMLDoc.SetDeclaration(XMLDec);

        xmlElem := xmlElement.Create('Envelope', NamespaceUri);

        XMLAtr := XmlAttribute.CreateNamespaceDeclaration('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
        XMLElem.Add(XMLAtr);
        XMLAtr := XmlAttribute.CreateNamespaceDeclaration('xsd', 'http://www.w3.org/2001/XMLSchema');
        XMLElem.Add(XMLAtr);
        XMLAtr := XmlAttribute.CreateNamespaceDeclaration(NamespacePrefix, NamespaceUri);
        XMLElem.Add(XMLAtr);

        xmlElem2 := XmlElement.Create('Header', NamespaceUri);
        xmlElem.Add(xmlElem2);

        Clear(xmlElem2);
        xmlElem2 := XmlElement.Create('Body', NamespaceUri);
        xmlElem2.Add(xmlText.Create(''));

        xmlElem.Add(xmlElem2);
        xmlDoc.Add(xmlElem);

        exit(XMLDoc);
    end;

    local procedure AddChildElementWithTxtValue(var inXMLElem: XmlElement; LocalName: Text; NamespaceUri: Text; inValue: Text);
    var
        CData: XmlCData;
    begin
        CData := XmlCData.Create('');
        AddChildElementWithCdataTxtValue(inXMLElem, LocalName, NamespaceUri, inValue, CData)
    end;

    local procedure AddChildElementWithCdataTxtValue(var inXMLElem: XmlElement; LocalName: Text; NamespaceUri: Text; inValue: Text; CData: XmlCData)
    var
        XMLEelem: XmlElement;
    begin
        if NamespaceUri <> '' then
            XMLEelem := XmlElement.Create(LocalName, NamespaceUri)
        else
            XMLEelem := XmlElement.Create(LocalName);
        XMLEelem.Add(xmlText.Create(inValue));
        if CData.Value() <> '' then
            XMLEelem.Add(CData);
        inXMLElem.Add(XMLEelem);
    end;

    procedure GetValueFromXML(Content: Text; pNodePath: Text): Text
    var
        XMLRootNode: XmlNode;
        XMLChildNode: XmlNode;
        XMLElem: XmlElement;
    begin
        GetRootNode(ConvertTextToXmlDocument(Content), XMLRootNode);

        XMLRootNode.SelectSingleNode(pNodePath, XMLChildNode);
        XMLElem := XMLChildNode.AsXmlElement();
        exit(XMLElem.InnerText());
    end;

    procedure ConvertTextToXmlDocument(Content: Text): XmlDocument
    var
        XmlDoc: XmlDocument;
    begin
        if XmlDocument.ReadFrom(Content, XmlDoc) then
            exit(XmlDoc);
    end;

    procedure GetRootNode(pXMLDocument: XmlDocument; var pFoundXMLNode: XmlNode)
    var
        lXmlElement: XmlElement;
    begin
        pXMLDocument.GetRoot(lXmlElement);
        pFoundXMLNode := lXmlElement.AsXmlNode();
    end;

    var
        SOAP11NamespaceURILbl: Label 'http://schemas.xmlsoap.org/soap/envelope/', Locked = true;
        SOAP12NamespaceUriLbl: Label 'http://www.w3.org/2003/05/soap-envelope', Locked = true;
        W3BaseNamespaceUriLbl: Label 'https://www.w3schools.com/xml/', Locked = true;
        SOAP11XMLContentTypeLbl: Label 'text/xml; charset=utf-8', Locked = true;
        SOAP12XMLContentTypeLbl: Label 'application/soap+xml; charset=utf-8', Locked = true;
        W3ActionUriLbl: Label 'tempconvert.asmx', Locked = true;
        LocalXPathSignatureLbl: Label '[local-name()="%1"]', Locked = true;
        LocalXPathSeparatorLbl: Label '/*', Locked = true;
        BodyXPathLbl: Label '/*[local-name()="Envelope"]/*[local-name()="Body"]', Locked = true;
        ErrorLbl: Label 'Error', Locked = true;


    var
        JSOn: Codeunit "JSON Management";

}



Continue Reading...

Http Class In Business (API)

GET

POST

PATCH


 codeunit 50391 HttpWebRequest

{
    trigger OnRun()
    begin


    end;


    procedure APITestConnection(Methode: Code[10]; UserName: Text; Password: Text; Domain: Code[100];
            url: text; var ResponseString: Text; var ErrorTxt: Text
             )
    begin
        Clear(Client);
        Clear(Request);
        Clear(Content);
        Clear(Headers);
        Client.SetBaseAddress(Url);
        Client.UseWindowsAuthentication(UserName, Password, Domain);
        Request.Method('GET');
        Content.GetHeaders(Headers);
        Headers.Remove('Content-Type');
        Client.DefaultRequestHeaders.Add('User-Agent', 'Dynamics 365');
        Headers.Add('Content-Type', 'application/json;odata.metadata=none');

        Client.Timeout(15000);
        if Not Client.Send(Request, Response) then
            ErrorTxt := ('The call to the web service failed.');

        if not Response.IsSuccessStatusCode() then
            ErrorTxt := ('Status code: ' + Format(Response.HttpStatusCode()) +
                    ' Description: ' + Response.ReasonPhrase())
        else
            Response.Content().ReadAs(ResponseString);

        If ResponseString <> '' then begin

            // JObject.ReadFrom(ResponseString);
            // JObject.Get('displayName', JToken);
            // ResponseString := 'Test is ok , Company Name  : ' + Jtoken.AsValue().AsText();


        end;

    end;


    procedure GETRequest(UserName: Text; Password: Text; Domain: Code[100];
    url: text; var ResponseString: Text; var ErrorTxt: Text
    )
    begin

        Clear(Client);
        Clear(Request);
        Clear(Content);
        Clear(Headers);
        Client.SetBaseAddress(Url);
        Client.UseWindowsAuthentication(UserName, Password, Domain);
        Request.Method('GET');
        Content.GetHeaders(Headers);
        Headers.Remove('Content-Type');
        Client.DefaultRequestHeaders.Add('User-Agent', 'Dynamics 365');
        Headers.Add('Content-Type', 'application/json;odata.metadata=none');

        Client.Timeout(15000);
        if Not Client.Send(Request, Response) then
            ErrorTxt := ('The call to the web service failed.');

        if not Response.IsSuccessStatusCode() then
            ErrorTxt := ('Status code: ' + Format(Response.HttpStatusCode()) +
                    ' Description: ' + Response.ReasonPhrase())
        else
            Response.Content().ReadAs(ResponseString);
        PurchHeaderInit(ResponseString);

    end;

    procedure PatchRequest(UserName: Text; Password: Text; Domain: Code[100];
   url: text; var ResponseString: Text; var ErrorTxt: Text
   )
    begin

        Clear(Client);
        Clear(Request);
        Clear(Content);
        Clear(Headers);
        Client.SetBaseAddress(Url);
        Client.UseWindowsAuthentication(UserName, Password, Domain);
        Request.Method('GET');
        Content.GetHeaders(Headers);
        Headers.Remove('Content-Type');
        Client.DefaultRequestHeaders.Add('User-Agent', 'Dynamics 365');
        Headers.Add('Content-Type', 'application/json');
        Headers.Add('If-Match', '*');

        Client.Timeout(15000);
        if Not Client.Send(Request, Response) then
            ErrorTxt := ('The call to the web service failed.');

        if not Response.IsSuccessStatusCode() then
            ErrorTxt := ('Status code: ' + Format(Response.HttpStatusCode()) +
                    ' Description: ' + Response.ReasonPhrase())
        else
            Response.Content().ReadAs(ResponseString);


    end;

    procedure PurchHeaderInit(JsonText: text)
    begin
        Clear(TempPurchaseHeader);
        if not JObject.ReadFrom(JsonText) then
            Error('Invalid response, expected a JSON object');

        JObject.Get('value', Jtoken);

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

        TotalCount := 0;
        OrderCount := 0;
        TotalCount := Jarray.Count();
        for i := 0 to Jarray.Count() - 1 do begin
            Jarray.Get(i, Jtoken);

            JObject := Jtoken.AsObject();

            IF Jtoken.AsObject.Get('No', Jtoken) then begin

                TempPurchaseHeader.INIT;
                TempPurchaseHeader."Document Type" := TempPurchaseHeader."Document Type"::Order;
                TempPurchaseHeader."No." := Jtoken.AsValue().AsCode();


                if Jtoken.AsObject.Get('BuyfromVendorNo', Jtoken) then;
                TempPurchaseHeader."Buy-from Vendor No." := Jtoken.AsValue().AsCode();
                if Jtoken.AsObject.Get('BuyfromVendorName', Jtoken) then;
                TempPurchaseHeader."Buy-from Vendor Name" := Jtoken.AsValue().AsText();
                if Jtoken.AsObject.Get('OrderDate', Jtoken) then;
                TempPurchaseHeader."Order Date" := Jtoken.AsValue().AsDate();
                if Jtoken.AsObject.Get('LocationCode', Jtoken) then;
                TempPurchaseHeader."Location Code" := Jtoken.AsValue().AsCode();
                if Jtoken.AsObject.Get('InterCompanyCode', Jtoken) then;
                TempPurchaseHeader."Inter Company Code" := Jtoken.AsValue().AsCode();
                TempPurchaseHeader.Status := TempPurchaseHeader.Status::Released;
                TempPurchaseHeader.INSERT;
            end;

        end;
        IF NOT TempPurchaseHeader.ISEMPTY THEN BEGIN
            IF PAGE.RUNMODAL(0, TempPurchaseHeader) = ACTION::LookupOK THEN BEGIN
                Message('Proccess Document No. %1', TempPurchaseHeader."No.");
            end;

        end;
    end;

    procedure PurchLineInit(JsonText: text)
    begin

    end;


    procedure SaleshHeaderInit(JsonText: text)
    begin

    end;

    procedure SalesLineInit(JsonText: text)
    begin

    end;

    procedure UpdateSalesHeader()
    begin

    end;

    procedure UpdatePurchHeader()
    begin

    end;



    var

        Client: HttpClient;
        Request: HttpRequestMessage;
        Response: HttpResponseMessage;
        Headers: HttpHeaders;
        Content: HttpContent;
        ResponseText: Text;
        ErrorBodyContent: Text;
        TextContent: Text;
        Jtoken: JsonToken;
        JObject: JsonObject;
        jsonval: JsonValue;
        Jarray: JsonArray;
        i: Integer;
        j: Integer;
        TotalCount: Integer;
        OrderCount: Integer;
        TempPurchaseHeader: Record 38 temporary;

}
Continue Reading...

GET Token & Get Authorization By Oaths in Business Central

procedure GetAuthorization(): Boolean;
    begin
        EInvoiceAPISetup.Get();
        CheckSetup();
        ResetVar();
        ResponseText := '';
        JSObject.Add('user_account_no', EInvoiceAPISetup."User Account No");
        JSObject.Add('connectorid', EInvoiceAPISetup."Connector Id");
        JSObject.WriteTo(RequestText);
        MyHttpContent.WriteFrom(RequestText);
        MyHttpContent.GetHeaders(ContentHeaders);
        ContentHeaders.Clear();
        //ContentHeaders.Add('User-Agent', 'Dynamics 365 Business Central');
        ContentHeaders.Add('Content-Type', 'application/json; charset=utf-8');
        ContentHeaders.Add('Secret-Key', EInvoiceAPISetup."Secret-Key");
        MyHttpClient.DefaultRequestHeaders.Add('User-Agent', 'Dynamics 365 Business Central');
        Fullurl := EInvoiceAPISetup."API Base Url" + AuthenticateTxt;
        if MyHttpClient.Post(Fullurl, MyHttpContent, MyHttpResponseMessage) then begin
            MyHttpResponseMessage.Content().ReadAs(ResponseText);

            UpdateRecord(ResponseText, 'AUTHORIZATION');
            exit(True);
        end ELSE
            if not MyHttpResponseMessage.IsSuccessStatusCode() then
                exit(false);
        // Error('The web service returned an error message:\\' +
        //         'Status code: ' + Format(MyHttpResponseMessage.HttpStatusCode()) +
        //         'Description: ' + MyHttpResponseMessage.ReasonPhrase());


    end;




//Keep Simple
procedure GetTokenFinal()
    var
        HttpClient: HttpClient;
        HttpHeaders: HttpHeaders;
        HttpRequestMessage: HttpRequestMessage;
        HttpResponseMessage: HttpResponseMessage;
    begin
        HttpRequestMessage.Method := 'GET';
        HttpRequestMessage.SetRequestUri := '';
        HttpRequestMessage.GetHeaders(HttpHeaders);
        HttpHeaders.Add('Secret-Key', '');
        HttpHeaders.Add('Authorization', 'Bearer ');
        IF not HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then
            IF HttpResponseMessage.IsBlockedByEnvironment then
                Error('Blocked By Environment')

            else
                Error('Internet Connection Failed');
        if not HttpResponseMessage.IsSuccessStatusCode() then
            Error('The web service returned an error message:\\' +
                    'Status code: ' + Format(HttpResponseMessage.HttpStatusCode()) +
                    'Description: ' + HttpResponseMessage.ReasonPhrase());
        HttpResponseMessage.Content().ReadAs(ResponseText);
        Message('%1', ResponseText);

    end;



procedure IsExpireAuthorization(): Boolean
    var
        RemainingTime: Duration;
    begin
        EInvoiceAPISetup.Get();
        if EInvoiceAPISetup.Expires <> 0DT then begin
            RemainingTime := (EInvoiceAPISetup."Expires In Hours" * 1000)
            - (System.CurrentDateTime() - EInvoiceAPISetup.Expires);
            if RemainingTime > 0 then
                exit(false);
        end;
        exit(true);

    end;

    procedure IsExpireToken(): Boolean
    var
        RemainingTime: Duration;
    begin
        EInvoiceAPISetup.Get();
        if EInvoiceAPISetup.Expires <> 0DT then begin
            RemainingTime := (EInvoiceAPISetup."Expires In Hours" * 1000)
         - (System.CurrentDateTime() - EInvoiceAPISetup.Expires);
            if RemainingTime > 0 then
                exit(false);
        end;
        exit(true);

    end;


Continue Reading...

Business Central OnPremise – DotNet assembly integration

 First of all it is necessary to set the target in the app.json file, in this case is target is “OnPrem” 



After this, it’s necessary to modify the settings.json of VsCode in order to integrate the paths where the dotNet assemblies reside.

Example

File – Preferences – Settings –  Extensions – AL Language Extension

Select “Modify in settings json”


In this “SETTINGS.JSON” file, you need to insert the assembly path for assembly reference

“al.assemblyProbingPaths”:[

“./.netpackages”,

“C:/Windows/assembly/”

]

Once this is done, it’s necessary to declare in our .AL file which assemblies to load

example: ASSEMBLY name: “mscorlib”

As a result we will have (at the beginning of our AL script)


…and so on for all the DotNet libraries to use

VAR

The declaration of the VAR section becomes:


TEST CASE – “System.Datetime”

Quick test with System.Datetime located in mscorlib and System.environment




Continue Reading...