0

I have below scheduelable class but issue is after executing this it is triggering another class and calling future method.. i need my that future to be called but needs to avoid that error. (one possible solution is make that future method queable). But not sure how to do that.. I am posting my code for batch and future method both. Please provide me the solution

Schedulable Class:

public with sharing class BatchToUpdateIPiSeq extends ilib_ScheduleAndBatch implements Schedulable{
 /*
 * Default constructor
 */ 
public BatchToUpdateIPiSeq(){

}


/*
  • Description: Execute method to be called when class is scheduled

*/ public override void execute(SchedulableContext ctx) { BatchToUpdateIPiSeq objBatch=new BatchToUpdateIPiSeq(); Database.executebatch(objBatch); } /

  • Description: Fetch required installed products to process

/ public override Database.QueryLocator start(Database.BatchableContext bc) { string strQuery; Set<String> productCode = new Set<String>{'20021532','20040619'}; strQuery = 'Select Id, Name, SVMXC__Company__r.IsPartner, Operation_Status__c, SVMXC__Status__c, Acceptance_Date__c, SVMXC__Date_Installed__c, SVMXC__Date_Shipped__c FROM SVMXC__Installed_Product__c WHERE Product_Code__c IN:productCode AND SVMXC__Status__c = 'Shipped' AND Operation_Status__c = NULL AND Acceptance_Date__c = NULL AND SVMXC__Date_Installed__c = NULL'; return Database.getQueryLocator(strQuery); } /

  • Process the qualified records as batchs

*/ public void execute(Database.BatchableContext bc, List<SVMXC__Installed_Product__c> records){ for(SVMXC__Installed_Product__c objIP : records){ Date startDate = objIP.SVMXC__Date_Shipped__c; Date dueDate = Date.Today(); Integer numberDaysDue = startDate.daysBetween(dueDate);

            if(numberDaysDue&gt;90 &amp;&amp; !objIP.SVMXC__Company__r.IsPartner){
                objIP.Operation_Status__c = 'On';
                objIP.SVMXC__Status__c = 'Installed';
                objIP.Acceptance_Date__c = system.today();
                objIP.SVMXC__Date_Installed__c = system.today();

            }
             if(numberDaysDue&gt;120 &amp;&amp; objIP.SVMXC__Company__r.IsPartner){
                objIP.Operation_Status__c = 'On';
                objIP.SVMXC__Status__c = 'Installed';
                objIP.Acceptance_Date__c = system.today();
                objIP.SVMXC__Date_Installed__c = system.today();

            }
            if(records.size()&gt;0)    
            update records;

       }
}
public override void finish(Database.BatchableContext bc){
    system.debug('inside finish method.');
}

}

After executing this it is calling below method (in AfterUpdate trigger) and causing an error:

if (setInstalledProductIds.size() > 0)
            sendInstalledProductToSAP(setInstalledProductIds);

@future(callout = true) public static void sendInstalledProductToSAP(Set<Id> setInstalledProductIds) { if (setInstalledProductIds == null || setInstalledProductIds.size() == 0) return; System.debug('== I am in future method');

    for (SVMXC__Installed_Product__c instProd : new InstalledProductsSelector().selectInstalledProductsFromIds(setInstalledProductIds))
    {
        if (instProd.ERP_Equipment_Id__c == null || instProd.SVMXC__Company__r.ERP_Customer_Id__c == null)
            setInstalledProductIds.remove(instProd.Id);
    }

}

David Reed
  • 92,733
  • 13
  • 84
  • 157
  • Did you see the answer to https://salesforce.stackexchange.com/questions/24843/calling-future-method-from-batch? – Prashanth K Feb 26 '21 at 03:42
  • Hi @PrashanthK, I have seen that but not sure how to implement that. Can you advise in terms of code mentioned above, – Harsh Shukla Feb 26 '21 at 05:25

1 Answers1

0

Queueable apex can be called from Batch. I have given below the implementation for the same.

if (setInstalledProductIds.size() > 0)
    ID jobID = System.enqueueJob(new sendInstalledProductToSAP(setInstalledProductIds));

Migrating the future to Queueable Apex:

public class sendInstalledProductToSAP implements Queueable,Database.AllowsCallouts {
    public Set<Id> setInstalledProductIds
    public sendInstalledProductToSAP(Set<Id> setInstalledProductIds){
        this.setInstalledProductIds = setInstalledProductIds;
    }
    public void execute(QueueableContext context) {
        if (setInstalledProductIds == null || setInstalledProductIds.size() == 0) return;
    for (SVMXC__Installed_Product__c instProd : new InstalledProductsSelector().selectInstalledProductsFromIds(setInstalledProductIds))
    {
        if (instProd.ERP_Equipment_Id__c == null || instProd.SVMXC__Company__r.ERP_Customer_Id__c == null)
            setInstalledProductIds.remove(instProd.Id);
    }       
}

}

Ranjit Mishra
  • 404
  • 4
  • 16