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
Arpita NayakArpita Nayak 

Send an email to the student & teacher 1 day before his birthday

Hi ,
I am creating a student/Teacher/Class App.I am facing some problem while creating the workflow rule .
My requirement is the email should be sent 1 day before the bday every year.I am unable to write the query here

Can anyone please help me.
 
Mahesh DMahesh D
Hi Arpita,

We can achieve this using the Batch Apex:

Batch Apex
A Batch class allows you to define a single job that can be broken up into manageable chunks that will be processed separately.

When to use Batch Apex
One example is if you need to make a field update to every Account in your organization. If you have 10,001 Account records in your org, this is impossible without some way of breaking it up. So in the start() method, you define the query you're going to use in this batch context: 'select Id from Account'. Then the execute() method runs, but only receives a relatively short list of records (default 200). Within the execute(), everything runs in its own transactional context, which means almost all of the governor limits only apply to that block. Thus each time execute() is run, you are allowed 150 queries and 50,000 DML rows and so on. When that execute() is complete, a new one is instantiated with the next group of 200 Accounts, with a brand new set of governor limits. Finally the finish() method wraps up any loose ends as necessary, like sending a status email.

Sample Batch Apex
1) Start method is automatically called at the beginning of the apex job. This method will collect record or objects on which the operation should be performed. These record are divided into subtasks & passes those to execute method.

2) Execute Method performs operation which we want to perform on the records fetched from start method.

3) Finish method executes after all batches are processed. Use this method to send confirmation email notifications.

Sample Code:
 
global class CleanUpRecords implements Database.Batchable<sObject> {

   global final String query;
   
   global CleanUpRecords(String q) {
       query = q;
   }

   global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator(query);
   }
   
   global void execute(Database.BatchableContext BC, List<sObject> scope) {
      // Code to send an email
   }

   global void finish(Database.BatchableContext BC){
       AsyncApexJob a = 
           [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
            TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob WHERE Id =
            :BC.getJobId()];
                          
       // Send an email to the Apex job's submitter 
       //   notifying of job completion. 
       Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       String[] toAddresses = new String[] {a.CreatedBy.Email};
       mail.setToAddresses(toAddresses);
       mail.setSubject('Record Clean Up Status: ' + a.Status);
       mail.setPlainTextBody
       ('The batch Apex job processed ' + a.TotalJobItems +
       ' batches with '+ a.NumberOfErrors + ' failures.');
       Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
   }
}

Please go through the below links:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm

https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_intro.htm

http://www.infallibletechie.com/2013/01/simple-batch-apex-example-in-salesforce.html

http://www.salesforcetutorial.com/what-is-batch-apex/

http://www.salesforcetutorial.com/running-batch-apex-example/

https://www.youtube.com/watch?v=PmvpMakxpm8

http://blog.shivanathd.com/2013/01/how-to-write-batch-class-in.html

https://www.minddigital.com/how-to-call-batch-apex-by-scheduler-class-within-salesforce/

https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_1.htm


Please do let me know if it helps you.

Regards,
Mahesh
Arpita NayakArpita Nayak
Thanx Mahesh for your reply but its difficult for me to wite this batch class as i am a beginner in Salesforce
Steps i have done 

1)Created an Email field both in student and Teacher object.
2)Created an Email Template.
In Email Body Field written ---
Hi{Student_c.Name}Wish yoy happy bday

3)Created Email Alert 
Selected Recipient Email:Email

4)after this steps i think i have to create a workflow rule which will be fired 1 day before the student bday.

I am unable to make the query as the email will be send every year 1day before bday .
Mahesh DMahesh D
Hi Arpita,

Please find the below code:
 
