2
global class KLSMSonBdayBatch implements Database.Batchable<SObject> ,Database.AllowsCallouts
{
    global KLSMSonBdayBatch()
    {

    }
    List<Account> lstofAccountBirthdate = new List<Account>();
    List<string> lstofSMSString;
    public static map<string,KL_Outbound_SMS__c> mapOutboundSMS = KL_Outbound_SMS__c.getAll();
    public static map<string,KL_Outbound_SMS_Template__c> mapOutboundSMSTemplate = KL_Outbound_SMS_Template__c.getAll();

    global Database.QueryLocator start(Database.BatchableContext context)   
    {
        return Database.getQueryLocator([SELECT Id, KL_Date_of_Birthday__c,PersonMobilePhone
                                         FROM Account WHERE 
                                        KL_DND__c = FALSE AND 
                                        ((KL_Date_of_Birthday__c !=: NULL AND 
                                        CALENDAR_MONTH(KL_Date_of_Birthday__c) =: system.today().month() AND
                                        DAY_IN_MONTH(KL_Date_of_Birthday__c) =: system.today().day()) 
                                        )]);

    }

    global void execute(Database.BatchableContext context, List<Account> lstAccount) 
    {
        string strPhoneNo = '';
        string strContent = '';
        if(lstAccount!= null && lstAccount.size()>0)
        {
            for(Account objAccount : lstAccount)
            {
                if(objAccount.KL_Date_of_Birthday__c != null && objAccount.KL_Date_of_Birthday__c.day() == system.today().day() && 
                    objAccount.KL_Date_of_Birthday__c.month() == system.today().month())
                {
                 lstofAccountBirthdate.add(objAccount);           
                }
            }  
            update lstAccount;
            system.debug('lstofAccountBirthdate');
        }
        if(lstofAccountBirthdate != null  && lstofAccountBirthdate.size() > 0)
        {
            lstofSMSString = new list<string>();
            strContent = mapOutboundSMSTemplate.get('Birthday wishes').KL_Body__c;
            for(Account objAccount : lstofAccountBirthdate)
            {
                if(objAccount.PersonMobilePhone!= null)
                {
                 lstofSMSString.add(objAccount.PersonMobilePhone);  
                }
            }
            if(lstofSMSString != null && lstofSMSString.size()>0)
            {
                for(string str : lstofSMSString)
                {
                    strPhoneNo += str +','; 
                }

                string ResponseID = SendSMS(strContent,strPhoneNo);
            }
        }
    }

    public static string SendSMS(string strMsgBody,string strContactNumber)
    {
        string ResponseId;
        if(strMsgBody != null && strMsgBody != '' && strContactNumber != null && strContactNumber != '')
        {
            string msgtext = strMsgBody;
            string strContactno = strContactNumber;

            String URL = mapOutboundSMS.get('SMS').KL_End_Point_URL__c;
            URL += 'To='+strContactNumber;
            URL += '&Text='+strMsgBody;

            HttpRequest req = new HttpRequest();
            req.setEndpoint (URL); 
            req.setMethod ('GET');

            Http http = new Http();
            if(!Test.isRunningTest())
            {
                HTTPResponse res = http.send(req);
                ResponseId=res.getBody().split('TID = \'')[1].substring(0, 10);
            }
        }
        return ResponseId;
    }


    global void finish(Database.BatchableContext context) 
    {
         AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob WHERE Id = : context.getJobId()
        ];
        // Send an email to the Apex job's submitter notifying of job completion.
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {
            'rishi.patel@saasfocus.com'
        };
        mail.setToAddresses(toAddresses);
        mail.setSubject('Apex Sharing Recalculation ' + a.Status); 
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
            ' batches with ' + a.NumberOfErrors + ' failures.'+'KLSMSonBdayBatch');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {
            mail
        });       
    }
}
  • 1
    Can you not just call sendSms first in your execute method? You have to call out before you perform any DML. – Adrian Larson Feb 10 '17 at 11:08
  • There is something similar aticle I found help.salesforce.com/… – Reshma Feb 10 '17 at 11:10
2

You need to restructure your execute logic. Right now your basic steps are:

  1. Filter
  2. Commit to database
  3. Make callout

Because 2 happens before 3, you get this error. It doesn't look like you even make any data transformations, so you may just want to remove step 2 altogether. That would be the simplest option. Alternatively, you can swap 2 and 3 so your logic structure becomes:

  1. Filter
  2. Make Callout
  3. Commit to database

In other words:

List<Account> filtered = new List<Account>();
for (Account record : scopeRecords) // aka lstAccount
{
    if (someCriteria)
    {
        filtered.add(record);
    }
}

// sendSms logic

update scopeRecords; // unclear why this step is necessary

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.