Usted está aquí:
Utilizar encapsulación en cálculos de Salesforce Spiff
El encapsulado está aislando un segmento de un cálculo de comisión en un campo calculado denominado separado. Esta técnica reduce el uso de memoria, simplifica la depuración, mejora la legibilidad y facilita el mantenimiento de su configuración a medida que cambian las reglas comerciales.
Ediciones necesarias
| Disponible en: Salesforce Classic (no disponible en todas las organizaciones) y Lightning Experience |
| Disponible en: Enterprise Edition, Unlimited Edition y Developer Edition |
| Está disponible a un coste adicional en: Edición profesional con API de servicios web activada |
¿Qué es el encapsulado?
Cuando escribe un cálculo de comisión, es tentador crear una expresión grande que combina cada condición, relación y operación aritmética. El encapsulado toma el enfoque opuesto: dividir la lógica en las unidades significativas más pequeñas, asignar un nombre a cada unidad y redactar el cálculo final a partir de esas piezas nombradas.
El encapsulado se produce en el nivel de campo calculado. En un plan bien estructurado, cada campo calculado realiza una única operación. Los cálculos de nivel inferior se alimentan de cálculos de nivel superior, que se alimentan del valor de pago final.
Considere un plan que paga a un representante una comisión por negociaciones divididas que se cerraron en el periodo actual, donde la parte del representante de los ingresos recurrentes anuales (ARR) supera un umbral. Sin encapsulación, una sola expresión combina cada condición y cada paso aritmético.
Calculated field, without encapsulation:
=if(CloseDate >= BeginningOfPeriod
AND CloseDate <= EndOfPeriod
AND OwnerId == UserId
AND ContractLength_Months__c > 12
AND Split_Percent__c != null
AND (Split_Percent__c * ARR) >= 20000,
Split_Percent__c * ARR * CommissionRate,
0)Esta expresión es difícil de leer, difícil de depurar en rastreo y frágil: un cambio de nombre de campo requiere buscar y modificar cada cálculo que hace referencia a él.
Con la encapsulación, cada condición y cada valor calculado se convierte en su propio campo nombrado. La expresión de pago final se lee directamente desde esos campos nombrados.
El siguiente ejemplo utiliza expresiones de filtro y campos calculados. Las expresiones de filtro devuelven verdadero o falso y solo utilizan lógica booleana; no admiten declaraciones de if(). Los campos calculados devuelven valores y admiten la sintaxis de expresión completa. Ambos se benefician de la encapsulación, pero por diferentes razones: Los campos calculados obtienen un beneficio de rendimiento (el motor evalúa cada campo cuándo y almacena el resultado), mientras que las expresiones de filtro obtienen un beneficio estructural (más fácil de leer, mantener y actualizar).
With encapsulation:
// Step 1 — Qualify the period (filter expression)
ClosedInPeriod = CloseDate >= BeginningOfPeriod
AND CloseDate <= EndOfPeriod
// Step 2 — Qualify the rep and deal type (filter expression)
ByRepMultiYear = OwnerId == UserId
AND ContractLength_Months__c > 12
// Step 3 — Compute the split amount (calculated field)
SplitARR = Split_Percent__c * ARR
// Step 4 — Qualify the threshold (filter expression)
SplitARREligible = Split_Percent__c != null
AND SplitARR >= 20000
// Step 5 — Final payout (calculated field)
Payout = if(ClosedInPeriod AND ByRepMultiYear AND SplitARREligible,
SplitARR * CommissionRate,
0)Para campos calculados, el motor de comisiones evalúa cada campo una vez y almacena el resultado; las referencias posteriores leen el valor almacenado en vez de volver a calcular la lógica. Las expresiones de filtro no comparten este comportamiento, ya que los filtros siempre se ejecutan como un todo independientemente de cómo están estructurados.
El campo Payout lee cuatro valores nombrados en vez de volver a calcular las mismas comparaciones aritméticas y de fecha en línea. Si cambia el nombre de Split_Percent__c, actualice SplitARR y SplitARREligible únicamente, la expresión de pago no se verá afectada.
Beneficios del encapsulado
El encapsulado ofrece estas ventajas sobre las expresiones monolíticas.
- Eficiencia de memoria. El motor de comisiones ejecuta un cálculo encapsulado una vez por declaración y almacena el resultado. Las referencias de cálculo posteriores leen el resultado almacenado en vez de volver a calcular la lógica. Este enfoque es especialmente valioso para cálculos que hacen referencia a grandes conjuntos de datos o relaciones cruzadas.
- Solución de problemas más fácil. Cuando un pago es incorrecto, rastree cada cálculo nombrado individualmente para encontrar dónde se desvía la lógica de las expectativas. En el ejemplo anterior, rastree
ClosedInPeriod,SplitARRySplitARREligiblepor separado para determinar qué condición excluye o incluye registros de forma incorrecta. Una expresión monolítica es difícil de inspeccionar porque el motor de comisión la evalúa como una única unidad. - Informes simplificados. Los campos calculados nombrados están disponibles como puntos de datos discretos para informes Spiff. Una expresión monolítica solo produce su resultado final. Los campos encapsulados le dan visibilidad sobre valores intermedios, como por ejemplo, la creación de informes sobre
SplitARRindependientemente de la aptitud para el pago. - Legisabilidad mejorada. Un cálculo de pago final que lee
SplitARR * CommissionRatees mucho más fácil de comprender que una expresión anidada equivalente. Los campos nombrados comunican la intención a cualquier usuario que revise el plan en el futuro. - Extensibilidad. Cuando cambia un campo de conector o cuando actualiza una regla comercial, una configuración bien encapsulada requiere un cambio en un solo lugar. En el ejemplo anterior, cambiar el umbral de aptitud de 20.000 a 25.000 significa actualizar únicamente
SplitARREligible. Una expresión monolítica que incrusta el umbral en línea requiere buscar y modificar cada filtro y cálculo que lo contiene.
Aplicar encapsulación a relaciones
Las relaciones entre objetos son uno de los lugares de mayor valor para aplicar encapsulación. Cada vez que un cálculo atraviesa una relación para recuperar un campo, consume memoria y tiempo de procesamiento. Encapsular la llamada de relación significa que el trabajo se produce una vez.
Tenga en cuenta estos enfoques cuando trabaje con objetos relacionados.
- Utilice rutas directas cuando esté disponible. Si necesita datos de Producto de oportunidad y División de oportunidad, utilice una relación directa OppProduct a División de oportunidad en vez de enrutar a través del objeto Oportunidad. Rutas más cortas significan menos travesías.
- Utilice relaciones de autoreferencia. En vez de crear OppToAccount y AccountToOpps como dos relaciones separadas, cree una relación OppToOpp donde la clave exclusiva es AccountId. Este enfoque logra el mismo resultado con una sola definición de relación.
- Realice cálculos en el objeto relacionado. En vez de extraer tres campos de un objeto relacionado y combinarlos en el cálculo del objeto actual, cree un campo calculado en el objeto relacionado que produzca el valor que necesita. A continuación, haga referencia a ese campo único a través de la relación. Una llamada de relación para recuperar un campo es menos costosa que una llamada de relación para recuperar múltiples campos.
Por ejemplo, en vez de hacer referencia a OppSplit.SplitPercent y OppSplit.ARR por separado a través de una relación y multiplicarlos en el cálculo de Oportunidad, cree un campo calculado de SplitARR en el objeto OppSplit. El cálculo de Oportunidad realiza a continuación una única llamada de relación para leer un valor precalculado.
Less efficient — two relationship traversals per record:
Payout = OppSplit.SplitPercent * OppSplit.ARR * Rate
More efficient — one relationship traversal per record:
// On OppSplit object:
SplitARR = SplitPercent * ARR
// On Opportunity object:
Payout = OppSplit.SplitARR * RateAplicar encapsulación con rastreo de captura
El encapsulado y el rastreo funcionan conjuntamente. Debido a que los cálculos encapsulados son campos nombrados por separado (los campos son discretos e identificados explícitamente), puede activar selectivamente el rastreo a nivel de campo. Puede desactivar el rastreo para cálculos intermedios que los representantes no necesitan ver y que implican grandes conjuntos de datos. Active el seguimiento de los valores de pago finales y las mediciones clave que los representantes revisan en sus extractos.
| Tipo de cálculo | Recomendación de rastreo | Motivo |
|---|---|---|
| Atraveses de relaciones | Desactivar | Cada desplazamiento almacena datos adicionales. Desactive el rastreo en campos de relaciones para reducir el consumo de memoria por declaración. |
| Variables acumuladas | Desactivar | Las variables acumuladas pasan por registros y almacenan valores intermedios. Rastrearlos expone la lógica interna que los representantes no necesitan y aumenta significativamente el uso de memoria. |
| Filtros dobles | Desactivar | Los filtros dobles implican cálculos de resumen intermedios y listas de Id. El rastreo en estos pasos crea ruido en la vista de representante sin agregar contexto útil. |
sum(), count(), let() funciones |
Desactivar | Estas funciones de agregación funcionan en grandes conjuntos de registros. Rastreo almacena datos para cada registro evaluado, lo que es costoso cuando el recuento de registros es alto. |
| Cálculos de YTD y grandes conjuntos de datos | Desactivar | Los totales del año hasta la fecha o del trimestre hasta la fecha exploran un gran número de registros históricos. El almacenamiento de rastreo para cada registro en ese conjunto consume una memoria significativa. Muestre el valor de salida en la declaración pero evite que el motor almacene el historial interno completo. |
| Tablas de índices, datos de cuotas u otros valores confidenciales | Desactivar | Rastreo hace que los valores intermedios sean visibles para los representantes en la vista de extracto y exportaciones. Desactive el rastreo en cualquier campo que haga referencia a datos que un representante no está autorizado a ver, como índices o cuotas para planes a los que no pertenece. |
| Campos de pago final y mediciones de cara al representante | Activar | Los representantes se basan en el rastreo para comprender cómo se calcula su comisión. Active el seguimiento en valores que aparecen en tarjetas de mediciones de extractos y la lista de obligaciones, así como en cualquier campo que los administradores de Comp necesitan para la creación de informes y exportaciones. |
Por ejemplo, si su lógica de pago incluye un total de ejecución del año hasta la fecha como un paso intermedio, encapsule ese total de ejecución como su propio campo con el rastreo desactivado. El campo de Payout al que hace referencia puede seguir teniendo el rastro activado, proporcionando al representante un número final sin exponer la lógica de acumulación interna.
// YTDCommissions — turn off trace (large dataset, internal only)
YTDCommissions = amounts_from(beginning_of_year(BeginningOfPeriod),
days_ago(BeginningOfPeriod, 1),
plan_name)
// CurrentPeriodPayout — turn on trace (rep-facing)
CurrentPeriodPayout = SplitARR * CommissionRate
// YTDTotal — turn on trace (rep-facing summary metric)
YTDTotal = YTDCommissions + CurrentPeriodPayout