global class SendBirthdayBatch implements Database.Batchable<sObject>, Schedulable, Database.Stateful {

    global final String query = 'SELECT Id, Name, DOB__c, Email__c FROM Teacher__c WHERE DOB__c = TOMORROW ';
    global List<String> eventMessages = new List<String>();
    
    global SendBirthdayBatch() {
       //query = q;
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator(query);
    }
   
    global void execute(Database.BatchableContext BC, List<sObject> scope) {
    
        List<Teacher__c> teacherList = (List<Teacher__c>) scope;
       
        List<Messaging.SingleEmailMessage> techMailList = new List<Messaging.SingleEmailMessage>();
        //Id templateId = [select id from EmailTemplate where Name = 'EmailTemplateName' LIMIT 1].id;
        
        for (Teacher__c teach : teacherList) {
            System.debug('=================teach:'+teach);
            system.debug(teach);
            
            system.debug('Send to: ' + teach.Name);
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); 
            String[] toAddresses = new String[] {teach.Email__c};
            mail.setToAddresses(toAddresses);
            mail.setSubject('Happy BirthDay ' + teach.Name);
            mail.setPlainTextBody('Happy Birthday ' + teach.Name);
            techMailList.add(mail);
            
        }
        if(!techMailList.isEmpty()) {
            try{
                Messaging.sendEmail(techMailList);
            }
            catch (Exception ex) {
                eventMessages.add('Unable to send email to Teacher: '+ ex.getStackTraceString());
            }
        }
   }

   global void finish(Database.BatchableContext BC){
       AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id =
            :BC.getJobId()];
                          
       // Send an email to the Apex job's submitter 
       //   notifying of job completion. 
       Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       String[] toAddresses = new String[] {a.CreatedBy.Email};
       mail.setToAddresses(toAddresses);
       mail.setSubject('SendBirthdayBatch: ' + a.Status);
       mail.setPlainTextBody
       ('The batch Apex job processed ' + a.TotalJobItems +
       ' batches with '+ a.NumberOfErrors + ' failures.');
       Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
   }
   
   //Method which schedules the ProductDownloadBatch
    global void execute(SchedulableContext sc) {        
        SendBirthdayBatch sbInstance = new SendBirthdayBatch();
        ID batchprocessid = Database.executeBatch(sbInstance, 100);
    }
}

Go to Developer Console and execute the below code:

SendBirthdayBatch sbInstance = new SendBirthdayBatch();
ID batchprocessid = Database.executeBatch(sbInstance, 100);

I already tested and it is working fine in my DE environment.

Please do let me know if it helps you.

Regards,
Mahesh
DebasisDebasis
Hi Arpita,

please use below steps to achieve it by using workflow and you can schedule this birthday email to go for every yera, you please chaneg the field name and object name as per your requiremnet. and also you can chnage the scheduling time for it.


Workflow rules by themselves typically run once until a record is saved or edited in any way, in which case it is reset.  So creating a single workflow rule to email a customer on his or her next birthday is a fairly basic workflow rule.
The trick is to get it to reset every year.  The idea behind this article is to have another workflow rule, triggered by the first, to "edit" a record automatically, therefore triggering the first again (and setting the next birthday email date in the meantime).

To understand how to create this setup, you'll first need to know:
Email Templates
Creating Custom Fields
Creating Workflow Rules



1 - Create an email template for the Birthday Email.

2 - Create a checkbox field:
 
1 - We'll call this field "Receive Birthday Emails" for the purposes of this article

2 - Default should be "Checked"

3 - Add it to all applicable page layouts so that all can see it (this will allow contacts to opt-out of the email)
 
3 - Create another checkbox field:​
 
1 - We'll call this field "Reset Birthday Email System"

2 - Default should be "Checked"

 3 - The workflow rule related field should be kept hidden from page layout.

4 - Read only for everyone
4 - Create a Date field:
 
1 - We'll call this field "Next Birthday"

2 - Leave "Default Value" blank

3 - Like "Reset Birthday Email System", we'll keep this out of ALL page layouts and keep it read only for everyone.
 
5 -- Create a Workflow Rule:
 
1 - ​We'll call it "Send Birthday Email".  This will be the rule that will send the actual email, and then triggers (1 day later) the Birthday Reset process.

2 - For the Object to create the Workflow on, select "Contact."  This will be the same for all workflow rules in this article.

3 - The Evaluation Criteria should be "created, and any time it's edited to subsequently meet criteria."

4 - In the first line of Rule Criteria, input: "Receive Birthday Emails" equals "True"

