Szukaj…


Uwagi

Wprowadzenie

W przeciwieństwie do obiektów niestandardowych, które mają rekordy na nich oparte, ustawienia niestandardowe pozwalają wykorzystywać niestandardowe zestawy danych w całej organizacji lub rozróżniać poszczególnych użytkowników lub profile na podstawie niestandardowych kryteriów. Oznacza to na przykład, że administratorzy mogą edytować niestandardowe ustawienia hierarchii, aby dezaktywować reguły przepływu pracy / sprawdzania poprawności dla pojedynczych użytkowników lub profili, bez konieczności wyłączania ich dla całej organizacji (patrz przykład Korzystanie z ustawień niestandardowych hierarchii w celu wyłączenia reguł przepływu pracy / sprawdzania poprawności powyżej ).

Reguły sprawdzania poprawności zwykle trzeba tymczasowo wyłączyć, gdy:

  • Kod aktualizuje stare rekordy, które były ostatnio edytowane przed aktywacją reguły sprawdzania poprawności i dlatego nie spełniają kryteriów nowszej reguły.
  • Kod wstawia nowe rekordy bez wartości wymaganych przez kryteria reguły sprawdzania poprawności.

Reguły przepływu pracy zwykle muszą być tymczasowo wyłączone, gdy:

  • Wywołałyby one alert e-mail lub aktualizację pola, które zastąpiłyby lub zakłóciłyby zmiany wprowadzone w rekordzie.

Zastosowanie ustawienia niestandardowego zapewnia administratorom pewną deklaratywną kontrolę nad kodem, więc jednym z wielu przypadków użycia jest to, że gdy są używane, mogą sprawić, że wdrożenie kodu w celu wyłączenia wyzwalaczy nie będzie konieczne (patrz przykład Używanie niestandardowych ustawień hierarchii do wyłączania kodu apex powyżej ).

Kluczową korzyścią dla programistów jest to, że dane ustawień niestandardowych są widoczne w pamięci podręcznej aplikacji, co umożliwia efektywny dostęp bez ponoszenia kosztów powtarzających się zapytań do bazy danych. Dane te mogą być następnie wykorzystane przez pola formuły, reguły sprawdzania poprawności, przepływy, apeks i interfejs API SOAP - patrz dokumentacja Salesforce .

Ograniczenia i uwagi dotyczące ustawień niestandardowych są udokumentowane tutaj .

Wyświetl ustawienia niestandardowe

Możliwe jest również tworzenie niestandardowych ustawień listy, typowe przypadki użycia obejmują przechowywanie dwuliterowych skrótów stanu, prefiksów wybierania międzynarodowego i numerów katalogowych produktów. Jednak Salesforce promuje teraz używanie niestandardowych typów metadanych zamiast listy ustawień niestandardowych.

Po utworzeniu nowego ustawienia niestandardowego zostanie wyświetlony następujący komunikat

Wskazówka: użyj niestandardowych typów metadanych do konfiguracji aplikacji
Jeśli zastanawiasz się nad użyciem ustawień niestandardowych listy, rozważ użycie niestandardowych typów metadanych. W przeciwieństwie do listy ustawień niestandardowych można migrować rekordy niestandardowych typów metadanych przy użyciu pakietów lub narzędzi interfejsu API metadanych.

Niestandardowe typy metadanych mają dodatkowe zalety w porównaniu z ustawieniami niestandardowymi listy, jak opisano w tej odpowiedzi . Według głównego twórcy CMD „Niestandardowe typy metadanych są planowane o wiele więcej niż niestandardowe ustawienia na sterydach”.

Tworzenie i zarządzanie ustawieniami niestandardowymi

kreacja

Aby utworzyć ustawienie niestandardowe, przejdź do:

Klasyczny
Setup> Develop> Custom Settings> New

Błyskawica
Ustawienia> Kod niestandardowy> Ustawienia niestandardowe> Nowy

Utwórz swoje ustawienie (zobacz Uwagi w dalszej części tego dokumentu, aby zobaczyć różnice między niestandardowymi ustawieniami Hierarchia i lista). Możesz zignorować listę wyboru Widoczność, chyba że planujesz wdrożyć ustawienia w pakiecie zarządzanym.

