Buscar..


Observaciones

Introducción

A diferencia de los objetos personalizados que tienen registros basados ​​en ellos, la configuración personalizada le permite utilizar conjuntos de datos personalizados en su organización, o distinguir usuarios particulares o perfiles según criterios personalizados. Esto significa, por ejemplo, que los administradores pueden editar las configuraciones personalizadas de la jerarquía para desactivar las Reglas de flujo de trabajo / validación para usuarios individuales o perfiles, sin tener que desactivarlas para toda la organización (consulte el ejemplo Uso de las configuraciones personalizadas de la jerarquía para desactivar las Reglas de flujo de trabajo / validación arriba) ).

Las reglas de validación generalmente deben desactivarse temporalmente cuando:

  • El código está actualizando los registros antiguos, que se editaron por última vez antes de que se activara una regla de validación y, por lo tanto, no cumplen con los criterios de la regla más reciente.
  • El código es insertar nuevos registros sin los valores requeridos por los criterios de una regla de validación.

Las reglas de flujo de trabajo comúnmente deben desactivarse temporalmente cuando:

  • Activarían una alerta por correo electrónico o una actualización de campo que sobrescribiría o interferiría con los cambios que está realizando en el registro.

El uso de una configuración personalizada otorga a los administradores cierto control declarativo sobre el código, por lo que uno de los muchos casos de uso es que, cuando se utiliza, puede hacer que no sea necesario implementar el código para deshabilitar los desencadenantes (consulte el ejemplo de Uso de la configuración de jerarquía personalizada para deshabilitar el código de Apex). ).

Un beneficio clave para los desarrolladores es que los datos de configuración personalizada se exponen en el caché de la aplicación, lo que permite un acceso eficiente sin el costo de consultas repetidas a la base de datos. Estos datos pueden ser utilizados por campos de fórmula, reglas de validación, flujos, Apex y la API SOAP; consulte la documentación de Salesforce .

Los límites y consideraciones para la configuración personalizada se documentan aquí .

Lista de configuraciones personalizadas

También es posible crear Configuraciones personalizadas de lista, los casos de uso comunes incluyen el almacenamiento de abreviaturas de estado de dos letras, prefijos de marcación internacional y números de catálogo para productos. Sin embargo, Salesforce ahora está promoviendo el uso de Tipos de metadatos personalizados, en lugar de Listar configuraciones personalizadas.

Cuando vaya a crear una nueva configuración personalizada, se mostrará el siguiente mensaje

Consejo: use tipos de metadatos personalizados para la configuración de la aplicación
Si está pensando en utilizar la configuración personalizada de la lista, considere usar tipos de metadatos personalizados en su lugar. A diferencia de la configuración personalizada de la lista, puede migrar los registros de los tipos de metadatos personalizados mediante el uso de paquetes o herramientas de API de metadatos.

Los tipos de metadatos personalizados tienen beneficios adicionales frente a la lista de configuraciones personalizadas como se describe en esta respuesta . Y de acuerdo con el desarrollador líder de CMDs "Hay mucho más planeado para los tipos de metadatos personalizados que las configuraciones personalizadas en esteroides".

Creación y gestión de configuraciones personalizadas

Creación

Para crear una configuración personalizada, vaya a:

Clásico
Configuración> Desarrollar> Configuraciones personalizadas> Nuevo

Relámpago
Configuración> Código personalizado> Configuración personalizada> Nuevo

Cree su configuración (consulte las Observaciones más adelante en este documento para ver las diferencias entre las configuraciones personalizadas de Jerarquía y Lista). Puede ignorar la lista de selección Visibilidad, a menos que planee implementar su configuración en un paquete administrado.

Para crear los campos de configuración, haga clic en el botón Nuevo y siga el proceso habitual para crear un campo personalizado.

administración

Una vez que haya creado su (s) campo (s), puede comenzar a configurar la configuración haciendo clic en el botón Administrar.

Es más fácil administrar la configuración si crea una nueva vista e incluye cualquier campo que haya creado para brindarle una visión general completa de la configuración, de un vistazo. El propietario de la instalación es el usuario o el perfil al que se aplica la configuración.

Para administrar la configuración en el nivel de organización, haga clic en el botón Nuevo sobre el encabezado Valor de nivel de organización predeterminado (en el cuadro rojo a continuación).

