0

I am trying to schedule a callout from a scheduled class. In order to get around the limitation of sending callouts from scheduled classes, I tried to include the scheduled class within my batch class, and when I ran the batch class from execute anonymous it didn't schedule the batch class. Since I'm returning elements in the methods from my main class, I couldn't use the @future(callout=true) notation. Is there any other workaround to be able to schedule callouts from a batch class?

Thank you in advance.

Main Class

public class CustomerBuilder implements Database.AllowsCallouts {

    Public static map<string,Customer__c> COD2Update = new map <string,Customer__c>(); // index of records by job id

    public static Set<String> getListOutBoundRecords(DateTime endDate, Integer custid ){ 


        Customer__c con = new Customer__c();

        accountmanagementreportingwebservice2.AccountManagementReportingWebserviceSoap s= new accountmanagementreportingwebservice2.AccountManagementReportingWebserviceSoap();
        accountmanagementreportingwebservice2.ListOutboundActivityRequest  req = new accountmanagementreportingwebservice2.ListOutboundActivityRequest();
        accountmanagementreportingwebservice2.ListOutboundActivityResponse res = new accountmanagementreportingwebservice2.ListOutboundActivityResponse();
        accountmanagementreportingwebservice2.Authentication a =new accountmanagementreportingwebservice2.Authentication();

        //Authorization  
        a.Username = '---------';
        a.Password = '-------'; 
        req.Authentication = a;
        req.ExcludeSubLevelEntries = Boolean.valueOf('true');
        req.CustomerId = custid;

        String jsonResponse = (JSON.serializePretty(res));
        JSON2APex result = JSON2APex.parse(jsonResponse);      
        set<string> jobIds = new set<string>();

        //****************** Parse the first callout response and build records

            for(JSON2APex.Om om: result.OutboundMessageList.om){
                Customer__c co = new Customer__c();

                co.Department_Name__c = om.DepartmentName;
                co.Delivered_Pages__c = om.DeliveredPages;

                //index of Customer Records
                COD2Update.put(co.JOB_ID__c, co);

            }

        return COD2Update.keyset();      
    }// end method



    public Customer__c getOutBoundRecords(string Jobid){ 

        Customer__c conc = new Customer__c();
        accountmanagementreportingwebservice2.GetOutboundDetailRequest req = new accountmanagementreportingwebservice2.GetOutboundDetailRequest();
        accountmanagementreportingwebservice2.GetOutboundDetailResponse res = new accountmanagementreportingwebservice2.GetOutboundDetailResponse();
        accountmanagementreportingwebservice2.Authentication a = new accountmanagementreportingwebservice2.Authentication();

        a.Username = '-------';
        a.Password = '------'; 
        req.Authentication = a;

        req.JobId = Jobid;           
        res = s.GetOutboundDetail(req);
        String jsonResponse = (JSON.serializePretty(res));


        //Retrieve the JSON response from the second callout and map the Customer fields with SF fields  

        String jsonResponse2 = (JSON.serializePretty(res));
        JSON2ApexOFD results = JSON2ApexOFD.parse(jsonResponse2);


        for(JSON2ApexOFD.OutboundFaxDetail om2: results.OutboundFaxMessage.OutboundFaxDetail){

            conc.Name = om2.SenderDeptName;
            conc.Delivered_Pages__c = om2.DeliveredPages;

        }

        if (conc != null){           
            return conc;           
        } else{          
            return null; 
        }
    }     

}// end class

*********************Batchable Class

global class CustomerBatchable3 implements Schedulable,  Database.AllowsCallouts, Database.Batchable<String> {

    Datetime endDate = System.today();
    Integer custid;
    map<string,Customer__c> rec2insert = new map <string,Customer__c>();


    global Iterable<String> start(Database.BatchableContext BC){  
         return new IterableExample();            
    }         

    global void execute(Database.BatchableContext BC, List<String> scope){

        //Second Callout
        for(String s :scope){
        Customer__c cod = new Customer__c(); //stores fax details
        Customer__c cod2 = new Customer__c(); // to be updated

            cod = CustomerBuilder.getOutBoundRecords(s);            
            System.debug('Call Out response');
            System.debug(cod);
            cod2 = cod;

            if(cod2 != null){
                cod2.Department_Name__c = Department_Name__c             
                cod2.Delivered_Pages__c = cod.Delivered_Pages__c;
                   rec2insert.put(s,cod2);
                }     
            }

        } 

        if(rec2insert.size() >0){
            insert rec2insert.values();
        }Else{
            system.debug('No Values for insert found');
        }
    }

    global void finish(Database.BatchableContext BC){

    }

    global  void execute(SchedulableContext sc)
    {

    Database.executeBatch(new CustomerBatchable3(), 50); 

    }

}

****************Custom Iterable

global class CustomIterable 
    implements Iterator<String> {


List<String> listcon{get;set;}
Integer i {get;set;} 



    public Iterator<String> iterator() { 
        return this; 
    }      

    public CustomIterable(){
           Datetime endDate = System.today();
           Integer custId;  


        String str = String.join(new List<String>(CustomerBuilder.getListOutBoundRecords(endDate,custId)), ', ');
        System.debug(JSON.serialize(str));
        listcon = str.split(',');
        i = 0;
    }

    global boolean hasNext(){
        if(i>= listcon.size()){
            return false;
        }
        else {
            return true;
        }
    }

    global String next(){
        if (i == 100){
            return null;
        }
        i++;
        return listcon[i-1];
    }

}

*****Iterable example class

global class IterableExample implements iterable<String>{

    global Iterator<String> Iterator(){

        return new CustomIterable();
    }
}
  • What Apex did you run in Execute Anonymous? – David Reed Dec 5 '19 at 16:14
  • In execute anonymous I ran: Id batchJobId = Database.executeBatch(new ConcordBatchable3(), 50); – AL 600 Dec 5 '19 at 16:18
  • @DavidReed And if I run code to execute the scheduler class, I get the error saying I can't make callouts from a scheduled class. ConcordSchedulable co = new ConcordSchedulable(); String sch = '0 0 * * * ? '; System.schedule('ConcordSchedulable', sch, co); – AL 600 Dec 5 '19 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.