function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
LuciferLucifer 

Schedule apex job logic missing

Hey Guys, 

I have been working on it from past 2 days but couldn't crack it. I'm writing a schedule job which runs every night and at 2 days before a taskoverdue it should send email to the assignees alerting them of the situation. The code I have wriyyen is missing a slight logic and I'm not getting the result. Could some one look at it pls.. I doubt the redline..

 

 

global class EscalateAnnualEnrollmentTaskProcess implements Schedulable {
global void execute(SchedulableContext ctx)
{
/* list of open annual enrollment requests */
List<Annual_Enrollment_Request__c> requestIds = [SELECT Id FROM Annual_Enrollment_Request__c WHERE status__c != 'ACCEPTED'];
/* list of tasks associated with these requests near overdue activitydate - 2 */
List<Task> tasksNearOverdue =[SELECT Id, ActivityDate, Subject FROM Task WHERE WhatId IN :requestIds AND IsClosed = false AND ActivityDate <= :Date.today().addDays(-2) ] ;
/* iterate over the tasks */
for (Task t:tasksNearOverdue) {
/* lookup the object */
Annual_Enrollment_Request__c request = [SELECT Id, Project_Manager__c, Director__c FROM Annual_Enrollment_Request__c WHERE Id = :t.WhatId];

/* lookup the user and send the email*/
User projectmanager = [SELECT Id, Name, Email FROM User WHERE Id = :request.Project_Manager__c];
sendemail(projectmanager, t);
/* lookup the user and send the email */
User director = [SELECT Id, Name, Email FROM User WHERE Id = :request.Director__c];
sendemail(director, t);
}

}
global void sendemail(User u, Task t)
{
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
string[] toaddress = New String[] {u.Email};
email.setSubject('Task Almost Overdue');
email.setPlainTextBody(t.Subject + 'is due ' + t.ActivityDate + ' and needs some attention.');
email.setToAddresses(toaddress);
Messaging.sendEmail(New Messaging.SingleEmailMessage[] {email});
}
}

vishal@forcevishal@force

I suppose it will be a every-day scheduled job. So one flaw I see here is that in your query, you are querying Tasks having activity date 2 or lesser days.

 

So here, if I have a task with activity date as day after tomorrow's. The email will be sent twice for this - one today and the other tomorrow.  Is this the case you're talking about? Or if any other, can you please share the issue you're facing.

LuciferLucifer

Hi Vishal Thats right. So since the job would be running every night or when ever it is going to email the respective PM and Director about the task near overdue. 

 

I have tried to modify the code further please have a look at it.

 

I didnt change much but has taken the condition out of query ..

 

 

global class EscalateAnnualEnrollmentTaskProcess implements Schedulable {
   global void execute(SchedulableContext ctx) 
   {
   List<Task> tasksnearoverdue = new List<Task>(); 
   DateTime Dt = System.today();
Date D = Date.newInstance(Dt.year(),Dt.Month(),Dt.day());
 
      /* list of open annual enrollment requests */
      List<Annual_Enrollment_Request__c> requestIds = [SELECT Id FROM Annual_Enrollment_Request__c WHERE status__c != 'ACCEPTED'];
      /* list of tasks associated with these requests near overdue activitydate - 2 */
      List<Task> tasksOverdue =[SELECT Id, ActivityDate, Subject FROM Task WHERE WhatId IN :requestIds AND IsClosed = false]; //AND ActivityDate <= :Date.today().addDays(-2) ] ;
      /* iterate over the tasks */
      for (Task t:tasksOverdue){
      
         if(t.ActivityDate.addDays(- 2)== system.today() )
                 tasksnearoverdue.add(t);
      }
      
      
      
      for (Task t:tasksNearOverdue) {
         /* lookup the object */
         Annual_Enrollment_Request__c request = [SELECT Id, Project_Manager__c, Director__c FROM Annual_Enrollment_Request__c WHERE Id = :t.WhatId];
 

         /* lookup the user and send the email*/
         User projectmanager = [SELECT Id, Name, Email FROM User WHERE Id = :request.Project_Manager__c];
         sendemail(projectmanager, t);
         /* lookup the user and send the email */
         User director =  [SELECT Id, Name, Email FROM User WHERE Id = :request.Director__c];
         sendemail(director, t);
      }
   
 } 
   global void sendemail(User u, Task t)
   {
      Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
      string[] toaddress = New String[] {u.Email};
      email.setSubject('Task Almost Overdue');
      email.setPlainTextBody(t.Subject + 'is due ' + t.ActivityDate + ' and needs some attention.');
      email.setToAddresses(toaddress);
      Messaging.sendEmail(New Messaging.SingleEmailMessage[] {email});
   }
}

LuciferLucifer

But it definetly dont need to be like sending a mail today and tomorrow aswell as it might annoy them but its least concerned at this moment. I wanted to produce a mail two days before the task near over due. I beleive my code seems to send twice like today and tomorrow.. I dont want to change it again for just one time as Im already finding difficulty with the present code itself:(

 

 

vishal@forcevishal@force

Lucifer, I am not able to understand what issue you're facing. Your code isn't bulk handled, you have queries inside for loops which is not a good practice. But functionality-wise, can you please tell me what issue you facing? Is the code not running or is it throwing errors or it runs but nothing happens as expected?

LuciferLucifer

With this code i'm trying to create a task with due date as 20th.. Since it is today at 18th, I'm expecting to get a mail. But I'm not getting. I tried to execute it in developer console in the following fashion

 

EscalateAnnualEnrollmentTaskProcess AE = new EscalateAnnualEnrollmentTaskProcess ();
String sch = '0 0 8 15 11 MON - FRI';
system.schedule('Annual Enrollment Schedule', sch, AE);

 

 

bottom line is im unable to get an email which is the whole purpose. Not sure if the logic is wrong or scheduling time is wrong or one of my friend told I need to write a batch class