function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Samuel Robert 15Samuel Robert 15 

Callout error to external system in salesforce “First error: You have uncommitted work pending. Please commit or rollback before calling out”

We have Trigger that calls a future webservice class , which is inturn callsout external system.
When the Account status is set to Active then the system callout the external ITSm sytem and creates a record there . We also maintain Mapping opject to track the ID so in future when the callout fires it will check our system to see if the record is already existing in the other system and performs a Update operation.
However, when we tested the scenario in sandbox it failed in calling the endpoint itself and throws the following error at the apex Jobs
First error: You have uncommitted work pending. Please commit or rollback before calling out
Please find the apex Webservice callout class.
 
global class TOPdeskCalloutObject {
@future (callout=true)
Webservice static void apiCall(String salesforceID, String action, String accountName, String apiType) {

    //Get Username password and URL
    TOPdesk_API__c api = TOPdesk_API__c.getInstance('TOPdeskAPI');        
    String username = api.User_Name__c;
    String password = api.Password__c;
    String TOPdeskURL = api.URL__c;
    String endpoint;
    String method;
    String errorMessage;
    String body ='';
    Boolean archive = FALSE;

    //Construct HTTP request and response
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();

    //Construct Authorization and Content header
    Blob headerValue = Blob.valueOf(username+':'+password);
    String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
    req.setHeader('Authorization', authorizationHeader);
    req.setHeader('Content-Type','application/json');

    System.debug('***SalesForce ID: '+ salesForceID);

    //Construct Endpoint
    try {
        TOPdesk_Mapping__c  mapping = [SELECT TOPdesk_Mapping__c.TOPdesk_ID__c FROM TOPdesk_Mapping__c WHERE Name = :salesForceID];
         if (string.isEmpty(mapping.TOPdesk_ID__c)) {
            System.debug('--in is empty--');  
            errorMessage = 'Action = '+action+'<br>API Call = '+method+'<br>Date / Time = '+DateTime.now()+'<br>API Status code = '+res.getStatusCode()+'<br>Response string = '+res.toString()+ ' Json Body = '+res.getBody(); 
            TOPdeskSendMail.sendMail(apiType,'Error = No TOPdesk ID returned '+errorMessage,salesForceID);                    
            return;
         }


        if (action == 'CREATE' && apiType == 'persons') {
            endpoint = TOPdeskURL+'/tas/api/'+apiType+'/id/'+mapping.TOPdesk_ID__c+'/unarchive'; 
            archive = TRUE;
                    System.debug('***CHECK : '+ endpoint + archive);

        }
        if (action == 'ARCHIVE' && apiType == 'persons') {
            endpoint = TOPdeskURL+'/tas/api/'+apiType+'/id/'+mapping.TOPdesk_ID__c+'/archive';         
            archive = TRUE;  
        }
        if (action == 'UPDATE') {
            endpoint = TOPdeskURL+'/tas/api/'+apiType+'/id/'+mapping.TOPdesk_ID__c; 
        }
        method = 'PUT';
        System.debug(endpoint);
        System.debug(method);
    }

     catch(QueryException e) {
        endpoint = TOPdeskURL+'/tas/api/'+apiType;
        method = 'POST';
        System.debug(method);
    }
        System.debug(endpoint);                                 
    //Construct Body     
    if (apiType == 'branches') {
        body = TOPdeskGetAccountBody.getAccount(salesForceID, action);
    }
    if (apiType == 'persons' && archive == FALSE) {
        body = TOPdeskGetContactBody.getContact(salesForceID, action);  
    }

     System.debug('CHECK BODY: '+body);
    //Set Method and Endpoint and Body
    req.setMethod(method);

    if(test.isrunningtest()){
        req.setEndpoint('www.test.com/tas/api/branches');
    }
    else{
        req.setEndpoint(endpoint);
    }

    req.setBody(body);

 // Adding debug statements -[AS] 17/04/2019
    System.debug('endpoint : '+endpoint );
    System.debug('method: '+method);
    System.debug('body: '+body);


    //Send endpoint to TOPdesk
    if(test.isrunningtest()){
       res = getTestResponse(req);
    }
    else{
        res = http.send(req);        
    }


    //Get TOPdeskID from body       
    string responseString = res.getBody();
    System.debug('responseString : '+responseString);
    TOPdeskResponseID responseClass = TOPdeskResponseID.parse(responseString);
    String topdeskID = responseClass.id;

    String statusCode = 'API Status code = '+res.getStatusCode();
    System.debug('API: '+res.getStatusCode());

    errorMessage = 'Action = '+action+'<br>API Call = '+method+'<br>Date / Time = '+DateTime.now()+'<br>API Status code = '+res.getStatusCode()+'<br>Response string = '+res.toString()+ ' Json Body = '+res.getBody(); 
    if (string.isEmpty(topdeskID)) {    
        TOPdeskSendMail.sendMail(apiType,'Error = No TOPdesk ID returned '+errorMessage,salesForceID);
    }

    //Check if TOPdeskID exists in SalesForce mapping table
     try {
    TOPdesk_Mapping__c  mappingID = [SELECT TOPdesk_Mapping__c.ID FROM TOPdesk_Mapping__c WHERE Name = :salesForceID];
        //upsert in case id topdesk id exists
        upsert new TOPdesk_Mapping__c(
        ID = mappingID.ID,
        Name = salesForceID,
        Object_Type__c = apiType,
        TOPdesk_ID__c = topdeskID,
        Object_Name__c = accountName,
        Last_API_Body__c =  body,
        Last_API_Message__c =errorMessage,
        Last_API_Status__c = statusCode 

        );
     } 
     catch(QueryException e) {
        //insert in case no topdesk id is known
        insert new TOPdesk_Mapping__c(
        Name = salesForceID,
        Object_Type__c = apiType,
        TOPdesk_ID__c = topdeskID,
        Object_Name__c = accountName,
        Last_API_Body__c = body,
        Last_API_Message__c =errorMessage,
        Last_API_Status__c = statusCode 
        );
     } 


}

public static HTTPResponse getTestResponse(HTTPRequest req) {
    HttpResponse res = new HttpResponse();
    res.setBody('{"id":"46d05ee6-a56c-489e-9939-8d33d182105f","name":"Dayco, Inc.","specification":"","clientReferenceNumber":"330199","timeZone":"","extraA":null,"extraB":null,"phone":"+1 7166894972","fax":"+1.716.689.1529","address":{"country":null,"street":"1650 Research Dr Ste 200","number":"","county":"MI","city":"Troy","postcode":"48083-2143","addressMemo":"","addressType":null},"email":"","website":"www.dayco.com","postalAddress":{"country":null,"street":"501 J James Adbn Pkwy 400","number":"","county":"NY","city":"Amherst","postcode":"14228","addressMemo":"","addressType":null},"branchType":"independentBranch","headBranch":null,"optionalFields1":{"boolean1":false,"boolean2":false,"boolean3":false,"boolean4":false,"boolean5":false,"number1":0.0,"number2":0.0,"number3":0.0,"number4":0.0,"number5":0.0,"date1":null,"date2":null,"date3":null,"date4":null,"date5":null,"text1":"","text2":"","text3":"","text4":"","text5":"","memo1":null,"memo2":null,"memo3":null,"memo4":null,"memo5":null,"searchlist1":null,"searchlist2":{"id":"b51176b2-885e-4e90-ada9-6e650e26deb9","name":"AMERICAS"},"searchlist3":{"id":"2b5422f6-4864-430f-af87-855d09991820","name":"NA"},"searchlist4":null,"searchlist5":null},"optionalFields2":{"boolean1":false,"boolean2":false,"boolean3":false,"boolean4":false,"boolean5":false,"number1":0.0,"number2":0.0,"number3":0.0,"number4":0.0,"number5":0.0,"date1":null,"date2":null,"date3":null,"date4":null,"date5":null,"text1":"0015000000YG531AAD","text2":"lori.sawatzke=nasdaq.com@example.com","text3":"null","text4":"CREATE","text5":"","memo1":null,"memo2":null,"memo3":null,"memo4":null,"memo5":null,"searchlist1":null,"searchlist2":null,"searchlist3":null,"searchlist4":null,"searchlist5":null},"creator":{"id":"41466b30-30a5-5fd9-bd85-b39fbe09efa9","name":"Breggeman, Joost"},"creationDate":"2019-03-25T09:56:04.937+0000","modifier":{"id":"41466b30-30a5-5fd9-bd85-b39fbe09efa9","name":"Breggeman, Joost"},"modificationDate":"2019-03-25T09:56:04.000+0000"}');
    res.setStatus('OK');
    res.setStatusCode(200);
    return res;
}
}