Para administrar la configuración a nivel de usuario o perfil, haga clic en el botón Nuevo en el cuadro azul a continuación.

Editar configuración personalizada

Uso de la configuración personalizada de la jerarquía para deshabilitar el flujo de trabajo / reglas de validación

Configuración personalizada

Configuración personalizada

Campo de configuración personalizada

Campo de configuración personalizada

Valor de campo de configuración personalizada

Cuando se marque el campo, se desactivará la regla de validación, para el usuario en ejecución o, en este ejemplo, su perfil:

Configuración personalizada Edición de campo - Perfil

La regla también se puede deshabilitar para toda una organización de Salesforce:

Configuración personalizada Edición de campo - Organización

Regla de validación

AND(
  /* the below is the reference to the Val_Rule_Cntrlr__c custom setting's checkbox field All_Opportunity_Disabled__c
  */
  $Setup.Val_Rule_Cntrlr__c.All_Opportunity_Disabled__c = FALSE,

  /* the below is the remainder of the validation rule's formula
  */
  CloseDate < TODAY()
)

En la regla anterior, ambos criterios deben evaluarse en TRUE para que se TRUE la regla.

Dado que la casilla de verificación All_Opportunity_Disabled__c se evaluará como TRUE cuando el perfil del usuario en ejecución sea Administrador del sistema, la regla se evaluará como FALSE .

Reglas de flujo de trabajo

Se puede aplicar el mismo enfoque para desactivar las Reglas de flujo de trabajo.

Uso de la configuración personalizada de la jerarquía para deshabilitar el código de Apex

Explicación

En este ejemplo, se creó un Desencadenador simple para cambiar la Fecha de Cierre de una Oportunidad, que está a punto de insertarse o actualizarse, a una fecha de 10 días en el futuro.

El campo de la casilla de verificación de la configuración personalizada de Apex Controller permite que el código se deshabilite en el nivel de usuario / perfil / organización.

Clase de Apex

trigger CloseDateUpdate on Opportunity (before insert, before update) {
    
    Id userId;
    Apx_Cntrlr__c userApexController;
    Boolean userSetting;
    
    userId = userinfo.getUserId();
    userApexController = Apx_Cntrlr__c.getInstance(userId);
    userSetting = userApexController.Close_Date_Update_Disabled__c;

    if (userSetting == false) {
        for(Opportunity opp : Trigger.new) {
            opp.CloseDate = date.today().addDays(10);
        }
    }
    
}

Prueba de unidad

@isTest
public class CloseDateUpdateTest {
    
    @testSetup
    static void dataSetup() {
        
        Profile p = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        
        User u = new User(LastName = 'Test',Alias = 't1',Email = '[email protected]',Username = '[email protected]',ProfileId = p.Id,TimeZoneSidKey = 'America/Denver',LocaleSidKey = 'en_US',EmailEncodingKey = 'UTF-8',LanguageLocaleKey = 'en_US');
        insert u;
    }
    
    static testMethod void testCloseDateUpdateEnabled() {
        
        User u = [SELECT Id FROM User WHERE Username = '[email protected]'];
        // set the custom setting field to FALSE so that the trigger is not deactivated
        Apx_Cntrlr__c apexController = new Apx_Cntrlr__c(SetupOwnerId = u.Id,Close_Date_Update_Disabled__c = false);
        upsert apexController;
        
        Opportunity[] opportunities1 = new Opportunity[]{};
        
        test.startTest();
        system.runAs(u){
                
                for(integer i = 0; i < 200; i++) {
                    opportunities1.add(new Opportunity(
                        Name          = 'Test Opp ' + i,
                        OwnerId       = u.Id,
                        StageName     = 'Prospecting',
                        CloseDate     = date.today().addDays(1),
                        Amount        = 100));
                }
            insert opportunities1;
        }
        test.stopTest();
        
        List<Opportunity> opportunities2 = [SELECT CloseDate FROM Opportunity];
        
        for(Opportunity o : opportunities2){
            system.assertEquals(date.today().addDays(10), o.closeDate, 'CloseDateUpdate trigger should have changed the Opportunity close date as it was not disabled by the apexController custom setting');
        }
    }
    
