Salesforce
Impostazioni personalizzate
Ricerca…
Osservazioni
introduzione
A differenza degli oggetti personalizzati che dispongono di record basati su di essi, le impostazioni personalizzate consentono di utilizzare set di dati personalizzati nell'organizzazione o di distinguere determinati utenti o profili in base a criteri personalizzati. Ciò significa, ad esempio, che gli amministratori possono modificare le impostazioni personalizzate della gerarchia per disattivare le regole di flusso di lavoro / convalida per singoli utenti o profili, senza doverli disattivare per l'intera organizzazione (vedere Esempio di utilizzo delle regole personalizzate della gerarchia per disabilitare il flusso di lavoro / regole di convalida sopra ).
Normalmente le regole di convalida devono essere disabilitate temporaneamente quando:
- Il codice sta aggiornando i vecchi record, che sono stati modificati l'ultima volta prima che fosse attivata una regola di convalida e quindi non soddisfano i criteri della nuova regola.
- Il codice sta inserendo nuovi record senza i valori richiesti dai criteri di una regola di convalida.
Normalmente le regole del flusso di lavoro devono essere disabilitate temporaneamente quando:
- Avrebbero attivato un avviso via email o un aggiornamento sul campo che avrebbe sovrascritto o interferito con le modifiche apportate al record.
L'utilizzo di un'impostazione personalizzata consente agli amministratori di adottare un controllo dichiarativo sul codice, pertanto uno dei molti casi d'uso è che, se utilizzati, possono rendere superfluo il deploy del codice per disabilitare i trigger (vedere Esempio di utilizzo delle impostazioni personalizzate della gerarchia per disattivare l'esempio di codice sopra ).
Un vantaggio chiave per gli sviluppatori è che i dati delle impostazioni personalizzate sono esposti nella cache dell'applicazione, che consente un accesso efficiente senza il costo delle query ripetute al database. Questi dati possono quindi essere utilizzati dai campi formula, dalle regole di convalida, dai flussi, dall'apice e dall'API SOAP: consultare la documentazione di Salesforce .
I limiti e le considerazioni per le impostazioni personalizzate sono documentati qui .
Elenca le impostazioni personalizzate
È anche possibile creare le Impostazioni personalizzate elenco, i casi d'uso comuni includono la memorizzazione di abbreviazioni di stato a due lettere, prefissi internazionali e numeri di catalogo per i prodotti. Tuttavia, Salesforce sta promuovendo l'uso dei tipi di metadati personalizzati, anziché le impostazioni personalizzate dell'elenco.
Quando si va a creare una nuova impostazione personalizzata, verrà visualizzato il seguente messaggio
Suggerimento: utilizzare i tipi di metadati personalizzati per la configurazione dell'app
Se stai pensando di utilizzare le impostazioni personalizzate dell'elenco, considera invece l'utilizzo di tipi di metadati personalizzati. A differenza delle impostazioni personalizzate dell'elenco, è possibile migrare i record dei tipi di metadati personalizzati utilizzando i pacchetti o gli strumenti dell'API dei metadati.
I tipi di metadati personalizzati offrono vantaggi aggiuntivi rispetto a Elenco impostazioni personalizzate come descritto in questa risposta . E secondo lo sviluppatore principale di CMD "C'è molto più in programma per i tipi di metadati personalizzati rispetto alle impostazioni personalizzate sugli steroidi".
Creazione e gestione delle impostazioni personalizzate
Creazione
Per creare un'impostazione personalizzata, vai a:
Classico
Configurazione> Sviluppo> Impostazioni personalizzate> Nuovo
fulmine
Impostazione> Codice personalizzato> Impostazioni personalizzate> Nuovo
Crea le tue impostazioni (consulta le Note più avanti in questo documento per le differenze tra le impostazioni personalizzate di Gerarchia e Elenco). È possibile ignorare l'elenco di selezione Visibilità, a meno che non si preveda di distribuire le impostazioni in un pacchetto gestito.
Per creare i tuoi campi di impostazione fai clic sul pulsante Nuovo e segui la normale procedura per la creazione di un campo personalizzato.
Gestione
Una volta creati i campi, puoi iniziare a configurare le impostazioni facendo clic sul pulsante Gestisci.
È più semplice gestire le impostazioni se crei una nuova vista e includi tutti i campi che hai creato per darti una panoramica completa delle impostazioni, a colpo d'occhio. Il proprietario dell'installazione è l'utente o il profilo a cui si applica l'impostazione.
Per gestire le impostazioni a livello di organizzazione, fai clic sul pulsante Nuovo sopra l'intestazione Valore livello organizzazione predefinita (nella casella rossa sotto).
Per gestire le impostazioni a livello di utente o profilo, fai clic sul pulsante Nuovo nella casella blu in basso.
Utilizzo delle impostazioni personalizzate della gerarchia per disabilitare le regole di flusso di lavoro / convalida
Impostazione personalizzata
Campo delle impostazioni personalizzate
Valore campo impostazione personalizzata
Quando il campo è selezionato, la regola di convalida sarà disabilitata, per l'utente corrente o in questo esempio, il loro profilo -
La regola può anche essere disabilitata per un'intera organizzazione Salesforce:
Regola di convalida
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()
)
Nella regola precedente, entrambi i criteri devono essere valutati su TRUE
affinché la regola venga attivata.
Poiché la casella di controllo All_Opportunity_Disabled__c
verrà valutata su TRUE
quando il profilo dell'utente in esecuzione è Amministratore di sistema, la regola verrà valutata su FALSE
.
Regole del flusso di lavoro
Lo stesso approccio può essere applicato per disattivare le regole del flusso di lavoro.
Utilizzo delle impostazioni personalizzate della gerarchia per disabilitare il codice apicale
Spiegazione
In questo esempio è stato creato un semplice Trigger per modificare la Data di chiusura di un'Opportunità, che sta per essere inserita o aggiornata, a una data di 10 giorni nel futuro.
Il campo Casella di controllo dell'impostazione personalizzata Apex consente di disabilitare il codice a livello di utente / profilo / organizzazione.
Apex Class
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 unitario
@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');
}
}
}
Aggiornamento delle impostazioni personalizzate della gerarchia in codice apicale
Potresti voler aggiornare le tue impostazioni personalizzate durante l'esecuzione del tuo codice, per disattivare le regole di convalida o del flusso di lavoro.
Nel codice seguente, ho creato una classe Apex programmabile che aggiornerà la data di chiusura di tutte le opportunità la cui data di chiusura è inferiore o uguale a 6 giorni dalla data corrente, modificando la data in 20 giorni in futuro.
Userò la mia impostazione personalizzata Val_Rule_Cntrlr__c per disattivare qualsiasi regola di convalida che mi impedisca di aggiornare le opportunità che soddisfano i miei criteri.
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;
}
}
}
Per assicurarmi che le mie regole di convalida vengano disattivate dalle modifiche alle mie impostazioni personalizzate nella mia classe, ho creato un campo Trigger_Validation_Rule__c
controllo Trigger_Validation_Rule__c
(che non sarebbe visibile agli utenti o aggiunto ai layout di pagina) e una regola di convalida con questo 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())
)
Quindi, quando creo le mie opportunità, il campo checkbox diventa true
modo che i criteri delle regole vengano soddisfatti, se il campo delle impostazioni personalizzate non è modificato dal mio codice.
@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);
}
}