Aby utworzyć pola ustawień, kliknij przycisk Nowy i postępuj zgodnie ze zwykłym procesem tworzenia niestandardowego pola.

Zarządzanie

Po utworzeniu pola (pól) możesz rozpocząć konfigurowanie ustawienia, klikając przycisk Zarządzaj.

Łatwiej jest zarządzać ustawieniem, jeśli utworzysz nowy widok i dodasz wszystkie utworzone pola, aby uzyskać kompleksowy przegląd tego ustawienia na pierwszy rzut oka. Właściciel instalacji to użytkownik lub profil, którego dotyczy ustawienie.

Aby zarządzać ustawieniem na poziomie organizacji, kliknij przycisk Nowy nad nagłówkiem Domyślna wartość poziomu organizacji (w czerwonym polu poniżej).

Aby zarządzać ustawieniem na poziomie użytkownika lub profilu, kliknij przycisk Nowy w niebieskim polu poniżej.

Edytuj ustawienia niestandardowe

Korzystanie z niestandardowych ustawień hierarchii w celu wyłączenia reguł przepływu pracy / sprawdzania poprawności

Ustawienia niestandardowe

Ustawienia niestandardowe

Pole ustawień niestandardowych

Pole ustawień niestandardowych

Wartość pola ustawienia niestandardowego

Gdy pole jest zaznaczone, reguła sprawdzania poprawności zostanie wyłączona, dla działającego użytkownika lub w tym przykładzie jego profil -

Edycja pola ustawienia niestandardowego - profil

Regułę można również wyłączyć dla całej organizacji Salesforce -

Edycja pola ustawień niestandardowych - organizacja

Reguła walidacji

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

W powyższej regule oba kryteria muszą mieć wartość TRUE , aby reguła została uruchomiona.

Ponieważ All_Opportunity_Disabled__c wyboru All_Opportunity_Disabled__c ma wartość TRUE gdy profil uruchomionego użytkownika to Administrator systemu, reguła zostanie ustawiona na FALSE .

Reguły przepływu pracy

To samo podejście można zastosować w celu dezaktywacji Reguł przepływu pracy.

Korzystanie z niestandardowych ustawień hierarchii w celu wyłączenia kodu apeksowego

Wyjaśnienie

W tym przykładzie utworzono prosty wyzwalacz , aby zmienić datę zamknięcia szansy, która ma zostać wstawiona lub zaktualizowana, na datę 10 dni w przyszłości.

Pole wyboru niestandardowego ustawienia Apex Controller umożliwia wyłączenie kodu na poziomie użytkownika / profilu / organizacji.

Klasa wierzchołkowa

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 jednostkowy

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

Aktualizowanie niestandardowych ustawień hierarchii w kodzie apeksowym

Możesz zaktualizować ustawienia niestandardowe podczas wykonywania kodu, aby wyłączyć reguły sprawdzania poprawności lub przepływu pracy.

W poniższym kodzie utworzyłem klasę apeksowalnego harmonogramu, która zaktualizuje datę zamknięcia wszelkich szans, których data zamknięcia jest mniejsza lub równa 6 dniom od bieżącej daty, zmieniając datę na 20 dni w przyszłości.

Wykorzystam moje ustawienie niestandardowe Val_Rule_Cntrlr__c, aby dezaktywować wszelkie reguły sprawdzania poprawności, które uniemożliwiłyby mi aktualizację możliwości spełniających moje kryteria.

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

Aby upewnić się, że moje reguły sprawdzania poprawności są dezaktywowane przez zmiany mojego niestandardowego ustawienia w mojej klasie, utworzyłem pole wyboru Trigger_Validation_Rule__c (które nie byłoby widoczne dla użytkowników lub dodane do układów stron) oraz regułę sprawdzania poprawności z tymi kryteriami:

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

Następnie ustawiam pole wyboru na wartość true podczas tworzenia moich możliwości, aby kryteria reguły były spełnione, jeśli niestandardowe pole ustawień nie jest edytowane przez mój kod.

@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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow