Friday, September 10, 2021

Read Multiple Level Response in Business Cental AL Extension by Json Token, Json Object & Json Array

Dear Firends,

Use below sample code to read multiple array document respone in AL Extension

Sample AL Input File 



{
   "orders":[
      {
         "DocumentNo":"SO004349",
         "Status":"Partially Shipped",
         "lines":[
            {
               "LineNo":20000,
               "QtyToShip":1,
               "Status":"Finalised"
            }
         ]
      },
      {
         "DocumentNo":"SO004424",
         "Status":"Partially Shipped",
         "lines":[
            {
               "LineNo":10000,
               "QtyToShip":5,
               "Status":"Finalised"
            },
            {
               "LineNo":20000,
               "QtyToShip":5,
               "Status":"Finalised"
            }
         ]
      },
      {
         "DocumentNo":"SO004423",
         "Status":"Partially Shipped",
         "lines":[
            {
               "LineNo":10000,
               "QtyToShip":4,
               "Status":"Finalised"
            }
         ]
      }
   ]
}

AL Extensoin Code to Read Above File:

procedure UpdateSOShipmentStatus_gFnc(JsonText: Text)Boolean
    var
        SalesHeader_lRec: Record "Sales Header";
        SalesLine_lRec: Record "Sales Line";
        WarehouseShipLine_lRec: Record "Warehouse Shipment Line";
        Jtoken: JsonToken;
        JObject: JsonObject;
        jsonval: JsonValue;
        Jarray: JsonArray;
        i: Integer;
        j: Integer;
        TotalCount: Integer;
        OrderCount: Integer;
        Location_lRec: Record Location;
        ReqWareShip_lBln: Boolean;
        AnylineFound_lBln: Boolean;
    begin
        if not JObject.ReadFrom(JsonTextthen
            Error('Invalid response, expected a JSON object');

        JObject.Get('orders', 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();

            Jtoken.AsObject.Get('DocumentNo', Jtoken);
            IF SalesHeader_lRec.GET(SalesHeader_lRec."Document Type"::Order, Jtoken.AsValue().AsCode()) then begin
                OrderCount += 1;

                Jarray.Get(i, Jtoken);
                if Jtoken.AsObject.Get('Status', Jtokenthen
                    SalesHeader_lRec."Shipment Status" := Jtoken.AsValue().AsText();

                JObject.Get('lines', Jtoken);
                for j := 0 to Jtoken.AsArray().Count() 1 do begin
                    JObject.Get('lines', Jtoken);
                    if Jtoken.AsArray().Get(j, Jtokenthen
                        Jtoken.AsObject.Get('LineNo', Jtoken);

                    if SalesLine_lRec.Get(SalesLine_lRec."Document Type"::Order, SalesHeader_lRec."No.", Jtoken.AsValue().AsInteger()) then begin
                        JObject.Get('lines', Jtoken);
                        if Jtoken.AsArray().Get(j, Jtokenthen
                            if Jtoken.AsObject.Get('QtyToShip', Jtokenthen begin
                                ReqWareShip_lBln := false;
                                IF Location_lRec.GET(SalesLine_lRec."Location Code"Then begin
                                    IF Location_lRec."Require Receive" Then begin
                                        ReqWareShip_lBln := true;
                                        WarehouseShipLine_lRec.RESET;
                                        WarehouseShipLine_lRec.Setrange("Source Type", 37);
                                        WarehouseShipLine_lRec.Setrange("Source Subtype", SalesLine_lRec."Document Type");
                                        WarehouseShipLine_lRec.Setrange("Source No.", SalesLine_lRec."Document No.");
                                        WarehouseShipLine_lRec.Setrange("Source Line No.", SalesLine_lRec."Line No.");
                                        IF WarehouseShipLine_lRec.FindFirst() Then begin
                                            IF WarehouseShipLine_lRec."Qty. Outstanding" <= Jtoken.AsValue().AsDecimal() THen
                                                WarehouseShipLine_lRec.Validate("Qty. to Ship", Jtoken.AsValue().AsDecimal())
                                            Else
                                                WarehouseShipLine_lRec.Validate("Qty. to Ship", WarehouseShipLine_lRec."Qty. Outstanding");

                                            WarehouseShipLine_lRec.Modify();
                                            AnylineFound_lBln := true;
                                        end;

                                    end;
                                end;
                                IF NOT ReqWareShip_lBln Then
                                    SalesLine_lRec.Validate("Qty. to Ship", Jtoken.AsValue().AsDecimal());
                            End;

                        JObject.Get('lines', Jtoken);
                        if Jtoken.AsArray().Get(j, Jtokenthen
                            if Jtoken.AsObject.Get('Status', Jtokenthen begin
                                SalesLine_lRec."Shipment Status" := Jtoken.AsValue().AsText();
                                SalesLine_lRec.Modify(true);
                                AnylineFound_lBln := true;

                                WarehouseShipLine_lRec.RESET;
                                WarehouseShipLine_lRec.Setrange("Source Type", 37);
                                WarehouseShipLine_lRec.Setrange("Source Subtype", SalesLine_lRec."Document Type");
                                WarehouseShipLine_lRec.Setrange("Source No.", SalesLine_lRec."Document No.");
                                WarehouseShipLine_lRec.Setrange("Source Line No.", SalesLine_lRec."Line No.");
                                IF WarehouseShipLine_lRec.FindFirst() Then begin
                                    WarehouseShipLine_lRec."Shipment Status" := SalesLine_lRec."Shipment Status";
                                    WarehouseShipLine_lRec.Modify();
                                    AnylineFound_lBln := true;
                                End;


                            end;
                    end;
                    SalesHeader_lRec.Modify(true);
                    AnylineFound_lBln := true;
                end;
            end;
        end;
        exit(AnylineFound_lBln);
    End;

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

New Example:

Simple single level Json Response:

{
    "access_token": "088e04b1-8efd-4491-a579-1cc4f07a7e68",
    "token_type": "bearer",
    "refresh_token": "cf822cb1-0b1e-48a4-aeda-db648b96d62a",
    "expires_in": 1479,
    "scope": "gstapi"
}
Reading AL code:

procedure ReadJson(JSONInput_iTxt: Text): TEXT
    var
        Jtoken: JsonToken;
        JObject: JsonObject;
        Customer_lRec: Record Customer;
        i: Integer;
        j: Integer;
        access_token: Text[100];
        token_type: Text[100];
        refresh_token: Text[100];
        expires_in: Text[80];
        scope: Guid;
        TotalCount: Integer;
        CustomerCount: Integer;
    begin
        If Not JObject.ReadFrom(JSONInput_iTxt) then
            Error('Invalid response, expected a JSON object');

        JObject.Get('access_token', Jtoken);
        access_token := Jtoken.AsValue().AsText();

        JObject.Get('token_type', Jtoken);
        token_type := Jtoken.AsValue().AsText();

        JObject.Get('refresh_token', Jtoken);
        refresh_token := Jtoken.AsValue().AsText();

        JObject.Get('expires_in', Jtoken);
        expires_in := Jtoken.AsValue().AsText();

        //JObject.Get('scope', Jtoken);
        //scope := Jtoken.AsValue().as();

        Exit(access_token);
    end;

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

Second example where there are object inside Json Response

{
    "status": "1",
    "message": "Record Added Successfully",
    "data": {
        "docNum": "INVOICE00126",
        "ctin": "27GSPMH2101G1Z2",
        "docId": "612f4e83218788617684a121"
    }
}

Reading AL code:

 procedure ReadJosn(JsonText: Text): Boolean
    var
        Jtoken: JsonToken;
        JtokenInner: JsonToken;
        JObject: JsonObject;
        jsonval: JsonValue;
        Jarray: JsonArray;
        i: Integer;
        j: Integer;

        Status_lTxt: Text[30];
        Message_lTxt: Text[30];
        DocNum_lTxt: Text[30];
        CTIN_lTxt: Text[30];
        DocId_lTxt: Text[30];
    begin
        If Not JObject.ReadFrom(JsonText) then
            Error('Invalid response, expected a JSON object');

        if JObject.Get('status', Jtoken) then
            Status_lTxt := Jtoken.AsValue().AsText();

        if JObject.Get('message', Jtoken) then
            Message_lTxt := Jtoken.AsValue().AsText();

        JObject.Get('data', Jtoken);

        If Jtoken.AsObject().Get('docNum', JtokenInner) then
            DocNum_lTxt := JtokenInner.AsValue().AsText();

        If Jtoken.AsObject().Get('ctin', JtokenInner) then
            CTIN_lTxt := JtokenInner.AsValue().AsText();

        If Jtoken.AsObject().Get('docId', JtokenInner) then
            DocId_lTxt := JtokenInner.AsValue().AsText();

        Message(Status_lTxt, Message_lTxt, DocNum_lTxt, CTIN_lTxt, DocId_lTxt);
    end;