Поиск…


замечания

Вступление

В отличие от пользовательских объектов, на которых записаны записи, пользовательские настройки позволяют использовать пользовательские наборы данных в вашей организации или различать отдельных пользователей или профили на основе пользовательских критериев. Это означает, например, что администраторы могут редактировать пользовательские настройки иерархии для деактивации правил Workflow / Validation для одиночных пользователей или профилей без необходимости их отключения для всей организации (см. Пример использования пользовательских настроек «Использовать иерархию» для отключения примера рабочего процесса / проверки ).

Правила проверки обычно должны быть временно отключены, когда:

  • Код обновляет старые записи, которые в последний раз редактировались до того, как было активировано правило проверки и поэтому не соответствуют критериям нового правила.
  • Код вставляет новые записи без значений, требуемых критериями правила проверки.

Правила рабочего процесса обычно необходимо временно отключать, когда:

  • Они будут запускать уведомление по электронной почте или полевое обновление, которое будет перезаписывать или вмешиваться в изменения, внесенные вами в запись.

Использование настраиваемой настройки предоставляет администраторам некоторый декларативный контроль над кодом, поэтому один из многих вариантов использования заключается в том, что при использовании они могут сделать ненужным развертывание кода для отключения триггеров (см. Пример использования пользовательских настроек «Использовать иерархию» для отключения примера Apex Code выше ).

Ключевым преимуществом для разработчиков является то, что данные пользовательских настроек отображаются в кеше приложений, что обеспечивает эффективный доступ без затрат на повторные запросы к базе данных. Эти данные затем могут использоваться полями формул, правилами проверки, потоками, Apex и SOAP API - см. Документацию Salesforce .

Ограничения и соображения для пользовательских настроек описаны здесь .

Список пользовательских настроек

Можно также создавать списки пользовательских настроек, общие случаи использования включают хранение двухбуквенных сокращений состояний, префиксов международного набора и номеров каталогов для продуктов. Однако Salesforce теперь продвигает использование пользовательских типов метаданных вместо пользовательских настроек списка.

Когда вы перейдете к созданию новой пользовательской настройки, отобразится следующее сообщение

Совет. Используйте настраиваемые типы метаданных для конфигурации приложения.
Если вы планируете использовать настраиваемые параметры списка, вместо этого используйте вместо них собственные типы метаданных. В отличие от настраиваемых параметров списка, вы можете перенести записи пользовательских типов метаданных с помощью пакетов или инструментов API метаданных.

Пользовательские типы метаданных обладают дополнительными преимуществами и списком пользовательских настроек, как описано в этом ответе . И, по словам ведущего разработчика CMD, «гораздо больше запланировано для пользовательских типов метаданных, чем для пользовательских настроек стероидов».

Создание и управление пользовательскими настройками

Создание

Чтобы создать пользовательскую настройку, перейдите по ссылке:

классический
Настройка> Разработка> Пользовательские настройки> Новый

молниеносный
Настройка> Пользовательский код> Пользовательские настройки> Новый

Создайте свой параметр (см. Примечания далее в этом документе для различий между пользовательскими настройками Hierarchy & List). Вы можете игнорировать список выбора видимости, если вы не планируете развертывать свои настройки в управляемом пакете.

Чтобы создать свои поля настроек, нажмите кнопку «Создать» и следуйте обычным процедурам создания настраиваемого поля.

управление

После того, как вы создали свое поле (ы), вы можете начать настройку этого параметра, нажав кнопку «Управление».

Легче управлять настройкой, если вы создаете новое представление и включаете любые поля, которые вы создали, чтобы дать вам полный обзор настроек с первого взгляда. Владелец установки - это пользователь или профиль, к которым применяется данный параметр.

Чтобы управлять настройкой на уровне организации, нажмите кнопку «Создать» над заголовком «Значение уровня организации по умолчанию» (в красном поле ниже).

Чтобы управлять настройкой на уровне пользователя или профиля, нажмите кнопку «Создать» в синем поле ниже.

Изменить пользовательскую настройку

Использование пользовательских настроек иерархии для отключения правил документооборота / валидации

Пользовательская настройка

Пользовательская настройка

Пользовательское поле настройки

Пользовательское поле настройки

Значение поля настраиваемой настройки

Когда поле будет проверено, правило проверки будет отключено для текущего пользователя или в этом примере, их профиль -

Пользовательское поле настройки поля - Профиль

Это правило также может быть отключено для всей организации Salesforce org -

Редактирование поля пользовательской настройки - Org

Правило проверки

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

В приведенном выше правиле обе части критериев должны оцениваться в TRUE чтобы правило было инициировано.

Поскольку флажок All_Opportunity_Disabled__c будет оцениваться как TRUE когда All_Opportunity_Disabled__c профиль пользователя будет системным администратором, правило будет оцениваться как FALSE .

Правила рабочего процесса

Такой же подход может применяться для деактивации правил рабочего процесса.

Использование пользовательских настроек иерархии для отключения кода Apex

объяснение

В этом примере был создан простой триггер , чтобы изменить дату закрытия возможности, которая должна быть вставлена ​​или обновлена, до даты 10 дней в будущем.

Поле флажка «Пользовательские настройки» Apex Controller позволяет отключить код на уровне пользователя / профиля / организации.

Класс 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);
        }
    }
    
}

Модульный тест

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

Изменение пользовательских настроек иерархии в коде Apex

Возможно, вы захотите обновить свои пользовательские настройки во время выполнения кода, чтобы отключить правила проверки или рабочего процесса.

В приведенном ниже коде я создал Schedulable Apex Class, который будет обновлять дату закрытия любых возможностей, дата закрытия которых меньше или равна 6 дням с текущей даты, изменяя дату на 20 дней в будущем.

Я буду использовать свою пользовательскую настройку Val_Rule_Cntrlr__c для деактивации любых правил проверки, которые помешали бы мне обновить возможности, соответствующие моим критериям.

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

Чтобы убедиться, что мои правила проверки деактивированы изменениями моей пользовательской настройки в моем классе, я создал поле флажка Trigger_Validation_Rule__c (которое не было бы видимым для пользователей или добавлено в макеты страниц) и правилом проверки с этими критериями:

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

Затем я устанавливаю поле флажка в true при создании моих возможностей, чтобы критерии соответствия выполнялись, если пользовательское поле настроек не редактируется моим кодом.

@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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow