• Wole Adeyeye
  • NEWBIE
  • 0 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 1
    Replies
I have a batch class that makes a external Http callout to create case records with a CreatePublicStuffCases() which is called in the start(). In the execute function, I have another callout to get users details for specific cases that were previously inserted in the CreatePublicStuffCases(). Then at the end, do a DML to insert new account and also, update the cases that were previously inserted with thier respective case owners. I keep getting the error "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out". Even when I tried doing the insert outside the loop with a List DML insert. Any help is much appreciated.

The start function : 
public Database.QueryLocator start(Database.BatchableContext context)
{
    CreatePublicStuffCases();
    String ps = 'Public Stuff';
    return Database.getQueryLocator('SELECT External_Source_Id__c FROM Case WHERE Requires_User_Details__c = true AND External_Source_Id__c != Null AND Origin =: ps');
}
The execute function :
public void execute(Database.BatchableContext context, List<Case> scope)
{

    //List<Account> publicStuffAccounts = new List<Account>();
    for (Case cse : scope)
    {            
        String newReq = cse.External_Source_Id__c;
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        req.setEndpoint('https://www.publicstuff.com/api/2.0/request_view?request_id='+newReq');
        Http http = new Http();
        HTTPResponse res = http.send(req);

        String resonseBody = res.getBody();
        String jsonString = resonseBody;
        Map<String,Object> rawObj = (Map<String,Object>) JSON.deserializeUntyped(jsonString);

        Map<String,Object> responseObj = (Map<String,Object>)rawObj.get('response');
        Map<String,Object> userDetails = (Map<String,Object>) responseObj.get('user_detail');

        //select a specific value
        String requeststatus = (String) responseObj.get('request_status');
        String firstname = (String) userDetails.get('firstname');
        String lastname = (String) userDetails.get('lastname');
        String email = (String) userDetails.get('email');
        String phone = (String) userDetails.get('phone');
        String address = (String) userDetails.get('address');
        String zipcode = (String) userDetails.get('zipcode');
        String space = (String) userDetails.get('space');
        String state = (String) userDetails.get('state');

        //check
        Account newPublicStuffContact = new Account(LastName = lastname, FirstName = firstname, PersonEmail = email, Phone = phone, PersonMailingStreet = address, PersonMailingPostalCode = zipcode,
            PersonMailingState = space, PersonMailingCountry = state);
        if (lastname == Null){
            return;
        }
        else{
            try{
                insert newPublicStuffContact;
                //publicStuffAccounts.add(newPublicStuffContact);
                Case caseUpdate = [SELECT Id, ContactId, Requires_User_Details__c FROM Case WHERE Id = :cse.Id];
                //update and mark the case's Requires_User_Details__c as false
                caseUpdate.Requires_User_Details__c = false;
                caseUpdate.AccountId = newPublicStuffContact.Id;
                System.debug('The newPublicStuffContact Id : ' + newPublicStuffContact.Id);
                Update caseUpdate;
                }
                catch (Exception e){
                    System.debug('Error inserting case' + e.getMessage())
                }
        }
        //mapPSContact.put(newPublicStuffContact.Id, newPublicStuffContact);
    }
    //insert publicStuffAccounts;
}
The CreatePublicStuffCases function : 
public static void CreatePublicStuffCases()
{
    // Callout code verbatim from the question
    Date d = Date.today();
    JSONGenerator gen = JSON.createGenerator(true);

    HttpRequest req = new HttpRequest();
    req.setMethod('GET');
    req.setEndpoint('https://www.publicstuff.com/api/2.0/requests_list?limit=2&client_id=****&status=open');
    Http http = new Http();
    HTTPResponse res = http.send(req);
    String resonseBody = res.getBody();
    String jsonString = resonseBody;
    Map<String,Object> rawObj = (Map<String,Object>) JSON.deserializeUntyped(jsonString);
    Map<String,Object> responseObj = (Map<String,Object>)rawObj.get('response');
    List<Case> newCases = new List<Case>();
    Map<String, Object> iMap = new Map<String, Object> ();
    Map<String,Object> id = new Map<String, Object>();
    List<Object> reqs = (List<Object>)responseObj.get('requests');
    for (Object x : reqs)
    {
        iMap = (Map<String, Object>)x;
        for (String field : iMap.keySet())
        {
            id = (Map<String,Object>) iMap.get(field);                
            String idx = 'id';
            String title = 'title';
            String description = 'description';
            String status = 'status';
            String address = 'address';
            String location = 'location';
            String zipcode = 'address';

            Integer OId = (Integer) id.get(idx);
            String Otitle = (String) id.get(title);
            String Odescription = (String) id.get(description);
            String OStatus = (String) id.get(status);
            String Oaddress = (String) id.get(address);
            String OLocation = (String) id.get(location);
            String OZipCode = (String) id.get(zipcode);
            Boolean OrequiresUserDetails = true;

                String CaseRecordTypeId = GlobalStaticMetaDataCache.getRTId('Case', GlobalFixedParams.RECORDTYPE_CASE_SERVICE_REQUEST);
                Case c = new Case(recordTypeId = CaseRecordTypeId, External_Source_Id__c = String.valueOf(OId), Customer_Request_Details__c = Otitle + ' ' + 
                    Odescription, Status = OStatus, SuppliedTargetAddress__c = Oaddress + ' ' + OLocation + ' ' + OZipCode, Requires_User_Details__c = OrequiresUserDetails, Origin = 'Public Stuff');
                newCases.add(c);
        }
    }
    try{
            insert newCases;
    }catch (Exception e){
    }
}
The excute function will send an email but that is no problem at the moment.
 
I have a batch class that makes a external Http callout to create case records with a CreatePublicStuffCases() which is called in the start(). In the execute function, I have another callout to get users details for specific cases that were previously inserted in the CreatePublicStuffCases(). Then at the end, do a DML to insert new account and also, update the cases that were previously inserted with thier respective case owners. I keep getting the error "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out". Even when I tried doing the insert outside the loop with a List DML insert. Any help is much appreciated.

The start function : 
public Database.QueryLocator start(Database.BatchableContext context)
{
    CreatePublicStuffCases();
    String ps = 'Public Stuff';
    return Database.getQueryLocator('SELECT External_Source_Id__c FROM Case WHERE Requires_User_Details__c = true AND External_Source_Id__c != Null AND Origin =: ps');
}
The execute function :
public void execute(Database.BatchableContext context, List<Case> scope)
{

    //List<Account> publicStuffAccounts = new List<Account>();
    for (Case cse : scope)
    {            
        String newReq = cse.External_Source_Id__c;
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        req.setEndpoint('https://www.publicstuff.com/api/2.0/request_view?request_id='+newReq');
        Http http = new Http();
        HTTPResponse res = http.send(req);

        String resonseBody = res.getBody();
        String jsonString = resonseBody;
        Map<String,Object> rawObj = (Map<String,Object>) JSON.deserializeUntyped(jsonString);

        Map<String,Object> responseObj = (Map<String,Object>)rawObj.get('response');
        Map<String,Object> userDetails = (Map<String,Object>) responseObj.get('user_detail');

        //select a specific value
        String requeststatus = (String) responseObj.get('request_status');
        String firstname = (String) userDetails.get('firstname');
        String lastname = (String) userDetails.get('lastname');
        String email = (String) userDetails.get('email');
        String phone = (String) userDetails.get('phone');
        String address = (String) userDetails.get('address');
        String zipcode = (String) userDetails.get('zipcode');
        String space = (String) userDetails.get('space');
        String state = (String) userDetails.get('state');

        //check
        Account newPublicStuffContact = new Account(LastName = lastname, FirstName = firstname, PersonEmail = email, Phone = phone, PersonMailingStreet = address, PersonMailingPostalCode = zipcode,
            PersonMailingState = space, PersonMailingCountry = state);
        if (lastname == Null){
            return;
        }
        else{
            try{
                insert newPublicStuffContact;
                //publicStuffAccounts.add(newPublicStuffContact);
                Case caseUpdate = [SELECT Id, ContactId, Requires_User_Details__c FROM Case WHERE Id = :cse.Id];
                //update and mark the case's Requires_User_Details__c as false
                caseUpdate.Requires_User_Details__c = false;
                caseUpdate.AccountId = newPublicStuffContact.Id;
                System.debug('The newPublicStuffContact Id : ' + newPublicStuffContact.Id);
                Update caseUpdate;
                }
                catch (Exception e){
                    System.debug('Error inserting case' + e.getMessage())
                }
        }
        //mapPSContact.put(newPublicStuffContact.Id, newPublicStuffContact);
    }
    //insert publicStuffAccounts;
}
The CreatePublicStuffCases function : 
public static void CreatePublicStuffCases()
{
    // Callout code verbatim from the question
    Date d = Date.today();
    JSONGenerator gen = JSON.createGenerator(true);

    HttpRequest req = new HttpRequest();
    req.setMethod('GET');
    req.setEndpoint('https://www.publicstuff.com/api/2.0/requests_list?limit=2&client_id=****&status=open');
    Http http = new Http();
    HTTPResponse res = http.send(req);
    String resonseBody = res.getBody();
    String jsonString = resonseBody;
    Map<String,Object> rawObj = (Map<String,Object>) JSON.deserializeUntyped(jsonString);
    Map<String,Object> responseObj = (Map<String,Object>)rawObj.get('response');
    List<Case> newCases = new List<Case>();
    Map<String, Object> iMap = new Map<String, Object> ();
    Map<String,Object> id = new Map<String, Object>();
    List<Object> reqs = (List<Object>)responseObj.get('requests');
    for (Object x : reqs)
    {
        iMap = (Map<String, Object>)x;
        for (String field : iMap.keySet())
        {
            id = (Map<String,Object>) iMap.get(field);                
            String idx = 'id';
            String title = 'title';
            String description = 'description';
            String status = 'status';
            String address = 'address';
            String location = 'location';
            String zipcode = 'address';

            Integer OId = (Integer) id.get(idx);
            String Otitle = (String) id.get(title);
            String Odescription = (String) id.get(description);
            String OStatus = (String) id.get(status);
            String Oaddress = (String) id.get(address);
            String OLocation = (String) id.get(location);
            String OZipCode = (String) id.get(zipcode);
            Boolean OrequiresUserDetails = true;

                String CaseRecordTypeId = GlobalStaticMetaDataCache.getRTId('Case', GlobalFixedParams.RECORDTYPE_CASE_SERVICE_REQUEST);
                Case c = new Case(recordTypeId = CaseRecordTypeId, External_Source_Id__c = String.valueOf(OId), Customer_Request_Details__c = Otitle + ' ' + 
                    Odescription, Status = OStatus, SuppliedTargetAddress__c = Oaddress + ' ' + OLocation + ' ' + OZipCode, Requires_User_Details__c = OrequiresUserDetails, Origin = 'Public Stuff');
                newCases.add(c);
        }
    }
    try{
            insert newCases;
    }catch (Exception e){
    }
}
The excute function will send an email but that is no problem at the moment.