5 - In the second line of Rule Criteria, input: "Reset Birthday Email System" equals "False"

6 - In the third line of the Rule Criteria, input: "Birthday" not equal to "" (leave the third column completely blank)

7 - Click Next.

6 - Add a Time Trigger and Action:
 
1 - ​Click Add Time Trigger.

2 - Set the trigger for 6 Hours after Contact: Next Birthday and click Save. (Note: if you need the email before the birthdate, select amount of time before Next Birthday instead.)

3 - On the new time trigger, Click Add Workflow Action | New Email Alert

4 - Type in a Description.  For Unique Name, we'll call it "Birthday Email".

5 - Select the Email Template you created in Step 1.

6 - In the Search field within the Recipient Type section, select Email Field

7 - Select "Email Field: Email" and click Add.​

Note: This will not work when the workflow is created on Account object, which is required when Person Account is enabled. Although there is a standard email field on Account when person accounts are enabled, this field cannot be used in email alerts.

               As a work around, we can create a custom Email field on Account object and make it hidden for all profiles except system admin. To update the Person Account Email field’s value in it, we can create another workflow with Field update action

7 - Add Another Time Trigger and Action:

1 - Click Add Time Trigger.

2 - Set the trigger for 30 Hours after Contact: Next Birthday and click Save

3 - On the new time trigger, Click Add Workflow Action | New Field Update

4 - Let's call it "Check Reset Birthday Email System Box"

5 - Be sure to check the box labeled Re-evaluate Workflow Rules after Field Change

6 - The Field to update is what we called "Reset Birthday Email System"

7 - Under "Checkbox Options", select "True"
 
8 - Create a Second Workflow Rule:
 
​1 - We'll call it "Reset Birthday Email".  This will be the rule that sets "Next Birthday" for the next birthday after the current date, then triggers the "Send Birthday Email" Workflow rule.

2 - The Evaluation Criteria should be "created, and any time it's edited to subsequently meet criteria."

3 - In the first line of Rule Criteria, input: "Receive Birthday Emails" equals "True"

4 - In the second line of Rule Criteria, input: "Reset Birthday Email System" equals "True"

5 - Click Next.
 
9 - Add a Field Update:
 
1 - Under Immediate Actions, click Add Workflow Action | New Field Update

2 - For the Name, let's call it "Reset Next Birthday".  This will actually set the Next Birthday field with the new value that represents the next birthday.

3 - For Field, select Next Birthday.

4 - Leave the Re-evaluate Workflow Rules after Field Change checkbox unchecked.

5 - Select Use a formula to set the new value, and Show Formula Editor
 
For Account/Contact:
 
IF(DATE(YEAR(TODAY()),MONTH(Birthdate),DAY(Birthdate)) <= TODAY(), DATE(YEAR(TODAY())+1,MONTH(Birthdate),DAY(Birthdate)), DATE(YEAR(TODAY()),MONTH(Birthdate),DAY(Birthdate)))
 
For Person Accounts:
 
IF(DATE(YEAR(TODAY()),MONTH(PersonBirthdate),DAY(PersonBirthdate)) <= TODAY(), DATE(YEAR(TODAY())+1,MONTH(PersonBirthdate),DAY(PersonBirthdate)), DATE(YEAR(TODAY()),MONTH(PersonBirthdate),DAY(PersonBirthdate)))
 
10 - Add a Time Trigger:​Click Add Time Trigger.
 
1 - Set the trigger for 1 hour after Rule Trigger Date.  This is to ensure that this action happens after changing the Next Birthday field.

2 - Add a Field Update on this time trigger.  Select the Field as Reset Birthday Email System.

3 - Check the Re-evaluate Workflow Rules after Field Change box.

4 - Select Checked is False

5 - Click Save. 
 
11 - Create a Third Workflow Rule
 
1 - Let's call this workflow rule "Birthday Email Opt-Out".  This will check the Reset checkbox when a user discontinues the email for a contact, so that if the contact wants the email again (sometime later), the Next Birthday field is properly reset before giving out an email on the wrong date.

2 - This workflow rule will be Evaluated Every time a record is Created or Edited (the 2nd option)

