1

I am trying to POST Opportunity with OpportunityLineItem data to an endpoint. I can get the opportunity data just fine but I am having a lot of trouble with the OpportunityLineItems and I feel myself hitting the wall. The problem is that the the data is coming across garbled. I want the data to come across in JSON format like this:

{
"Id": "006o000000H62OHAAZ",

"Name": "Wed17Test2",

"Account": "abc12345",

"Pricebook": "Standard",

"OPTYQuantity": 6.00,



    "OLI": [

        {
            "OpportunityId": "006o000000H62OHAAZ",
            "ProdcutCode": "GC1060",
            "OLIQuantity": "1.00",
            "UnitPrice": "100000.00",
            "TotalPrice": "100000.00"
        }, {
            "OpportunityId": "006o000000H62OHAAZ",
            "ProdcutCode": "GC1020",
            "OLIQuantity": "2.00",
            "UnitPrice": "5000.00",
            "TotalPrice": "10000.00"
        }, {
            "OpportunityId": "006o000000H62OHAAZ",
            "ProdcutCode": "GC1040",
            "OLIQuantity": "3.00",
            "UnitPrice": "25000.00",
            "TotalPrice": "75000.00"
        }

    ]

}

Instead the data is coming across in JSON format like this:

[ {"OpportunityId" : "006o000000H6C72AAF", 
  "ProductCode" : "GC1060",
  "OLIQuantity" : 1.00,
  "UnitPrice" : 100000.00,
  "TotalPrice" : 100000.00,
  "Id" : "006o000000H6C72AAF",
  "Name" : "monday22d",
  "Account" : "flarnco",
  "Pricebook" : "Standard",
  "OPTYQuantity" : 3.00} ]

this is causing the data to come across all jumbled up when I POST like this:

 "","","","","",006o000000H6C72AAF006o000000H6C72AAF006o000000H6C72AAF,"",1.01.01.0,100000.05000.025000.0,100000.05000.025000.0,""

You can see that it's all mashed up and a mess.

I can get by with the data for the Opportunity just being sent in an array but I'd really like to have it come through in the nested JSON format.

I'd really appreciate any help getting over this hurdle.

Here's my Code:

