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[] {
            '[email protected]'
        };
        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
        });       
    }
}
2
  • 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, 2017 at 11:08
  • There is something similar aticle I found help.salesforce.com/…
    – Reshma
    Feb 10, 2017 at 11:10

1 Answer 1

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
0

You must log in to answer this question.

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