0

I requirement is to send data from my salesforce org to SAP org. I have successfully written the APEX Class for it. Problem was the JSON structure (see below) was branched and I did not know how to go about it. However, I had good help from this stack exchange community and have found the solution. However, my debug shows that the serialized structure is converted twice. See the debug result below for better understanding of what I mean to say.

My required JSON structure:

[
"BusinessPartnerCategory": "2",
"OrganizationBPName": "Test Contact Name",
"to_BusinessPartnerAddress": [
    {
        "Country" : "Test Contact Country",
        "StreetName" : "Test Contact StreetName",
        "PostalCode" : "Test Contact PostalCode",
        "CityName" : "Test Contact City",
        "t0_AddressUsage" : [
                            { 
                            "AddressUsage" : "Test Contact AddressUsage"
                            }
                            ]
    }
]
"to_BusinessPartnerTax" : [
     {
       "BPTaxType" : "Test Contact TaxType",
       "BPTaxNumber" : "Test Contact TaxNumber"
     }
     ]

]

My Current APEX code:

public class jsontEST2 {
    class SapData{                         // Inner class properties
        String BusinessPartnerCategory;
        String OrganizationName;
        String TestHardCode;
        BusinessPartnerAddress[] to_BusinessPartnerAddress;       //Inner class with an array variable
        T0BusinessPartnerTax[] t0_BusinessPartnerTax ;            //Inner class with an array variable
    }
    
    class BusinessPartnerAddress {                             //1st array properties
        String Country;
        String StreetName;
        String PostalCode;
        String CityName;
        AddressUsage[] t0_AddressUsage;                         //1st array with an inner array
    }
    
    class AddressUsage {                                        //inner-inner array property
        String AddressUsage; 
    }
    
    class T0BusinessPartnerTax {                              //2nd array properties
        String BPTaxType;
        String BPTaxNumber;
    }
    
                                                          //Future method as this entire class i will copy in an http post class to be triggered via a trigger
    @future(callout=true)
    public static void LGS(){                               
        //Querying the required records - where checkbox is ticked
        List<Contact> conList = [SELECT Name, MobilePhone, Fax, Phone, MailingCountry, MailingStreet, MailingPostalCode, MailingCity, MailingState FROM Contact WHERE Create_SAP_record__c = TRUE];  
        String MyHttpRequestBody;
        
        
        SapData sapData = new SapData();                   //creating instance of class
        
        for(Contact con : conList){
            
            //creating for loop to give values of the respective fields
            
            sapData.OrganizationName = con.Name;                   
            sapData.BusinessPartnerCategory = con.Phone;
            sapData.TestHardCode = 'Test Hard Code';
            
            T0BusinessPartnerTax businessPartnerTax = new T0BusinessPartnerTax();          //2nd array instance
            businessPartnerTax.BPTaxType = con.MobilePhone;
            businessPartnerTax.BPTaxNumber = con.Fax;
            
            sapData.t0_BusinessPartnerTax = new List<T0BusinessPartnerTax>{businessPartnerTax};       //adding this (2nd array) array to main class instance
                sapData.t0_BusinessPartnerTax.add(businessPartnerTax);
            
            BusinessPartnerAddress businessPartnerAddress = new BusinessPartnerAddress();           //1st array instance
            
            businessPartnerAddress.Country = con.MailingCountry;
            businessPartnerAddress.StreetName = con.MailingStreet;
            businessPartnerAddress.PostalCode = con.MailingPostalCode;
            businessPartnerAddress.CityName = con.MailingCity;
            
            AddressUsage toAddressUsage = new AddressUsage();                                        //1st array inner-inner array instance
            businessPartnerAddress.t0_AddressUsage = new List<AddressUsage> {toAddressUsage};        //initialising the inner inner array instance to a list
                toAddressUsage.AddressUsage = con.MailingState;
            
            
            sapData.to_BusinessPartnerAddress = new List<BusinessPartnerAddress>{businessPartnerAddress};       //adding the 1st array to main class              
                sapData.to_BusinessPartnerAddress.add(businessPartnerAddress);                     
            
        }
        
        MyHttpRequestBody = JSON.serialize(sapData);                                           //serializing data
        System.debug(MyHttpRequestBody);                                                       //debugging for checking format
    }
    
}

