+ Start a Discussion
sonam gupthasonam guptha 

sending an email based on account.enddate__c on every month

HI,

Iam afraid as a begginer.
on a account table i have custom field termEndDate__c which was a formula field of type date,so when termEndDate__c is set to less than 90 days on a particular account, i have to send an email with the account name,and this has to done on monthly basis as a schedule and we need to include account name in the email,and has to check all the accounts in my salesforce org should send an email which accounts are less than 90 days. is it possible.please help me out

 
Best Answer chosen by sonam guptha
Varun SinghVarun Singh
Sure Sonam,

You can try  this
Working Perfectly in single email
 
global class expireNotify implements Database.Batchable<sObject> {
   global Database.QueryLocator start(Database.BatchableContext bc) {
       //Date d = Date.today()+90;
       String soql = 'SELECT EndDate__c, Name FROM Account WHERE EndDate__c !=NULL';
       return Database.getQueryLocator(soql);
   }
  
   global void execute(Database.BatchableContext bc, List<account> recs) {
       List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
       Date D =Date.today();
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    List<String> toAddresses = new List<String>();
                    String messageBody;
                    list<string> accstring =new list<string>();
                    integer i=0;
       for(account m : recs) {
           if(m.EndDate__c.daysBetween(D) < 90 )
           {
                  i+=1;    
           
            messageBody = i+'-->'+ m.Name ;
            accstring.add(messageBody );           
           }    
       }                
       toAddresses.add('spnvarun0121@gmail.com');
           mail.setToAddresses(toAddresses);
           mail.setSubject('Welcome to Sweet 16 Siebel Batch');
           string allstring = string.join(accstring,'<br/>');
       mail.setHtmlBody('<html><body>Hi Sir Hope you are well <br>'+'<br> List of accounts <br>'+allstring + ',<br>Your accounts Expires today. <br>Kindly contact your administrator.<br><br><b>Regards,</b><br>Magulan D<br/></body></html>'); 

                  mailList.add(mail);   

       Messaging.sendEmail(mailList);
   }
  
   global void finish(Database.BatchableContext bc) {
   }
}

excute sheduler class
 
global class scheduleExpireNotify implements Schedulable {
    global void execute(SchedulableContext sc) {
        expireNotify en = new expireNotify();
        Database.executeBatch(en);
    }
}




If It works  for  you please slelect my answer is best answer 
Thanks,

All Answers

Varun SinghVarun Singh
HI Sonam ,
You have to Use Process Builder or Workflow rule

I task was same for Opportunity Object.You have to use Account and your field instead of opp and custom field in attched snap.
It Will helpful for  you i think.

User-added image

1-4-create an email template before sending email
2--For Process Builder  you have choose Object as Account
3-Run Your Proces when Account is created ot Edited
4-Your Criteria should be there 
[Account].termEndDate__c -today()==90
5-Choose immidiate action as send email alert
choose your email template
6- Activate Process Builder 

Enjoy it will work for  you 

If You like this this answer then don't Forget to make as Best Answer .

Thanks
Amil_AbdallahAmil_Abdallah
Varun's logic above will work when a record is created or edited to meet the conditions you described.  However, if you need something to occur on a monthly basis, then you would need to write a schedulable class.  https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm

Your logic for the schedulable class would need to be something like this:

- Write a query that grabs all accounts that are less than 90 days
- Loop through the records and create a single email message containing the account details and add the email message to a list of messages
- Insert/Send the emails in the email list outside of the loop/at the end

Here is info on writing emails in apex: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_single.htm
 
sonam gupthasonam guptha
varun,

wf and PB work on any event happens like insert or update,but here i will not perform any operation manually,and it has send an email weekly wise by checking out all my account records.so we can use scheduler for weekly emails but how to check all the accounts?
sonam gupthasonam guptha
amil,

thats what even iam thinking i will write some code if i strucked up any where please help me out thanks!
Amil_AbdallahAmil_Abdallah
No problem. I do this all the time so I should be able to help.  Please select my answer as the best choice if this does solve your issue.  Thanks!
Varun SinghVarun Singh
Hi Sonam ,
If you want Do this  by code ,so  you have to wtrie a batch class  for  it and  weeekly basis run this  to batch to send email notification only for  those  records  who older than 90 days(account.enddate__c) using sheduler class.

I will help you  for  this code if you want.

Thanks
Varun SinghVarun Singh
Hi Sonam i hope  this  code is  helpful for  you

Batch Apex Class:
 
global class expireNotify implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext bc) {
        Date d = Date.today()+90;
        String soql = 'SELECT EndDate__c, Name, Email_Address__c FROM Account WHERE EndDate__c =: d';
        return Database.getQueryLocator(soql);
    }
   
    global void execute(Database.BatchableContext bc, List<account> recs) {
        List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
        for(account m : recs) {
            List<String> toAddresses = new List<String>();           
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            toAddresses.add(m.Email_Address__c);
            mail.setToAddresses(toAddresses);
            mail.setSubject('Welcome to Sweet 16 Siebel Batch');
            String messageBody = '<html><body>Hi ' + m.Name + ',<br>Your account Expires today. <br>Kindly contact your administrator.<br><br><b>Regards,</b><br>Magulan D</body></html>';
            mail.setHtmlBody(messageBody); 
            mailList.add(mail);          
        } 
        Messaging.sendEmail(mailList);
    }
   
    global void finish(Database.BatchableContext bc) {
    }
}

Schedulable Class: 
 
global class scheduleExpireNotify implements Schedulable {
    global void execute(SchedulableContext sc) {
        expireNotify en = new expireNotify();
        Database.executeBatch(en);
    }
}

Schedule the 'scheduleExpireNotify' as mentioned below in App Setup --> Apex Classes --> Schedule Apex and select 'sscheduleExpireNotify' class. Check Weekly and select all the days. Give Start and End dates and Preferred Start time and Click 'Save' button.

User-added image

User-added image

I  you Need more  Help Inform Me.

Thanks,
sonam gupthasonam guptha
varun,

its not working as expected,i think we need to add if condtion to fire the email,and if there are more than 4,5 accounts will it grab those accounts or by default it will always gives us only one account name.
 
if(acc.enddate__c <90) 
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            toAddresses.add('mail address');
            mail.setToAddresses(toAddresses);
            mail.setSubject('Here is expiration account details');
            String messageBody = '<html><body>Hi ' + acc.Name + ',<br>Your account Expires today. <br>Kindly contact your administrator.<br><br><b>Regards,</b><br>support Team </body></html>';
            mail.setHtmlBody(messageBody); 
            mailList.add(mail);

 
Varun SinghVarun Singh
Hi Sonam,
This is working code
try this code
global class expireNotify implements Database.Batchable<sObject> {
   global Database.QueryLocator start(Database.BatchableContext bc) {
       //Date d = Date.today()+90;
       String soql = 'SELECT EndDate__c, Name FROM Account WHERE EndDate__c !=NULL limit 10';
       return Database.getQueryLocator(soql);
   }
  
   global void execute(Database.BatchableContext bc, List<account> recs) {
       List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
       Date D =Date.today();
       for(account m : recs) {
           if(m.EndDate__c.daysBetween(D) < 90 )
           {
           List<String> toAddresses = new List<String>();           
           Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
           toAddresses.add('devenderreddy@bluejeans.com');
           mail.setToAddresses(toAddresses);
           mail.setSubject('Welcome to Sweet 16 Siebel Batch');
           String messageBody = '<html><body>Hi ' + m.Name + ',<br>Your account Expires today. <br>Kindly contact your administrator.<br><br><b>Regards,</b><br>Magulan D</body></html>';
           mail.setHtmlBody(messageBody); 
           mailList.add(mail);   
           }    
       } 
       Messaging.sendEmail(mailList);
   }
  
   global void finish(Database.BatchableContext bc) {
   }
}
If It works  for  you please slelect my answer is best answer 
Thanks,
sonam gupthasonam guptha
iam getting below error:--

SendEmail failed. First exception on row 0; first error: NO_MASS_MAIL_PERMISSION, Single email is not enabled for your organization or profile.: []
Varun SinghVarun Singh
please check
setup--> Email Administration
-->Deliverability-->Access level Picklist Shoul be -->All Email

The reasons are :
 
>>Trial accounts do not allow the use of mass email. You will have to purchase a license to go live with your org.
 
