更新 Apex 代码中的层次结构自定义设置
你可能希望在执行代码期间更新自定义设置,以关闭验证或工作流程规则。
在下面的代码中,我创建了一个可调度 Apex 类 ,它将更新其关闭日期小于或等于当前日期 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 = 'example@gmail.com',Username = 'sotest@gmail.com',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 = 'sotest@gmail.com'];
// 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);
}
}