Salesforce
Anpassade inställningar
Sök…
Anmärkningar
Introduktion
Till skillnad från anpassade objekt som har poster baserade på dem, kan anpassade inställningar använda egna datauppsättningar över hela organisationen eller skilja särskilda användare eller profiler utifrån anpassade kriterier. Detta innebär till exempel att administratörer kan redigera anpassade hierarkiinställningar för att inaktivera arbetsflödes- / valideringsregler för enskilda användare eller profiler, utan att behöva stänga av dem för hela organisationen (se Använda hierarki anpassade inställningar för att inaktivera exempel på arbetsflöde / valideringsregler ovan) ).
Valideringsregler måste vanligtvis inaktiveras tillfälligt när:
- Koden uppdaterar gamla poster som senast redigerades innan en valideringsregel aktiverades och uppfyller därför inte den nyare regelens kriterier.
- Koden sätter in nya poster utan de värden som krävs enligt en valideringsregelkriterier.
Regler för arbetsflöden måste vanligtvis inaktiveras tillfälligt när:
- De skulle utlösa en e-postvarning eller fältuppdatering som skulle skriva över eller störa de ändringar du gör i posten.
Användning av en anpassad inställning ger en viss deklarativ kontroll över koden, så ett av de många användningsfallen är att när de används kan de göra det onödigt att distribuera kod för att inaktivera triggers (se Använda hierarki anpassade inställningar för att inaktivera Apex-koden exemplet ovan ).
En viktig fördel för utvecklarna är att data för anpassad inställning exponeras i applikationscachen, vilket möjliggör effektiv åtkomst utan kostnaden för upprepade frågor till databasen. Dessa data kan sedan användas av formelfält, valideringsregler, flöden, Apex och SOAP API - se Salesforce-dokumentationen .
Gränser och överväganden för anpassade inställningar dokumenteras här .
Lista anpassade inställningar
Det är möjligt att skapa listan anpassade inställningar också, fall för vanligt bruk inkluderar lagring av förkortningar med två bokstäver, internationella uppringningsprefix och katalognummer för produkter. Men Salesforce marknadsför nu användningen av anpassade metadatatyper i stället för listan anpassade inställningar.
När du går till en ny anpassad inställning visas följande meddelande
Tips: Använd anpassade metadatatyper för appkonfiguration
Om du funderar på att använda listan anpassade inställningar kan du överväga att använda anpassade metadatatyper istället. Till skillnad från listan anpassade inställningar kan du migrera posterna för anpassade metadatatyper med hjälp av paket eller Metadata API-verktyg.
Anpassade metadatatyper har ytterligare fördelar kontra Lista anpassade inställningar som beskrivs i det här svaret . Och enligt ledande utvecklare av CMD: er "Det finns mycket mer planerat för anpassade metadatatyper än anpassade inställningar på steroider."
Skapa och hantera anpassade inställningar
Skapande
För att skapa en anpassad inställning, gå till:
Klassisk
Inställning> Utveckla> Anpassade inställningar> Nytt
Blixt
Inställning> Anpassad kod> Anpassade inställningar> Ny
Skapa din inställning (se anmärkningarna senare i det här dokumentet för skillnader mellan anpassade inställningar för hierarki och lista). Du kan ignorera Visibility picklisten, såvida du inte planerar att distribuera din inställning i ett hanterat paket.
För att skapa dina inställningsfält klickar du på knappen Ny och följer den vanliga processen för att skapa ett anpassat fält.
Förvaltning
När du har skapat dina fält / fält kan du börja konfigurera inställningen genom att klicka på Hantera-knappen.
Det är lättare att hantera inställningen om du skapar en ny vy och inkluderar alla fält som du har skapat för att ge dig själv en omfattande överblick över inställningen, på ett ögonkast. Setup-ägaren är användaren eller profilen som inställningen gäller.
För att hantera inställningen på org-nivå klickar du på Ny-knappen ovanför rubriken Standardvärdesnivåvärde (i röd ruta nedan).
Om du vill hantera inställningen på användar- eller profilnivå klickar du på knappen Ny i den blå rutan nedan.
Använda hierarkiska anpassade inställningar för att inaktivera arbetsflödes- / valideringsregler
Anpassad inställning
Anpassat inställningsfält
Anpassat inställningsfältvärde
När fältet är markerat kommer valideringsregeln att inaktiveras, för den löpande användaren eller i detta exempel, deras profil -
Regeln kan också inaktiveras för en hel Salesforce-organisation -
Valideringsregeln
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()
)
I ovanstående regel måste båda kriterierna utvärderas till TRUE
för att regeln ska utlösas.
Eftersom kryssrutan All_Opportunity_Disabled__c
utvärderas till TRUE
när den löpande användarprofilen är systemadministratör, kommer regeln att utvärderas till FALSE
.
Regler för arbetsflöde
Samma tillvägagångssätt kan tillämpas för att inaktivera arbetsflödesregler.
Använda hierarkiska anpassade inställningar för att inaktivera Apex-kod
Förklaring
I det här exemplet har en enkel triggare skapats för att ändra stängningsdatum för en möjlighet, som är på väg att infogas eller uppdateras, till ett datum 10 dagar i framtiden.
I Apex Controller-anpassningsinställningens kryssrutefält kan koden inaktiveras på användar- / profil / org-nivå.
Apex klass
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);
}
}
}
Enhetstest
@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');
}
}
}
Uppdatera anpassade hierarkiinställningar i Apex-kod
Du kanske vill uppdatera dina anpassade inställningar under körningen av din kod, för att stänga av validering eller arbetsflödesregler.
I koden nedan har jag skapat en schemalagd Apex-klass som kommer att uppdatera stängningsdatumet för alla möjligheter vars stängningsdatum är mindre än eller lika med 6 dagar från det aktuella datumet och ändrar datumet till 20 dagar i framtiden.
Jag kommer att använda min anpassade inställning Val_Rule_Cntrlr__c för att inaktivera valideringsregler som hindrar mig från att uppdatera möjligheterna som uppfyller mina kriterier.
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;
}
}
}
För att säkerställa att min valideringsregler inaktiveras av ändringarna i min anpassade inställning i min klass har jag skapat ett kryssrutefält Trigger_Validation_Rule__c
(som inte skulle kunna synas för användare eller läggas till sidlayouter) och en valideringsregel med dessa kriterier:
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())
)
Jag ställer sedan in kryssrutefältet till true
när jag skapar mina möjligheter så att kriterierna för regler skulle uppfyllas, om det anpassade inställningsfältet inte redigeras av min 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);
}
}