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
❤Code❤Code 

batch class to Calculate no of contact roles on opportunity!!!!!

Hi All,

I have a requirement where i need to have a batch class which calculates no of contact roles on opportunity and display on a custom field on opportunity. Can anyone help me with this how to write it.

Regards
Mahesh DMahesh D
Hi

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

    //Variable Section
    global FINAL String strQuery;
    global List<String> errorMessages = new List<String>();
    
    global ProcessOpportunityBatch() { 
        this.strQuery = getBatchQuery();
    }
    
    //Returns the Query String to Batch constructor to fetch right records.
    private String getBatchQuery() {
        String strQuery = 'Select Id, Num_Contact_Roles__c, (Select OpportunityId From OpportunityContactRoles) From Opportunity'; 
        return strQuery;
    }
    
    //Batch Start method
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(strQuery);
    }

    //Batch Execute method calls findCostForWoD method
    global void execute(Database.BatchableContext BC, List<sObject> scopeList) {
        System.debug(LoggingLevel.INFO, '== scopeList size ==' + scopeList.size());
        
        List<Opportunity> oppList = (List<Opportunity>) scopeList;
            
        for(Opportunity opp: oppList) {
            opp.Num_Contact_Roles__c = opp.OpportunityContactRoles.size();
        }
        
        
        try {                    
            Database.SaveResult[] saveResults = Database.update(oppList, false);
            for (Database.SaveResult sr : SaveResults) {
                if(!sr.isSuccess()) {
                    for (Database.Error err : sr.getErrors()) {
                        errorMessages.add('Error: ' + err.getStatusCode() + ': ' + err.getMessage());
                    }
                    system.debug(sr.getErrors()[0].getMessage());
                }
            }
            System.debug('errorMessages: '+errorMessages);
        } catch (System.Exception ex) {
            System.debug('An error occurred when updating Opportunity Batch: ' + ex.getMessage());
            return;
        }
    }  

    //Batch Finish method for after execution of batch work
    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 ProcessOpportunityBatch 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 });
    }
    
    //Method which schedules the ProcessOpportunityBatch 
    global void execute(SchedulableContext sc) {
        ProcessOpportunityBatch pob = new ProcessOpportunityBatch();
        ID batchprocessid = Database.executeBatch(pob);
    }
}

I also verified the above code by running it in my DE environement and it is working properly.

Please do let me know if it helps you.

Regards,
Mahesh