Loading

Contract Renewal Automation in Salesforce CPQ

Publiseringsdato: Sep 27, 2025
Beskrivelse
In Salesforce CPQ you can Renew Your Contracts and Assets  by manually checking the contract's renewal forecast or renewal quoted fields. If you would like to automate your contract renewal process, follow the best practices below to renew contracts via scheduled apex batch jobs.
 
Løsning
To automate the contract renewal process, it is recommended to perform this task by making use of a Scheduled Apex class to execute a Batch Apex class on the Contract object with a batch size of 1. The batch Apex class can query all of the desired records to renew and set the SBQQ__RenewalForecast__c or the SBQQ__RenewalQuoted__c field. The below example queries all contracts in the org where neither SBQQ__RenewalForecast__c nor SBQQ__RenewalQuoted__c are checked. Then, it sets SBQQ__RenewalForecast__c on those contracts to true in order to generate renewal opportunities. It also sends an email to the user who created the batch to inform them of the status of the batch processing.
 
///***Batch Apex Class***

global class RenewContractsBatch implements Database.Batchable<SObject>, Database.Stateful {
	global Integer recordsProcessed = 0;

	global Database.QueryLocator start(Database.BatchableContext bc){
		return Database.getQueryLocator(
			//This is where you input the conditions for the records which you wish to set renewal for 
			'SELECT SBQQ__RenewalForecast__c, SBQQ__RenewalQuoted__c, Id FROM Contract WHERE SBQQ__RenewalForecast__c = FALSE AND SBQQ__RenewalQuoted__c = FALSE'
		);
	}
	global void execute(Database.BatchableContext bc, List<Contract> scope){
		for(Contract contract:scope){
			contract.SBQQ__RenewalForecast__c = TRUE;
			recordsProcessed = recordsProcessed + 1;
		}
		update scope;
	}
	global void finish(Database.BatchableContext bc){
       // Get the ID of the AsyncApexJob representing this batch job
       // from Database.BatchableContext.
       // Query the AsyncApexJob object to retrieve the current job's information.
       AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
          TotalJobItems, CreatedBy.Email
          FROM AsyncApexJob WHERE Id =
          :BC.getJobId()];
       // OPTIONAL: Send an email to the Apex job's submitter notifying of job completion.
       Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       String[] toAddresses = new String[] {a.CreatedBy.Email};
       mail.setToAddresses(toAddresses);
       mail.setSubject('Contract Renewal Batch ' + a.Status);
       mail.setPlainTextBody
       ('The batch Apex job processed ' + a.TotalJobItems +
       ' batches with '+ a.NumberOfErrors + ' failures.');
       Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	}
}

With the Batch Apex class created, a Schedulable apex class must be created to invoke the Batch apex class automatically. When invoking the Batch apex class, it is important to use a batch size of 1 to avoid running into org limits for individual Apex processes.
 
//***Schedulable Apex Class***

global class RenewSchedule implements Schedulable {
    global void execute(SchedulableContext ctx) {
        RenewContractsBatch batchObject = new RenewContractsBatch();
		Id batchId = Database.executeBatch(batchObject, 1);
    }
}

After you have created your batch class and the Schedule class to invoke it, you can choose to run your renewal batch daily using the standard Salesforce Schedule Apex interface found by clicking the 'Schedule Apex' button on the Apex Classes list in Setup. However, if you wish for your batch to run more frequently, you can execute some form of the following code. The example below is for setting the RenewSchedule class from above to run every 10 minutes. The batch is being set to run every hour on the 0, 10, 20, 30, 40, and 50 minute marks.

For more information about the System.schedule method, see this developer documentation article.
 
//***Anonymous Apex to Set Up Scheduled Apex Execution***

RenewSchedule c = new RenewSchedule();
String sch0 = '0 0 * * * ?';
System.schedule('Renew Contracts 0', sch0, c);

String sch1 = '0 10 * * * ?';
System.schedule('Renew Contracts 10', sch1, c);

String sch2 = '0 20 * * * ?';
System.schedule('Renew Contracts 20', sch2, c);

String sch3 = '0 30 * * * ?';
System.schedule('Renew Contracts 30', sch3, c);

String sch4 = '0 40 * * * ?';
System.schedule('Renew Contracts 40', sch4, c);

String sch5 = '0 50 * * * ?';
System.schedule('Renew Contracts 50', sch5, c);

Note: Time-Based Workflow rules can be used to renew automatically for customers that do not process many contracts. However, if you are ever attempting to renew multiple contracts in the same workflow automation, you will risk running into Apex limits. Running batch jobs with size 1 will bypass such Apex limits. When using Time-Based Workflow rules, make sure that the Default Workflow User is a system admin or a user who has all the proper access to CPQ objects and the records. Identify Your Salesforce Org’s Default Workflow User by clicking on the link.
It is not recommended to use a Scheduled Flow to automate renewal. The Scheduled Flow will return an error when used to automate renewal. A scheduled flow uses an "internal" user to run the process. The user is called Automated Process. This user is not accessible nor configurable and will not have the proper access to CPQ. Feel free to upvote this Idea regarding the Automated Process user.
Knowledge-artikkelnummer

000383568

 
Laster
Salesforce Help | Article