    static testMethod void testCloseDateUpdateDisabled() {
        
        User u = [SELECT Id FROM User WHERE Username = '[email protected]'];
        // set the custom setting field to TRUE to deactivate the trigger
        Apx_Cntrlr__c apexController = new Apx_Cntrlr__c(SetupOwnerId = u.Id,Close_Date_Update_Disabled__c = true);
        upsert apexController;
        
        Opportunity[] opportunities1 = new Opportunity[]{};
            
        test.startTest();
        system.runAs(u){
            
            for(integer i = 0; i < 200; i++) {
                opportunities1.add(new Opportunity(
                    Name          = 'Test Opp ' + i,
                    OwnerId       = u.Id,
                    StageName     = 'Prospecting',
                    CloseDate     = date.today().addDays(1),
                    Amount        = 100));
            }
            insert opportunities1;
        }
        test.stopTest();
        
        List<Opportunity> opportunities2 = [SELECT CloseDate FROM Opportunity];
        
        for(Opportunity o : opportunities2){
            system.assertEquals(date.today().addDays(1), o.closeDate, 'CloseDateUpdate trigger should not have changed the Opportunity close date as it was disabled by the apexController custom setting');
        }
    }
        
}

Actualización de las configuraciones personalizadas de la jerarquía en el código de Apex

Es posible que desee actualizar la configuración personalizada durante la ejecución de su código, para desactivar las reglas de validación o flujo de trabajo.

En el código a continuación, he creado una Clase de Apex programable que actualizará la Fecha de cierre de cualquier oportunidad cuya Fecha de cierre sea inferior o igual a 6 días a partir de la fecha actual, cambiando la fecha a 20 días en el futuro.

Usaré mi Configuración personalizada Val_Rule_Cntrlr__c para desactivar cualquier regla de validación que me impida actualizar las oportunidades que cumplan con mis criterios.

global class Scheduled_OppCloseDateUpdate implements Schedulable {

    global void execute(SchedulableContext SC) {
        updOpportunityCloseDates();
    }

    global void updOpportunityCloseDates() {
        
        Id userId;
        Val_Rule_Cntrlr__c setting;
        Boolean validationRulesAlreadyDisabled;
        List<Opportunity> processedOpps = new List<Opportunity>();
        Date d;
        
        // get running user's Id
        userId = userinfo.getUserId();
        // retrieve Custom Setting status, for running user
        setting = Val_Rule_Cntrlr__c.getInstance(userId);
        
        // if the setting field is false, update it to disable validation rules
        if (setting.All_Opportunity_Disabled__c == false) {
            setting.All_Opportunity_Disabled__c = true;
            upsert setting;
        }
        // if the setting field was already true, there's no need to disable it
        // but it shouldn't be switched to false by this class once the process has been completed
        else {
            validationRulesAlreadyDisabled = true;
        }
        
        // execute code to manage business process
   
        d = system.today().addDays(6);
        
        for(Opportunity o : [SELECT Id, CloseDate
                               FROM Opportunity
                              WHERE CloseDate <= :d
                                // class only updates open Opportunities
                                AND Probability > 0 AND Probability < 100])
        {
            o.CloseDate = System.today().addDays(20);
            processedOpps.add(o);
        }
        
        if (processedOpps.size() > 0) {
            update processedOpps;
        }
        
        // reactivate validation rules
        if (validationRulesAlreadyDisabled == false) {
            setting.All_Opportunity_Disabled__c = false;
            upsert setting;
        }
        
    }
    
}

Para asegurarme de que mis reglas de validación están siendo desactivadas por los cambios en mi configuración personalizada en mi clase, he creado un campo de casilla de verificación Trigger_Validation_Rule__c (que no sería visible para los usuarios o agregado a los diseños de página) y una regla de validación con este criterio:

AND(
  $Setup.Val_Rule_Cntrlr__c.All_Opportunity_Disabled__c = FALSE,
  Trigger_Validation_Rule__c = TRUE,

  /* allow the above criteria to be met while inserting the Opportunities, without triggering the rule, in the @testSetup portion of the test */
  NOT(ISNEW())
)

Luego, establezco el campo de la casilla de verificación en true al crear mis Oportunidades para que se cumplan los criterios de las reglas, si el campo de configuración personalizada no es editado por mi código.

@isTest
private class WE_ScheduledCloseDateUpdateTest {

