0

Please Correct me i am getting some errors for sending mails to the approver every days its not approved in approval process

here i am using batchapex its daily acessing the schedule class

global class BatchSendEmailAlerts implements  Database.Batchable<Apply_Job__c> 
{
 public List<Apply_Job__c> opptyUpdateList = new List<Apply_Job__c>();
 Public String query='SELECT Id,Next_Alert_Schduled_Date__c,Status__c FROM Apply_Job__c Where Status__c='Pending Approval' and Next_Alert_Schduled_Date__c =today';
 public set<id> opptyIds = new set<id>();
 public map<id,string> mailIdsMap = new map<id,string>();

 global database.querylocator start(Database.BatchableContext BC)
 {

    return Database.getQueryLocator(query);
 }
 global void execute(Database.BatchableContext BC, LIST<Apply_Job__c> listOppty)
 {
    if(listOppty!=null && listOppty.size()>0)
    {
        for(Apply_Job__c opptyRec: listOppty)
        {
          opptyIds.add(opptyRec.id);
        }       
    }
    if(opptyIds !=null && opptyIds.size()>0)
    {
        for(ProcessInstanceWorkitem PIobj: [select id,ActorId,ProcessInstanceId,actor.email,ProcessInstance.TargetObjectId from ProcessInstanceWorkitem where ProcessInstance.TargetObjectId in: opptyIds])
        {
            mailIdsMap.put(PIobj.ProcessInstance.TargetObjectId,PIobj.actor.email);
        }
    }
    system.debug('~~~~~~~~~~~~opptylist'+listOppty);
    List<Messaging.SingleEmailMessage> lstMsgsToSend = new List<Messaging.SingleEmailMessage>();
    for(Apply_Job__c opptyRec: listOppty)
    {
     List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
     String subject = ' rember';
     Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
     //email.setOrgWideEmailAddressId(Label.Orgwide_Email_Address_Id); 
     email.setSubject(subject);
     List<string> toaddress= new List<String>();    
     toaddress.add(mailIdsMap.get(opptyRec.id)); 
     email.setToAddresses(toaddress);
     emails.add(email);
     OpptyRec.Next_Alert_Schduled_Date__c = system.today()+1;
     opptyUpdateList.add(OpptyRec);
    }
    try
    {
        if(opptyUpdateList !=null && opptyUpdateList.size()>0)
        {
            update opptyUpdateList;
            update emails;
        }
        if(emails!=null && emails.size()>0)
        {
            Messaging.sendEmail(emails);
          //  Messaging.SendEmail(new Messaging.SingleEmailMessage[] {emails});
        }
    }
    catch(exception e)
    {
        //do nothing
    }
 }

 global void finish(Database.BatchableContext BC)
 {
    //do nothing
 }
}  


++++++++++++++++++++++++

Schedule Apex:

global class ScheduleSendAlerts implements Schedulable
{
    global void Execute (SchedulableContext SC)
    {

        BatchSendEmailAlerts sendalerts = new BatchSendEmailAlerts();
        database.executebatch(sendalerts,50);
        system.debug('In the batch class');


    }
}
0

2 Answers 2

3

You need to escape single quotes in a string query.

Fails

String query = 'SELECT ... FROM MyObject__c WHERE Status = 'Pending'';

Works

String query = 'SELECT ... FROM MyObject__c WHERE Status = \'Pending\'';
2

Another way to avoid the compilation problem is to recognise that the batchable documentation example's use of dynamic SOQL is often not the best way to go. You can use static (compile-time checked) SOQL instead which requires less escaping as illustrated below. Also note that it makes more sense to use local variables than class-level variables in the execute method because in a default batchable the fields are not preserved between execute calls.

public class BatchSendEmailAlerts implements Database.Batchable<Apply_Job__c> {

    public database.querylocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator([
                SELECT Id,Next_Alert_Schduled_Date__c,Status__c
                FROM Apply_Job__c
                Where Status__c = 'Pending Approval'
                and Next_Alert_Schduled_Date__c = today
                ]);
    }

    public void execute(Database.BatchableContext BC, LIST<Apply_Job__c> listOppty) {

         set<id> opptyIds = new map<Id, Apply_Job__c>(listOppty).keySet();
         map<id,string> mailIdsMap = new map<id,string>();
         for(ProcessInstanceWorkitem PIobj: [
                 select id,ActorId,ProcessInstanceId,actor.email,ProcessInstance.TargetObjectId
                 from ProcessInstanceWorkitem
                 where ProcessInstance.TargetObjectId in: opptyIds
                 ]) {
            mailIdsMap.put(PIobj.ProcessInstance.TargetObjectId,PIobj.actor.email);
        }

        List<Apply_Job__c> opptyUpdateList = new List<Apply_Job__c>();
        List<Messaging.SingleEmailMessage> lstMsgsToSend = new List<Messaging.SingleEmailMessage>();

        ...
    }
    ...
}
2
  • The docs do it dynamically out of some sense of making the code more unit-testing friendly, but in practice, that's rarely ever necessary. I wish they'd mention this method as the primary means of writing the code. I'm not even sure most people know you can do this...
    – sfdcfox
    Sep 18, 2016 at 14:45
  • 1
    @sfdcfox Yeah I think the docs push people in the wrong direction on the dynamic/static SOQL, public/global and encapsulation vs public fields.
    – Keith C
    Sep 18, 2016 at 15:04

You must log in to answer this question.

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