I have an @future
class, SubmitOnApproval
which is called when an opportunity is approved. This class is below:
public without sharing class SubmitOnApproval {
@future
public static void oppRecordsToSubmit(id oppId){
Opportunity o = [select id, recordtype.DeveloperName from Opportunity where id = : oppId];
if(o.recordtype.DeveloperName!='PIP_Finished_Product'){
List<GT_Quote__c> oppQuote = new List<GT_Quote__c>();
oppQuote = [Select id, opportunity__c, Submit_Request_Picklist__c, Product__c
from GT_Quote__c
where opportunity__c = :oppId
and Submit_Request_Picklist__c = 'Draft'
and Product__c != ''
and Quote_Stage__c = 'Request Pending'];
if(oppQuote.size()>0){
for(GT_Quote__c quote : oppQuote){
quote.Submit_Request_Picklist__c = 'Submit';
}
database.update(oppQuote, True);
}
}
else{
List<Opportunity_Application__c> oppAppsToSubmit = new List<Opportunity_Application__c>();
oppAppsToSubmit = [select id, Submit_Request__c
from Opportunity_Application__c
where Submit_Request__c = 'Draft'
and Opportunity__c = :oppId];
if(oppAppsToSubmit.size()>0){
for(Opportunity_Application__c oa : oppAppsToSubmit){
oa.Submit_Request__c = 'Submit';
}
database.update(oppAppsToSubmit, True);
}
}
}
@future
public static void oppRecordsToCancel(id oppId){
Opportunity ocancel = [select id, StageName, recordtype.DeveloperName from Opportunity where id = : oppId];
system.debug('rtrtrt'+ ocancel.recordtype.DeveloperName);
List<GT_Quote__c> cancelledQuotes = new List<GT_Quote__c>();
cancelledQuotes = [Select id, opportunity__c, Submit_Request_Picklist__c
from GT_Quote__c
where opportunity__c = :oppId and Submit_Request_Picklist__c = 'Draft'];
for(GT_Quote__c quote : cancelledQuotes){
quote.Quote_Stage__c = 'Request Cancelled';
}
if(cancelledQuotes.size()>0){
database.update(cancelledQuotes, True);
}
I am trying to use an @future
class, QuoteRestCallouts
, to generate some XML and then make POST
call to an external webservice (Vendavo). That class is below:
public class QuoteRestCallouts{
@future (callout=true)
public static void makePostCallout(List<Id> quoteRecords) {
String body = ''; //data to send to external service
String xmlstring = '';
String xmlns = 'http://schemas.xmlsoap.org/soap/envelope/';
String soapNS = 'http://schemas.xmlsoap.org/soap/envelope/';
String tns = 'http://www.vendavo.com/ws/types';
String xsd = 'http://www.w3.org/2001/XMLSchema';
String xsi = 'http://www.w3.org/2001/XMLSchema-instance';
for (Id quoteId : quoteRecords) {
GT_Quote__c q = [SELECT Id,
Name
//MORE FIELDS HERE
FROM GT_Quote__c WHERE id=:quoteId];
//GENERATE SOME XML HERE
HttpRequest req = new HttpRequest();
req.setTimeout(120000);
req.setEndpoint('callout:Vendavo_Integration');
req.setMethod('POST');
req.setHeader('content-type', 'application/text');
req.setBodyDocument(doc);
Http http = new Http();
HttpResponse res;
try {
res = http.send(req);
if (res.getStatusCode() < 200 || res.getStatusCode() > 300) {
displayResponseAndSendErrorEmail();
} else {
displayResponseAndSendErrorEmail();
}
}
catch (System.CalloutException e) {
displayResponseAndSendErrorEmail();
}
}
}
My QuoteAfterUpdate
trigger generates the quoteRecords list used in QuoteRestCallouts
. The problem is that SubmitOnApproval
triggers QuoteAfterUpdate
which tries to call QuoteRestCallouts
and I run into the problem of calling 2 @future
methods in the same transaction.
Can I use queueable apex in some way? I have looked for some examples but I can't figure out how to pass a parameter i.e. quoteRecords
to the execute method. I want the below ideally:
public void execute(QueueableContext context, List<Id> quoteRecords) {
doSomething();
}
Also we are using a custom quote object as SFDC didn't have the standard object when ours was implemented.
Thanks for any help
if(oppQuote.size()>0)
andif(oppAppsToSubmit.size()>0){
andif(cancelledQuotes.size()>0){
are all superfluous; no DML is burned on empty lists