However in debug log, it shows like this :

 15:15:03:044 USER_DEBUG [70]|DEBUG|

 {"to_BusinessPartnerAddress":[
  {"t0_AddressUsage": [
   {"AddressUsage":"Nevada"}],
   "StreetName":"Nevada",
   "PostalCode":"12345",
   "Country":"USA",
   "CityName":"Nevada"},
  {"t0_AddressUsage":[
   {"AddressUsage":"Nevada"}],
   "StreetName":"Nevada",
   "PostalCode":"12345",
   "Country":"USA",
   "CityName":"N

Here is a picture of debug log for better understanding:

enter image description here

Here is the raw debug line :

06:51:54.12 (69958229)|USER_DEBUG|[70]|DEBUG|{"to_BusinessPartnerAddress":[{"t0_AddressUsage":[{"AddressUsage":"Nevada"}],"StreetName":"Nevada","PostalCode":"12345","Country":"USA","CityName":"Nevada"},{"t0_AddressUsage":[{"AddressUsage":"Nevada"}],"StreetName":"Nevada","PostalCode":"12345","Country":"USA","CityName":"Nevada"}],"TestHardCode":"Test Hard Code","t0_BusinessPartnerTax":[{"BPTaxType":"1234567890","BPTaxNumber":"1234567890"},{"BPTaxType":"1234567890","BPTaxNumber":"1234567890"}],"OrganizationName":"Pete 'Maverick' Mitchell","BusinessPartnerCategory":"12345678"}

As you can see the "AddressUsage" is added twice and is causing a 400 Bad request error when I try to pass this is the body for my callout.

enter image description here

//////////////////////////////////////////////////////////EDIT//////////// Pls note that the below JSON structure (hard coded) is the one I want with all the correct names of objects and values. So I have used those names in my code. I have not posted the new code as only the names are different and one test hard code object is less and I do not want to add to your confusion. When I try to pass the (MyHttpRequestBody ) variable into (req.setBody(MyHttpRequestBody )), I get the 400 bad request error. However, If I pass the below hard coded JSON structure directly into (req.setBody), I get 201 OK status. Also I have tried to use the same values in hard coded JSON structure in my code (contact record with same values in fields) with just a changed NAME as that field needs to be unique in order to create a record in SAP S4. Yet it gave me a 400 bad request. I can post my entire Apex code if you need as well

My Hard coded JSON Structure : {"BusinessPartnerCategory" : "2","OrganizationBPName1" "Shaunakssss Enterprieses LLC", "to_BusinessPartnerAddress" : [ {"Country" : "DE", "StreetName" : "LC Street 16", "PostalCode" : "99991", "CityName" : "Wadallof", "to_AddressUsage" : [ { "AddressUsage" : "XXDEFAULT" } ] } ], "to_BusinessPartnerTax" : [ { "BPTaxType" : "DE0", "BPTaxNumber" : "DE011112223"}]}

My JSON structure via our code :

{"to_BusinessPartnerTax":[{"BPTaxType":"1234567890","BPTaxNumber":"1234567890"}],"to_BusinessPartnerAddress":[{"t0_AddressUsage":[{"AddressUsage":"Nevada"}],"StreetName":"Nevada","PostalCode":"12345","Country":"USA","CityName":"Nevada"}],"OrganizationBPName1":"Pete 'Maverick' Mitchell","BusinessPartnerCategory":"12345678"}

2
  • 1
    Please check this link - salesforce.stackexchange.com/questions/370832/… Mar 15 at 10:58
  • I do not mean the string is being serialized twice, its that JSON branches appear twice as you can see from the image (addressUsage is appearing twice). Because of this when I pass the JSON in POST callout body, I get a 400 Bad request error as the JSON structure is not proper Mar 15 at 13:23

1 Answer 1

1

The issue is with these two lines:

sapData.to_BusinessPartnerAddress = new List<BusinessPartnerAddress>{businessPartnerAddress};       //adding the 1st array to main class              
sapData.to_BusinessPartnerAddress.add(businessPartnerAddress);

The first line constructs a list and adds an element of the variable businessPartnerAddress

The second line adds the same element again.

You can remove the second line

6
  • I cannot thank you enough for all the help you have provided! I seem to get the JSON structure right now, However, the 400 bad request error is STILL there. I know for sure that my Http callout code is correct, there is only an issue with the body (the JSON structure needed to be sent). Earlier, I was testing my callout code using a hard coded JSON structure (which I have added/edited above) and the record was made in SAP side. Now the JSON structure that we are making via code is actually in reverse order. Pls see the edit for more understanding. Does order of JSON objects matter in callout? Mar 16 at 13:34
  • JSON order should not matter though I can't speak to SAP as I've never integrated to it
    – cropredy
    Mar 16 at 16:49
  • If you paste the two JSONs into a JSON formatter; you can see the issue is between the hardcoded JSON using to_ and the code using t0_. It wasn't clear from your original OP which was right so I used what you posed in the OP
    – cropredy
    Mar 16 at 16:55
  • Thanks again. I did make the to_address change however, the issue was because the BPTaxtype field is only a 3 length field with one number. So now I'm getting a 201 created request. Now I need to pass this code in a trigger - Since future methods process randomly, I need to require the use of Queueable apex in this. I need to see how to pass the Queueable interface in my above code for get and post callouts. Mar 17 at 12:24
  • You should post your own answer as the solution (or accept this one) - then any future questions you have where you get stuck; use new questions, not comments on existing questions in order to keep us all sane here :-)
    – cropredy
    Mar 17 at 16:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .