Recherche…


Remarques

introduction

Contrairement aux objets personnalisés qui ont des enregistrements basés sur eux, les paramètres personnalisés vous permettent d'utiliser des ensembles de données personnalisés dans votre organisation ou de distinguer des utilisateurs ou des profils particuliers en fonction de critères personnalisés. Cela signifie, par exemple, que les administrateurs peuvent modifier les paramètres personnalisés de la hiérarchie pour désactiver les règles de workflow / validation pour des utilisateurs ou des profils uniques, sans avoir à les désactiver pour l'ensemble de l'organisation (voir l'exemple ci-dessus ).

Les règles de validation doivent généralement être désactivées temporairement lorsque:

  • Le code met à jour les anciens enregistrements, qui ont été modifiés pour la dernière fois avant qu'une règle de validation ne soit activée et ne répondent donc pas aux critères de la nouvelle règle.
  • Le code insère de nouveaux enregistrements sans les valeurs requises par les critères d'une règle de validation.

Les règles de workflow doivent généralement être désactivées temporairement lorsque:

  • Ils déclencheraient une alerte par e-mail ou une mise à jour sur le terrain qui écraserait ou perturberait les modifications apportées à l'enregistrement.

L'utilisation d'un paramètre personnalisé accorde aux administrateurs un certain contrôle déclaratif sur le code, de sorte que l'un des nombreux cas d'utilisation est que, lorsqu'ils sont utilisés, ils évitent de déployer du code pour désactiver les déclencheurs (voir l'exemple ci-dessus ).

Un avantage clé pour les développeurs est que les données du paramètre personnalisé sont exposées dans le cache de l'application, ce qui permet un accès efficace sans le coût des requêtes répétées sur la base de données. Ces données peuvent ensuite être utilisées par les champs de formule, les règles de validation, les flux, Apex et l’API SOAP - voir la documentation Salesforce .

Les limites et considérations relatives aux paramètres personnalisés sont documentées ici .

Liste des paramètres personnalisés

Il est possible de créer des paramètres personnalisés de liste également, les cas d'utilisation courants étant le stockage des abréviations d'état à deux lettres, des préfixes de numérotation internationaux et des numéros de catalogue pour les produits. Toutefois, Salesforce fait désormais la promotion de l'utilisation des types de métadonnées personnalisés au lieu des paramètres personnalisés de la liste.

Lorsque vous allez créer un nouveau paramètre personnalisé, le message suivant sera affiché

Conseil: utilisez des types de métadonnées personnalisés pour la configuration de l'application
Si vous envisagez d'utiliser des paramètres personnalisés, envisagez plutôt d'utiliser des types de métadonnées personnalisés. Contrairement aux paramètres personnalisés de liste, vous pouvez migrer les enregistrements de types de métadonnées personnalisés à l'aide des packages ou des outils d'API de métadonnées.

Les types de métadonnées personnalisés présentent des avantages supplémentaires par rapport aux paramètres personnalisés listés, comme décrit dans cette réponse . Et selon le développeur principal de CMDs "Il y a beaucoup plus de projets de types de métadonnées personnalisés que de paramètres personnalisés sur les stéroïdes."

Création et gestion de paramètres personnalisés

Création

Pour créer un paramètre personnalisé, accédez à:

Classique
Configuration> Développer> Paramètres personnalisés> Nouveau

Foudre
Configuration> Code personnalisé> Paramètres personnalisés> Nouveau

Créez votre paramètre (voir les remarques plus loin dans ce document pour connaître les différences entre les paramètres personnalisés de la hiérarchie et de la liste). Vous pouvez ignorer la liste de sélection Visibilité, sauf si vous prévoyez de déployer votre paramètre dans un package géré.

Pour créer vos champs de paramétrage, cliquez sur le bouton Nouveau et suivez le processus habituel pour créer un champ personnalisé.

La gestion

Une fois que vous avez créé votre ou vos champs, vous pouvez commencer à configurer le paramètre en cliquant sur le bouton Gérer.

Il est plus facile de gérer le paramètre si vous créez une nouvelle vue et incluez les champs que vous avez créés pour vous donner une vue d'ensemble complète du paramètre, en un coup d'œil. Le propriétaire de la configuration est l'utilisateur ou le profil auquel le paramètre s'applique.

Pour gérer le paramètre au niveau de l'organisation, cliquez sur le bouton Nouveau au-dessus de l'en-tête Valeur par défaut de l'organisation (dans la zone rouge ci-dessous).

Pour gérer le paramètre au niveau de l'utilisateur ou du profil, cliquez sur le bouton Nouveau dans la zone bleue ci-dessous.

Modifier un paramètre personnalisé

Utilisation des paramètres personnalisés de la hiérarchie pour désactiver les règles de workflow / validation

Paramètre personnalisé

Paramètre personnalisé

Champ de paramétrage personnalisé

Champ de paramétrage personnalisé

Valeur du champ de réglage personnalisé

Lorsque le champ est coché, la règle de validation est désactivée pour l'utilisateur en cours d'exécution ou, dans cet exemple, son profil -

Paramètre de paramétrage personnalisé - Profil

La règle peut également être désactivée pour toute une organisation Salesforce -

Paramètre de paramétrage personnalisé - Org

Règle de validation

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

Dans la règle ci-dessus, les deux critères doivent être évalués à TRUE pour que la règle soit déclenchée.

Comme la case à cocher All_Opportunity_Disabled__c pour TRUE lorsque le profil de l'utilisateur en cours d'exécution est System Administrator, la règle est évaluée à FALSE .

Règles de workflow

La même approche peut être appliquée pour désactiver les règles de workflow.

Utilisation des paramètres personnalisés de la hiérarchie pour désactiver le code Apex

Explication

Dans cet exemple, un simple déclencheur a été créé pour modifier la date de clôture d'une opportunité, qui est sur le point d'être insérée ou mise à jour, à une date ultérieure de 10 jours.

La case à cocher du paramètre personnalisé du contrôleur Apex permet de désactiver le code au niveau utilisateur / profil / org.

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

Test de l'unité

@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');
        }
    }
        
}

Mise à jour des paramètres personnalisés de la hiérarchie dans le code Apex

Vous souhaiterez peut-être mettre à jour vos paramètres personnalisés lors de l'exécution de votre code, pour désactiver les règles de validation ou de workflow.

Dans le code ci-dessous, j'ai créé une classe Apex programmable qui mettra à jour la date de clôture de toute opportunité dont la date de clôture est inférieure ou égale à 6 jours à compter de la date actuelle, pour changer la date à 20 jours.

J'utiliserai mon paramètre personnalisé Val_Rule_Cntrlr__c pour désactiver toute règle de validation qui m'empêcherait de mettre à jour les opportunités répondant à mes critères.

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

Pour m'assurer que mes règles de validation sont désactivées par les modifications apportées à mon paramètre personnalisé dans ma classe, j'ai créé une zone de case à cocher Trigger_Validation_Rule__c (qui ne serait pas visible pour les utilisateurs ou ajoutée aux mises en page) et une règle de validation avec ces critères:

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

J'ai ensuite défini le champ de la case à cocher sur true lors de la création de mes opportunités afin que les critères de règles soient remplis, si le champ de paramètre personnalisé n'est pas modifié par mon code.

@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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow