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
});
}
}
1 Answer
You need to restructure your execute
logic. Right now your basic steps are:
- Filter
- Commit to database
- 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:
- Filter
- Make Callout
- 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
sendSms
first in yourexecute
method? You have to call out before you perform any DML.