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 

Help in Batch Class

Based on the requirement i have written a batch class.The Scenarios is i need to send an email notification 90 days before the contract end date to the contract owner.Where the contract role should be of 'SA'.But the email is not going to the contract owner.Correct me if the code written is correct or wrong.Any help very much appreciated.

Batch Class :
global class NotificationEmailtoOwner implements Database.Batchable < sObject > 
{
    global Database.QueryLocator start(Database.BatchableContext bc) 
    {
        Date ed = Date.today().addDays(90);
        System.debug(Date.today().addDays(90));

        set<Id> setContractIds = new set<Id>();
        set<Id> OwnerIds = new set<Id>();
        //Map<Id, User> userMap = new Map<Id,User>([select Name, Email from User where Id in :ownerIds]);

        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 FROM Contract  WHERE Id IN: setContractIds');
        return Database.getQueryLocator('select id, Name, Email from User where Id IN:OwnerIds');
    }

    global void execute(Database.BatchableContext bc, List < Contract > recs) 
    {
        List < Messaging.SingleEmailMessage > mailList = new List < Messaging.SingleEmailMessage > ();
        User u = [select Id from User where Profile.Name = 'System Administrator' Limit :1];
        for (Contract c: recs) 
        {
             c.OwnerId = u.Id;   

            if (c.Contact_Email__c!= null) 
            {
                List < String > toAddresses = new List < String > ();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                toAddresses.add(c.Contact_Email__c);
                mail.setToAddresses(toAddresses);
                mail.setSubject('Notification Before 90 Days of Contract End Date for the Contract Owner');
                String messageBody = '<html><body>Hi ' + c.Contract_Name__c  + ',<br>Your  Contract Expires within 90 Days . <br>Kindly take approriate action.<br><br><b>Regards,</b><br>EDBPSQL</body></html>';
                mail.setHtmlBody(messageBody);
                mailList.add(mail);
            }
        }
        Messaging.sendEmail(mailList);
    }

    global void finish(Database.BatchableContext bc) {}
}
Schedule Class :
global class scheduleNotificationEmailtoOwner implements Schedulable {
    global void execute(SchedulableContext sc) {
        NotificationEmailtoOwner neo = new  NotificationEmailtoOwner();
        Database.executeBatch(neo);
    }
}


 
pconpcon
The problem is that your query on line 16 is a string and the query doesn't resolve correctly.  I've taken the liberty to update your code.  This should do what you are looking for.
 
global class NotificationEmailtoOwner implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext bc) {
        Date ed = Date.today().addDays(90);

        Set<Id> setContractIds = new Set<Id>();
        Set<Id> OwnerIds = 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 Contract_Name__c,
                EndDate,
                Contact_Email__c,
                Contract_End_Date_2__c
            from Contract
            where Id in: setContractIds
        ]);
    }

    global void execute(Database.BatchableContext bc, List<Contract> recs) {
        List <Messaging.SingleEmailMessage> mailList = new List < Messaging.SingleEmailMessage > ();
        User u = [
            select Id
            from User
            where Profile.Name = 'System Administrator'
            limit 1
        ];

        for (Contract c: recs) {
            c.OwnerId = u.Id;

            if (c.Contact_Email__c == null) {
                continue;
            }

            List<String> toAddresses = new List<String> {
                c.Contact_Email__c
            };

            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setToAddresses(toAddresses);
            mail.setSubject('Notification Before 90 Days of Contract End Date for the Contract Owner');
            String messageBody = '<html><body>Hi ' + c.Contract_Name__c  + ',<br>Your Contract Expires within 90 Days . <br>Kindly take approriate action.<br><br><b>Regards,</b><br>EDBPSQL</body></html>';
            mail.setHtmlBody(messageBody);
            mailList.add(mail);
        }
        Messaging.sendEmail(mailList);
    }

    global void finish(Database.BatchableContext bc) {}
}
NOTE: This code has not been tested and may contain typographical or logical errors