>>You are missing a permission in the backend and must log a feature activation case with Salesforce support to enable "Respect SendEmail API" and "SendEmail API".
 
>>The access level might have been set to "system e-mails".
 In setup | Administration setup | Email Administration | Deliverability, verify if the access level is set to "All e-mails".
 
The e-mail deliverability is a new feature released in spring 13 and as per the release notes, all newly refreshed sandboxes default to "system email only"
 
Other wise

Trial accounts do not allow the use of mass email. You will have to purchase a license to go live with your org.
i think you are  using Dev org
 this code will work in licence organization (production and in sandbox both)
https://help.salesforce.com/articleView?id=000002868&language=en_US&type=1


 
sonam gupthasonam guptha
can we able to club all the accounts in one mail,currently its sending induividual email for each account?
Amil_AbdallahAmil_Abdallah
Yes you can.  Just create one email to send at the end.  Define a String variable in your class.  In your for loop, append the account information into the string variable to hold the Email Message body. Assign the value of the string to the email message body after the loop.  If you are using a Batch class to interate through the accounts you will need to implement Database.Stateful along with Database.Batchable<sObject>.  Since batch classes execute logic per batch of records, you need to use Database.Stateful to keep your string variable from getting erased for each batch of records it processes.  
 
global class YourBatchCLass implements Database.Batchable<sObject>, Database.Stateful {

String emailBody;

global void execute(Database.BatchableContext BC, List<Account> scope) {
		Boolean result;

		for(Account acct : scope)
		{
                   emailBody += 'Name: ' + acct.Name;
                }
}

global void finish(Database.BatchableContext BC) {

		Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
		String[] toAddresses = new String[] {'emailaddress@email.com'};
		mail.setToAddresses(toAddresses);
		mail.setSubject('Subject');
               mail.setPlainTextBody(emailBody);

		try{
			Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
		}
		catch (Exception e){
			System.debug('**** An exception occurred: ' + e);
		}
	}

 
Varun SinghVarun Singh
Sure Sonam,

You can try  this
Working Perfectly in single email
 
global class expireNotify implements Database.Batchable<sObject> {
   global Database.QueryLocator start(Database.BatchableContext bc) {
       //Date d = Date.today()+90;
       String soql = 'SELECT EndDate__c, Name FROM Account WHERE EndDate__c !=NULL';
       return Database.getQueryLocator(soql);
   }
  
   global void execute(Database.BatchableContext bc, List<account> recs) {
       List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
       Date D =Date.today();
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    List<String> toAddresses = new List<String>();
                    String messageBody;
                    list<string> accstring =new list<string>();
                    integer i=0;
       for(account m : recs) {
           if(m.EndDate__c.daysBetween(D) < 90 )
           {
                  i+=1;    
           
            messageBody = i+'-->'+ m.Name ;
            accstring.add(messageBody );           
           }    
       }                
       toAddresses.add('spnvarun0121@gmail.com');
           mail.setToAddresses(toAddresses);
           mail.setSubject('Welcome to Sweet 16 Siebel Batch');
           string allstring = string.join(accstring,'<br/>');
       mail.setHtmlBody('<html><body>Hi Sir Hope you are well <br>'+'<br> List of accounts <br>'+allstring + ',<br>Your accounts Expires today. <br>Kindly contact your administrator.<br><br><b>Regards,</b><br>Magulan D<br/></body></html>'); 

                  mailList.add(mail);   

       Messaging.sendEmail(mailList);
   }
  
   global void finish(Database.BatchableContext bc) {
   }
}

excute sheduler class
 
global class scheduleExpireNotify implements Schedulable {
    global void execute(SchedulableContext sc) {
        expireNotify en = new expireNotify();
        Database.executeBatch(en);
    }
}




If It works  for  you please slelect my answer is best answer 
Thanks,
This was selected as the best answer
Varun SinghVarun Singh
please update your email in code insted of mine ;)
Varun SinghVarun Singh
Choose my Answer is best if it is working for  you
sonam gupthasonam guptha
varun,

its working,but it grabs the accounts more than 90 days even?
Varun SinghVarun Singh
try to  calculate days EndDate__c-today < =90

You can also use formula  field  which return type  will number type

For the number of  Days Remaining  the formula would be:

Datatype = Formula 
Result = Number 
Formula =  TheDateField__c - TODAY()