    @testSetup
    static void dataSetup() {

        Profile p = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        
        User u = new User(LastName = 'Test',Alias = 't1',Email = '[email protected]',Username = '[email protected]',ProfileId = p.Id,TimeZoneSidKey = 'America/Denver',LocaleSidKey = 'en_US',EmailEncodingKey = 'UTF-8',LanguageLocaleKey = 'en_US');
        insert u;

        Val_Rule_Cntrlr__c valRuleCntrlr = new Val_Rule_Cntrlr__c(SetupOwnerId = u.Id,All_Opportunity_Disabled__c = false);
        upsert valRuleCntrlr;
            
        List<Opportunity> testOpps = new List<Opportunity>();
            
        // create the Opportunities that will be updated by the class
        for(integer i = 0; i < 200; i++) {
            testOpps.add(new Opportunity(
                Name          = 'Test Opp Update' + i,
                OwnerId       = u.Id,
                StageName     = 'Prospecting',
                CloseDate     = date.today().addDays(1),
                Amount        = 100,
                // set checkbox field to true, to trigger validation rules if they've not been deactivated by class
                Trigger_Validation_Rule__c = true));
        }
        // create the Opportunities that won't be updated by the class
        for(integer i = 0; i < 200; i++) {
            testOpps.add(new Opportunity(
                Name          = 'Test Opp Skip' + i,
                OwnerId       = u.Id,
                StageName     = 'Prospecting',
                CloseDate     = date.today().addDays(15),
                Amount        = 100,
                Trigger_Validation_Rule__c = true));
        }           
        insert testOpps;

    }
    
    // code required to test a scheduled class, see https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm for more details
    public static String CRON_EXP = '0 0 0 15 3 ? 2022';

    static testmethod void testCloseDateUpdates() {

        // execute scheduled class
        
        Test.startTest();
        
        String jobId = System.schedule('ScheduleApexClassTest',
                                       CRON_EXP,
                                       new Scheduled_OppCloseDateUpdate());
        
        CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime
                            FROM CronTrigger
                           WHERE id = :jobId];
        
        System.assertEquals(CRON_EXP, ct.CronExpression);
        System.assertEquals(0, ct.TimesTriggered);
        System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));
        
        Test.stopTest();

        // test results
        
        Integer updateCount = 0;
        Integer skipCount   = 0;

        List <Opportunity> opportunitys = [SELECT Id, Name, CloseDate FROM Opportunity];

        for(Opportunity o : opportunitys) {
            if (o.Name.contains('Update') &&
                updateCount == 0)
            {
                System.assertEquals(date.today().addDays(20), o.CloseDate, 'Opportunity\'s Close Date should have been updated as it was less than 7 days away');
                updateCount = 1;
            }
            if (o.Name.contains('Skip') &&
                skipCount == 0)
            {
                System.assertEquals(date.today().addDays(15), o.CloseDate, 'Opportunity should not have been updated as it\'s Close Date is more than 7 days away');
                skipCount = 1;
            }
        }
        // check that both lists of Opportunities have been tested
        System.assertEquals(2, updateCount + skipCount, 'Count should be 2 once all assertions have been executed');
    
    }
    
    // check that the class does not change the custom setting's field to false, if it was true before class was executed
    static testmethod void testSettingUpdates() {
        
        User u = [SELECT Id FROM User WHERE UserName = '[email protected]'];
        
        // switch the custom setting field to true before the scheduled job executes
        Val_Rule_Cntrlr__c setting;
        setting = Val_Rule_Cntrlr__c.getInstance(u.Id);
        setting.All_Opportunity_Disabled__c = true;
        upsert setting;
        
        System.runAs(u) {
            
            Test.startTest();
            
            String jobId = System.schedule('ScheduleApexClassTest',
                                           CRON_EXP,
                                           new Scheduled_OppCloseDateUpdate());
            
            CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime
                                FROM CronTrigger
                               WHERE id = :jobId];
            
            System.assertEquals(CRON_EXP, ct.CronExpression);
            System.assertEquals(0, ct.TimesTriggered);
            System.assertEquals('2022-03-15 00:00:00', String.valueOf(ct.NextFireTime));
            
            Test.stopTest();
        }
        setting = Val_Rule_Cntrlr__c.getInstance(u.Id);
        
        // check that the class did not change the All_Opportunity_Disabled__c field to false
        System.assertEquals(true, setting.All_Opportunity_Disabled__c);
    }

}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow