0

I was testing out a new APEX callout where whenever an opportunity was won, it would call out to our application.

I was able to get the job to complete, however I am not seeing the update take place in the external system, and I do have system.debug in my class where I'm not seeing anything logged in the debug logger. Any help would be appreciated if you notice anything wrong in my trigger and class.

Here is my APEX Class:

global class OpportunityUpdateURL {
public class Message {
    public Prospect prospect;
    public String status;

}

public class Prospect{
    public String email;

}

private static String toJsonString(Message m) {
    return JSON.serializePretty(m);
}    

@future (callout=true)
public static void hitTheServer(String email, String status) {


    // Instantiate a new HTTP request, specify the method (PATCH) as well as the endpoint  
    String url='https://XXX.XXXqa.com/api/referrals?_method=PATCH';
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(url);
    req.setHeader('Authorization', 'Token token="apitokenhere"');
    req.setHeader('Content-Type', 'application/json');
    req.setHeader('Accept', 'application/vnd.infl-v3+json');

    Prospect p = new Prospect();
    p.email = email;
    Message m = new Message();
    m.prospect = p;
    m.status = status;


    String body = toJsonString(m);
    req.setMethod('POST');
    req.setBody(body);
    System.debug('this is the body');
    System.debug(body);
    HttpResponse res = h.send(req);
    System.debug('Response: '+ res.getBody());
    }
}

Here is my APEX trigger:

trigger updateOpptyCustomerWons on Opportunity (after update) { 
//make a set to hold opportunity ids that we need
Set<Id> opptyIds = new Set<Id>();

for(Opportunity o : trigger.new)
    {
        //check to see if our field has been changed
        if(o.StageName != trigger.oldMap.get(o.Id).StageName){

            opptyIds.add(o.Id);

    }

   }

if(!opptyIds.isEmpty()){


    //Opportunity opp




    List<Opportunity> opptyList = 
        [SELECT Id,StageName,Name, Account.Name
        FROM Opportunity 
        WHERE StageName = 'Closed Won' AND Id IN :opptyIds ];





    for(Opportunity oppty: opptyList){

        String email = '[email protected]';
        String status = 'won';


    OpportunityUpdateURL.hitTheServer(email, status);



   } 

  }
}

Thanks! Steve

1 Answer 1

0

The first thing that strikes me about your trigger is the entry conditions. I'd change the filters conditions as follows:

for(Opportunity o : trigger.new)
    {
        //check to see if our field has been changed
        if(o.StageName == 'Closed Won' && (o.StageName != trigger.oldMap.get(o.Id).StageName)){

            opptyIds.add(o.Id);

    }

}

The above makes certain that you're not running a query on any Opp Ids that don't already have a StageName of Closed Won. Once you do that, you no longer need to query any records unless there's something like an email address you're going to need when you finish your trigger later.

    for(Opportunity oppty: opptyList){

        String email = '[email protected]';
        String status = 'won';


    OpportunityUpdateURL.hitTheServer(email, status);

   } 

The above concerns me. If I'm not mistaken, a maximum of 5 @future method calls can be made at a time. For that reason, you're going to want to bulkify your hitTheServer method so it can accept lists of email addresses and statuses. Even better would be to accept a map. Once you do, put your strings into a map and at the end of the for loop, send the map to your hitTheServer(map) @future method.

I'd also highly recommend you change your string variable names of email and status to something else since those are common field names that could potentially cause problems. Off hand, I don't think they're protected names (it's not convenient for me to verify either way with the new page formats of SF Online Documentation), but I'd still recommend changing them for the sake of clarity.

2
  • thanks so much for your reply. I updated your first and third recommendations and I will research sending my callouts in a batch. Jun 14, 2015 at 20:03
  • You're welcome Steve. Community etiquette is to help others by marking your question as solved by checkmarking an answer that resolved your issue. When a user doesn't, it leaves the impression to anyone who searches the topic later that your question wasn't answered to your satisfaction. Once you have sufficient reputation, you can also upvote posts and answers.
    – crmprogdev
    Jun 14, 2015 at 20:38

You must log in to answer this question.

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