public static void postOpty(List<String> optyIds){



    List<OpportunityLineItem> lineItems = [SELECT Id , OpportunityId, ProductCode, Quantity, UnitPrice, TotalPrice FROM OpportunityLineItem 
                        WHERE OpportunityId IN :optyIds];

    List<Opportunity> op = [Select Id, Name , Account.Name, OptyPriceBook__c , TotalOpportunityQuantity From Opportunity Where Id IN :optyIds];



    JSONGenerator gen = JSON.createGenerator(true);
    gen.writeStartArray();

    for(Opportunity o : op){

        gen.writeStartObject();
        gen.writeStringField('Id', o.Id);
        gen.writeStringField('Name', o.Name);
        gen.writeStringField('Account', o.Account.Name);
        gen.writeStringField('Pricebook', o.OptyPriceBook__c);
        gen.writeNumberField('OPTYQuantity', o.TotalOpportunityQuantity);


       for(OpportunityLineItem oli : lineItems){
            gen.writeStringField('OpportunityId', oli.OpportunityId);
            gen.writeStringField('ProductCode', oli.ProductCode);
            gen.writeNumberField('OLIQuantity', oli.Quantity);
            gen.writeNumberField('UnitPrice', oli.UnitPrice);
            gen.writeNumberField('TotalPrice', oli.TotalPrice); 
       }


    gen.writeEndObject();      
     gen.writeEndArray();

        String jsonOptys = gen.getAsString();
        System.debug('jsonOptys: ' + jsonOptys);

        //create http request object
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');
        req.setEndpoint('https://MYENDPOINT.COM');
        req.setHeader('Content-Type', 'application/json');
        req.setBody(jsonOptys);
        Http http = new Http();
        HTTPResponse res = http.send(req);
        system.debug('API Service returned '+ res.getBody());           

             if (res.getStatusCode() != 200) {
        System.debug('Error from ' + req.getEndpoint() + ' : ' +
          res.getStatusCode() + ' ' + res.getStatus());
    }

Many Thanks!

Pauly

3 Answers 3

0

I think there might be a problem making sure you are placing the correct OpportunityLineItems in the proper Opporunities as well as the malformed JSON. You can include the query for the OLIs with your opportunity query:

List<Opportunity> op = [SELECT Id, Name, Account.Name, OptyPriceBook__c, TotalOpportunityQuantity, (SELECT Id, OpportunityId, ProductCode, Quantity, UnitPrice, TotalPrice,  FROM Opportunity.OpportunityLineItems) FROM Opportunity WHERE Id in :optyIds];

Then you can change your JSON generation loop to make sure that each for loop is wrapped with startArray() and endArray() calls, and each object inside the loop is wrapped with a startObject() endObject() call.

    JSONGenerator gen = JSON.createGenerator(true);
    gen.writeStartArray();

    for(Opportunity o : op){

        gen.writeStartObject();
        gen.writeStringField('Id', o.Id);
        gen.writeStringField('Name', o.Name);
        gen.writeStringField('Account', o.Account.Name);
        gen.writeStringField('Pricebook', o.OptyPriceBook__c);
        gen.writeNumberField('OPTYQuantity', o.TotalOpportunityQuantity);

        gen.writeStartArray();
        for(OpportunityLineItem oli : op.OpportunityLineItems){
            gen.writeStartObject();
            gen.writeStringField('OpportunityId', oli.OpportunityId);
            gen.writeStringField('ProductCode', oli.ProductCode);
            gen.writeNumberField('OLIQuantity', oli.Quantity);
            gen.writeNumberField('UnitPrice', oli.UnitPrice);
            gen.writeNumberField('TotalPrice', oli.TotalPrice); 
            gen.writeEndObject();
        }
        gen.writeEndArray();
        gen.writeEndObject(); 
    }
    gen.writeEndArray();
}

I haven't used the JSONGenerator much, but I think this can solve your formation problems.

2

When you have an example of the JSON you want as you do, I highly recommend allowing http://json2apex.herokuapp.com/ to generate the code for you. That code then leverages Apex's built in JSON methods and avoids the low level calls like writeStartObject that are otherwise needed and easy to get wrong (as you have discovered).

Having simple Apex classes that represent the data (part of how json2apex works) also often turns out to be helpful including when writing tests.

0

I got it!! Thanks @trankz

JSONGenerator gen = JSON.createGenerator(true);
    gen.writeStartObject();
    gen.writeFieldName('Opty');

   for(Opportunity o : op){

        gen.writeStartObject();
        gen.writeStringField('Id', o.Id);
        gen.writeStringField('Name', o.Name);
        gen.writeStringField('Account', o.Account.Name);
        gen.writeStringField('Pricebook', o.OptyPriceBook__c);
        gen.writeNumberField('OPTYQuantity', o.TotalOpportunityQuantity);
        gen.writeEndObject();

        gen.writeFieldName('OLI');
        gen.writeStartArray();
       for(OpportunityLineItem oli : lineItems){

           gen.writeStartObject();
           //gen.writeStringField('Id', oli.Id);
            gen.writeStringField('OpportunityId', oli.OpportunityId);
            gen.writeStringField('ProductCode', oli.ProductCode);
            gen.writeNumberField('OLIQuantity', oli.Quantity);
            gen.writeNumberField('UnitPrice', oli.UnitPrice);
            gen.writeNumberField('TotalPrice', oli.TotalPrice); 
            gen.writeEndObject();


       }

        gen.writeEndArray();
        gen.writeEndObject();


        String jsonOptys = gen.getAsString();
        System.debug('jsonOptys: ' + jsonOptys);

You must log in to answer this question.

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