3 - Rule Criteria: "Receive Birthday Emails" equals "False"

4 - Click Add Workflow Action | Select Existing Action

5 - Under "Search:", select "Field Update"

6 - Select Field Update: Check Reset Birthday Email System Box and click Add, then click Save
 
​12 - Create a Fourth (and final) Workflow Rule
 
1 - Let's call it "Birthday Change".  This rule takes care of the unlikely event that a contact's Birthdate field changes - we trigger our second Rule, so as to reset Next Birthday to reflect the new date.

2 - This workflow rule will be Evaluated Every time a record is Created or Edited (the 2nd option)

3 - Rule Criteria: Use a formula : 
 
For Account/Contact:
 
(MONTH(Birthdate) <> MONTH(Next_Birthday__c) || DAY(Birthdate) <> DAY(Next_Birthday__c)) && Receive_Birthday_Emails__c = True
 
For Person Accounts:
 
(MONTH( PersonBirthdate ) <> MONTH(Next_Birthday__pc) || DAY(PersonBirthdate) <> DAY(Next_Birthday__pc))
 
4 - Click Add Workflow Action | Select Existing Action

5 - Under "Search:", select "Field Update"

6 - Select Field Update: Check Reset Birthday Email System Box and click Add, then click Save

​13 - Activate all Workflow Rules
 
1 - Go to Setup > Create > Workflow & Approvals > Workflow Rules.  Click "Activate" next to each of the four new workflow rules.  This allows the workflow rules to actually run.

14 - Verification: before enabling for all contacts​ 
 
1 - NOTE:This step is not technically necessary, but recommended to ensure that all emails are scheduled properly.

2 - Create a test contact on an account.  Add an email field and keep the "Receive Birthday Emails" box checked.  Set the contact's birthday to Tomorrow.

3 - Monitor the Time Based Queue (see Monitoring the Workflow Queue) You should see 1 Workflow in the queue for your contact, for the workflow "Reset Birthday Email", set for 1 hour from now.

4 - Wait approx. one hour.  After this rule executes, you should see 2 workflow rules in the queue, one scheduled at 6am on the Contact's birthday, and another scheduled 6am the next day, both for the rule "Send Birthday Email".

5 - If desired, you can do further verification the next day, that the email get sent, and then the next day at 6am, the Reset workflow should trigger and set Next Birthday to next year, and one hour later (7am), 2 more Workflow rules will be in the queue.

6 - When satisfied with verification, move on to Step 15.
 
15 - Enable All contacts to Receive Emails
 
1 - ​In order for any existing contacts to receive birthday emails, run a report that returns all contacts for which you'd like this feature enabled (note you may need to create a custom report type that includes just Contacts), and include these three fields: Contact ID, Receive Birthday Emails, and Reset Birthday Email System.

2 - Export the details of the report and open the document as a spreadsheet, and change ALL 0s to 1s and save as CSV.  Then import them back in using the Import Wizard as detailed in this article.

3 - Due to the time-based queue limitations, the time it takes for the initial reset and scheduling of the birthday emails will vary depending on how many contacts are in your system.  The limit for time-based workflow action execution is 500 per hour, including any other time-based workflow action that may be in your system.


Please do let me know if it helps you.

Thanks,
Debasis
Arpita NayakArpita Nayak

Thanx Debasis for ur reply.It was really helpful.I have done all settings but the Email Notification still i am unable to get.I have attached some snapshots for better understanding.Please check this .
User-added imageUser-added imageUser-added image
DebasisDebasis
Hi Arpita,

yo have to configure i think 3 workflow as per previous post and based onthe time based action email will go. please check your all workflow and  scheduled actions time.
This is a proven method from salesforce to send birthday email.
follow this link below
https://help.salesforce.com/HTViewSolution?id=000181218&language=en_US

let me know if any questions.

Thanks,
Debasis
 
Jennifer Cain 5Jennifer Cain 5

Hi Debasis, 

I have also followed all your instructions and followed the article very closely. Mine still is not sending the email. PLEASE HELP! :) 

Thanks!

Jenn