Apex Trigger :
 
trigger TOPdeskAccountUpdate on Account (after update) {
for (Account a : Trigger.new) {

String salesforceID = a.ID;
String action;
String apiType = 'branches';
System.debug('***SalesForce ID: '+ salesforceID);

//when account status is moved to Active Cust omer
if(trigger.oldMap.get(a.Id).Account_Status__c != a.Account_Status__c && a.Account_Status__c == 'Active Customer' ) {
    action = 'CREATE';
    System.debug('***Action: '+ action);
    TOPdeskCalloutObject.apiCall(salesforceID, action, a.Name, apiType);
    } 
//when Active Customer is updated
else if (trigger.oldMap.get(a.Id).Account_Status__c == a.Account_Status__c && a.Account_Status__c == 'Active Customer') { 
    action = 'UPDATE';
    System.debug('***Action: '+ action);
    TOPdeskCalloutObject.apiCall(salesforceID, action, a.Name, apiType);
   }
//when Active Customer is moved to Inactive
else if (trigger.oldMap.get(a.Id).Account_Status__c != a.Account_Status__c && a.Account_Status__c != 'Active Customer') { 
    action = 'ARCHIVE';
    System.debug('***Action: '+ action);
    TOPdeskCalloutObject.apiCall(salesforceID, action, a.Name, apiType);

    List<Contact> cList = [SELECT ID FROM Contact where accountID=:salesforceID];
        System.debug('***CONTACT: '+ cList); 

    for (Contact c : cList) {
        upsert new Contact(
        ID = c.ID,
        TOPdesk_Contact__c = FALSE);
    }
   }
} }

Please advise
Thanks
Khan AnasKhan Anas (Salesforce Developers) 
Hi Samuel,

Greetings to you!

Please refer to the below knowledge articles which might help you further with the above issue.

https://help.salesforce.com/articleView?id=000079772&type=1

https://help.salesforce.com/articleView?id=000003701&type=1

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas