Loading

Automatización de renovaciones de contrato en Salesforce CPQ

Fecha de publicación: Sep 27, 2025
Descripción
En Salesforce CPQ, para renovar los contratos y activos, se pueden comprobar de manera manual los campos de renovación prevista o renovación presupuestada. Si desea automatizar el proceso de renovación de contratos, siga las prácticas recomendadas que figuran a continuación para hacerlo mediante trabajos por lotes de Apex programados.
 
Solución
A fin de automatizar el proceso de renovación de contratos, se recomienda usar una clase de Apex programada para ejecutar una clase de Apex por lotes en el objeto Contrato con un tamaño de lote de 1. Con la clase de Apex por lotes se pueden consultar todos los registros deseados para renovar y establecer los campos SBQQ__RenewalForecast__c o SBQQ__RenewalQuoted__c. En el ejemplo que figura a continuación se consultan todos los contratos de la organización donde no está marcado SBQQ__RenewalForecast__c ni SBQQ__RenewalQuoted__c. Luego, se establece SBQQ__RenewalForecast__c como verdadero en dichos contratos para generar oportunidades de renovación. Además, se envía un correo electrónico al usuario que creó el lote para informarle del estado del proceso por lotes.
 
///***Clase de Apex por lotes***

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

	global Database.QueryLocator start(Database.BatchableContext bc){
		return Database.getQueryLocator(
			//Aquí es donde debe introducir las condiciones para los registros en los que quiere establecer la renovación. 
			'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){
       // Obtenga el Id. del AsyncApexJob que representa este trabajo por lotes.
       // from Database.BatchableContext.
       // Consulte el objeto AsyncApexJob para recuperar la información del trabajo actual.
       AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
          TotalJobItems, CreatedBy.Email
          FROM AsyncApexJob WHERE Id =
          :BC.getJobId()];
       // OPCIONAL: Notifique por correo electrónico a quien envió el trabajo de Apex sobre el trabajo terminado.
       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 });
	}
}

Una vez creada la clase de Apex por lotes, para invocarla de manera automática, se debe crear una clase de Apex programable. Cuando se invoca a la clase de Apex por lotes, es importante usar un tamaño de lote de 1 a fin de evitar alcanzar los límites de la organización con relación a los procesos de Apex individuales.
 
//***Clase de Apex programable***

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

Después de crear la clase por lotes y la clase programada para invocarla, puede optar por ejecutar el lote de renovación de forma diaria con la interfaz de Apex programada de Salesforce. Para ello, haga clic en el botón "Programar Apex" en la lista Clases de Apex en Configuración. Si desea que el lote se ejecute con mayor frecuencia, puede ejecutar una versión del siguiente código. El ejemplo que se encuentra a continuación es para que la clase anterior RenewSchedule se ejecute cada 10 minutos. Se establece que el lote se ejecute cada hora en los minutos 0, 10, 20, 30, 40 y 50.

Para obtener más información sobre el método System.schedule, consulte este artículo de la documentación para desarrolladores.
 
//***Apex anónimo para configurar la ejecución programada de Apex***

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);

Nota: Aquellos clientes que no procesen demasiados contratos pueden usar reglas de flujo de trabajo basadas en tiempo para renovaciones automáticas. Si intenta renovar varios contratos con la misma automatización de flujo de trabajo, corre el riesgo de alcanzar los límites de Apex. Ejecutar trabajos por lotes con tamaño 1 hará que omita esos límites de Apex. Cuando utilice reglas de flujo de trabajo basadas en tiempo, asegúrese de que el usuario predeterminado del flujo de trabajo sea un administrador del sistema o un usuario con todos los permisos adecuados de acceso a registros y objetos de CPQ. Puede hacer clic en el vínculo para identificar el usuario de flujo de trabajo predeterminado de su Salesforce Org.
No se recomienda usar un flujo programado para automatizar la renovación. Se mostrará un mensaje de error en el flujo programado si lo hace. Un flujo programado utiliza un usuario "interno" para ejecutar el proceso. El usuario se denomina "Proceso automatizado". No se puede acceder a este usuario ni configurarlo, y no tendrá el acceso adecuado a CPQ. Puede votar a favor de esta idea sobre el usuario Proceso automatizado.
Número del artículo de conocimiento

000383568

 
Cargando
Salesforce Help | Article