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
SalesforceCrm AccountCRMSalesforceCrm AccountCRM 

Add Conditions in Send Email Notification

Hello All,
I had a requirement where i need to send an email notification 100 days before the contract end date.So based on this we had a batch and schedule class written.Now we would like to add few more condition in the code.
We have two picklist value as 'Status Renewed' and "Status Renewed next Year".This picklist field has some values  as Status renewed for nxt quarter , pipeline etc the other picklist has renewed and renewed lost.
Condition is when the "Status Renewed" is equal to "Status renewed for next quarter " or "Pipeline" AND when "Status Renewed next Year" is not equal to "Renewed" or"Renewed lost".
So how do i give this condition in an execute method.When this condition is satisfied ,then the email notification should be sent to the owner before 100 days.

Batch and Schedule Class:
global class NotificationEmailtoAccountExecutive implements Database.Batchable < sObject >, Schedulable, Database.Stateful {
	global List<String> errorMessages = new List<String>();
    global Database.QueryLocator start(Database.BatchableContext bc) {
     
        Date ed = Date.today().addDays(100);
        System.debug(Date.today().addDays(100));
        
        set<Id> setContractIds = new set<Id>();

        for(Contract_role__c objContract: [SELECT  Contract__c FROM Contract_role__c WHERE Role__c = 'Subscription Administrator' AND Contract__r.EndDate =: ed]) {
			setContractIds.add(objContract.Contract__c);
        }
        
        return Database.getQueryLocator('Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email ,Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds');
    }

    global void execute(Database.BatchableContext bc, List < Contract > recs) {
        List < Messaging.SingleEmailMessage > mailList = new List < Messaging.SingleEmailMessage > ();
        for (Contract c: recs) {
            if (c.Contact_Email__c != null) {
                List < String > toAddresses = new List < String > ();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                toAddresses.add(c.Contact_Email__c);
	        toAddresses.add(c.Owner.Email);
                toAddresses.add(c.Account.Owner.Email);
                toAddresses.add(c.Owner.Manager.Email);
                toAddresses.add(c.Account.Owner.Manager.Email);
                mail.setToAddresses(toAddresses);
                mail.setSubject('Notification Before 100 Days of Contract End Date');
                String messageBody = '<html><body>Hi ' + c.Contract_Name__c  + ',<br>Your  Contract Expires within 100 Days . <br>Kindly take  action.<br><br><b>Regards,</b><br>ADP</body></html>';
                mail.setHtmlBody(messageBody);
                mailList.add(mail);
            }
        }
        Messaging.sendEmail(mailList);
    }

    global void finish(Database.BatchableContext bc) {
		AsyncApexJob aaj = [Select Id, Status, NumberOfErrors, JobItemsProcessed, MethodName, 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[] {aaj.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('JOB Salesforce NotificationEmailtoAccountExecutive Finished: ' + aaj.Status);
        String bodyText='Total Job Items ' + aaj.TotalJobItems + ' Number of records processed ' + aaj.JobItemsProcessed + ' with '+ aaj.NumberOfErrors + ' failures.\n';
        bodyText += 'Number of Error Messages ' + errorMessages.size() + '\n';
        bodyText += 'Error Message' + String.join(errorMessages, '\n');
        mail.setPlainTextBody(bodyText);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	}
	
	global void execute(SchedulableContext SC) {
        NotificationEmailtoAccountExecutive batchable = new NotificationEmailtoAccountExecutive();
		database.executebatch(batchable);
    }
}
Any help very much appreciated.

 
Mahesh DMahesh D
Hi,

Please try the below code:
 
return Database.getQueryLocator('Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email ,
Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds AND Status_Renewed__c IN: (\'Status renewed for next quarter\', \'Pipeline\') AND Status_Renewed_next_Year__c IN: (\'Renewed\', \'Renewed lost\')');

or
 
return Database.getQueryLocator('Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email ,
Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds AND Status_Renewed__c IN (\'Status renewed for next quarter\', \'Pipeline\') AND Status_Renewed_next_Year__c IN (\'Renewed\', \'Renewed lost\')');


Please do let me know if it helps you.

Regards,
Mahesh
SalesforceCrm AccountCRMSalesforceCrm AccountCRM
@Mahesh D :Thanks for your reply.The system throws an error when i use the above condition.
 line breaks not allowed in string literals at line 18 column -1    

 
Mahesh DMahesh D
return Database.getQueryLocator('Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email, Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds AND Status_Renewed__c IN: (\'Status renewed for next quarter\', \'Pipeline\') AND Status_Renewed_next_Year__c IN: (\'Renewed\', \'Renewed lost\')');

Try this,

Regardsm
Mahesh
SalesforceCrm AccountCRMSalesforceCrm AccountCRM
@Mahesh D :The system throw the error again and again .
I tried in this way :
Database.getQueryLocator([Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email, Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds AND Status_Renewed__c IN: ('Status renewed for next quarter', 'Pipeline') AND Status_Renewed_next_Year__c IN: ('Renewed', 'Renewed lost')]);
But still the system throws an error as :
Compile Error: expecting a right parentheses, found ','
Any Suggestion.

 
Abhi_TripathiAbhi_Tripathi
Try using this query in your batch
Database.getQueryLocator([Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email, Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds AND Status_Renewed__c IN ('Status renewed for next quarter', 'Pipeline') AND Status_Renewed_next_Year__c IN ('Renewed', 'Renewed lost')]);

it should work
Mahesh DMahesh D
Use the below one from my above post:
 
return Database.getQueryLocator('Select  id, Contract_Name__c, EndDate, Contact_Email__c, Contract_End_Date_2__c, Owner.Email, Owner.Manager.Email , Account.Owner.Email,Account.Owner.Manager.Email  FROM Contract  WHERE Id IN: setContractIds AND Status_Renewed__c IN (\'Status renewed for next quarter\', \'Pipeline\') AND Status_Renewed_next_Year__c IN (\'Renewed\', \'Renewed lost\')');

Regards,
Mahesh
SalesforceCrm AccountCRMSalesforceCrm AccountCRM
@Abhi_Tripathi ,@Mahesh D :Thanks for your response.I tried using the queries as suggested ,but no luck.
It works when i use :
return Database.getQueryLocator('Select  id, Contract_Name__c , EndDate ,Contact_Email__c, Contract_End_Date_2__c ,ownerId,Owner.Email, Account.Owner.Email  FROM Contract  WHERE Id IN: setContractIds');
and a email is sent .When i start giving / adding the condition in the query , i cant see any email is sent and in the debug logs nothing gets executed.Any help very much appreciated.
Mahesh DMahesh D
Make sure that you have matching records in your system before you execute the batch.

Regards,
Mahesh
SalesforceCrm AccountCRMSalesforceCrm AccountCRM
@Mahesh:I do have the records created and executes as per the code .But when i start adding the conditions it does not execute.I mean the o/p is not getting executed.
Abhi_TripathiAbhi_Tripathi
Try running your finish method code in developer Console, hardcode the email id of yours, check weather its sending mails or not
SalesforceCrm AccountCRMSalesforceCrm AccountCRM
@Abhi_Tripathi :How to execute the finish method.I didnt get ur point.
Ria SharmaRia Sharma
@mahesh D: I referenced above code and tried writing similar batch class but I am having hard time adding one condition. Can you look and help me out. My requirement is below:
1. Run batch apex on daily basis to send email notification 
2. Email should be send 30 days, 60 days and 90 days before contract end date on opportunity where stage is 8 
3. Email should go to only those contacts in associated account where 'sendemail' checkbox is true. 

Now my problem is how to add third condition and how to send email to contact email address. 
 
global class RenewalEmailNotification implements Database.Batchable < sObject >, Schedulable, Database.Stateful {
	global List<String> errorMessages = new List<String>();
    global Database.QueryLocator start(Database.BatchableContext bc) {
        /* Date d = Date.today();*/
        Date ed = Date.today().addDays(30);
        System.debug(Date.today().addDays(30));
         // This set will hold the Id's of the opportunities 
        Set <ID> OppIds = new Set <ID>(); 
        
        // Query all the Opportunities in your database that meet the selection criterial for update.
        //List <Opportunity> oppsToUpdate = new List <Opportunity>([SELECT Id FROM Opportunity]);
        List <Opportunity> oppsToUpdate = new List <Opportunity>([SELECT Id, StageName FROM Opportunity WHERE StageName IN ('8 Renewal', '8 Renewal (pending validation)', '8 Renewal (validated)', '8 Renewal (Quote Delivered to Customer)') AND Contract_End_Date__c=: ed]);
        
        // Return this list of opportunities, which will get passed to our execute() method below.
	    return Database.getQueryLocator('Select  id, Name , Owner.Email, Contract_End_Date__c FROM opportunity  WHERE Id IN: oppsToUpdate ');
    }
  
              
global void execute(Database.BatchableContext bc, List < opportunity > recs) {
   List < Messaging.SingleEmailMessage > mailList = new List < Messaging.SingleEmailMessage > ();  
        
        for (opportunity c: recs) {
            if (c.Account != null) {
                List < String > toAddresses = new List < String > ();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                toAddresses.add(c.Account.name);
				toAddresses.add(c.Owner.Email);
                mail.setToAddresses(toAddresses);
                mail.setSubject('Notification Before 30 Days of Contract End Date');
                String messageBody = '<html><body>Hi ' + c.Name  + ',<br>Your  Contract Expires within 30 Days . <br>Kindly take approriate action.<br><br><b>Regards,</b><br>RV</body></html>';
                mail.setHtmlBody(messageBody);
                mailList.add(mail);
            }
        }
        Messaging.sendEmail(mailList);
    }

    global void finish(Database.BatchableContext bc) {
		AsyncApexJob aaj = [Select Id, Status, NumberOfErrors, JobItemsProcessed, MethodName, 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[] {aaj.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('JOB Salesforce RenewalEmailNotification Finished: ' + aaj.Status);
        String bodyText='Total Job Items ' + aaj.TotalJobItems + ' Number of records processed ' + aaj.JobItemsProcessed + ' with '+ aaj.NumberOfErrors + ' failures.\n';
        bodyText += 'Number of Error Messages ' + errorMessages.size() + '\n';
        bodyText += 'Error Message' + String.join(errorMessages, '\n');
        mail.setPlainTextBody(bodyText);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	}
	
	global void execute(SchedulableContext SC) {
        RenewalEmailNotification batchable = new RenewalEmailNotification();
		database.executebatch(batchable);
    }
}