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 

Batch Class Error as System.StringException: Invalid id at mail.setTargetObjectId(c.Owner.Email)

Hello,
I have a written a Batch Class to send an notification email 60 days before the contract end date.I have created the email template and used in the code.But the system throws an error as :
Batch Class Error as System.StringException: Invalid id at line #29 
mail.setTargetObjectId(c.Owner.Email);
global class SixtyDaysNotificationEmail 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(60);
        System.debug(Date.today().addDays(60));
        
        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,  Account.Owner.Email ,Account.Owner.Manager.Email,Owner.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 > ();
                List < String > CcAddresses = new List < String > ();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                toAddresses.add(c.Contact_Email__c);
                ccAddresses.add(c.Account.Owner.Email);
               // toAddresses.add(c.Account.Owner.Manager.Email);
                mail.setToAddresses(toAddresses);
                mail.setCcAddresses(CcAddresses);
                mail.setTargetObjectId(c.Owner.Email);
                mail.setTemplateId('00X4B000000M3zx');
                mail.setSaveAsActivity(false);
               // mail.setSubject('Notification Before 100 Days of Contract End Date to Account Executive and Manager');
               // String messageBody = '<html><body>Hi ,The Contract Named ' + c.Contract_Name__c  + ',<br>Will get Expired within 60 Days . <br>Kindly take approriate action to inform the Customer.<br><br><b>Regards,</b><br>CAB</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);
    }
}
The targetobjectid should be for the contact.But when i use mail.setTargetObjectId(c.Contact_Email__c); the system throws the same error .
Any help very much appreciated.
 
 
Pankaj_GanwaniPankaj_Ganwani
You can also set UserId too. Use c.OwnerId instead. Make sure you are fetching the OwnerId field value in batch start method.
BALAJI CHBALAJI CH
Hi SalesforceCrm,

For "mail.setTargetObjectId", we need to set the ID of the user, not the Email. 
So you can try 
mail.setTargetObjectId(c.OwnerId);
​Please let me know if that works for you.

Best regards,
BALAJI



 
SalesforceCrm AccountCRMSalesforceCrm AccountCRM
@Pankaj_Ganwani ,@BALAJI CH :Thanks for your response.I have Custom object as Contact which has loop up relation with contract.If i use mail.setTargetObjectId(c.Contact__cId) , the system throws an error.Invalid field Contact__cId for SObject Contract.When i use mail.setTargetObjectId(c.CustomerSignedId) ,the system throws an error as REQUIRED_FIELD_MISSING, Missing targetObjectId with template.Any suggestion.
BALAJI CHBALAJI CH
For setTargetObjectId, we can use only the ID of the contact, lead, or user to which the email will be sent. The ID you specify sets the context and ensures that merge fields in the template contain the correct data.

For more information on setTargetObjectId, please find below link.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_single.htm

Best Regards,
BALAJI