トリガ、プロセス、入力規則の実行制御

トリガやプロセス、入力規則など、DML操作で自動的にトリガされる機能は、実運用の中で一時的に無効化したいことがちょいちょいあります。
トリガ以外は、普通に無効化できるのですが、トリガに関してはわざわざ無効化したトリガのリリースが必要なので、だるいです。
また、テストクラスを、それらが動く前提で組んでいると、それらの改修が必要になったときに、テストクラスが軒並みエラーになってイラついたりします。

そんな時、階層型のカスタム設定でそれぞれon/offできるようにつくっておくと、結構便利です。

こんな感じのカスタム設定を用意しておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126858/eaa3b74e-8f22-2f3a-7307-4066fd8af229.png)
実際には、もっと細かく(せめて、オブジェクトごとぐらい?)にフラグを用意しとくのが良いかなと思います。

レコードの登録は、組織のデフォルト値だけセットしとけばとりあえずは十分かなと思いますが、特定のプロファイル/ユーザにだけ別途設定して、システム管理者のみ実行を回避するなんてこともできます。
データ補正が必要になった場合なんかに、補正を行うユーザでだけ止まるようにすれば、ほかのユーザの運用止めなくていいので、結構便利な気がします。
(もちろん、更新するデータが被るといけないので、そこは注意が必要ですが。)

###トリガでの利用
トリガで利用する場合は、とりあえず`getinstance()`しておけば、良い感じでとってきてくれるみたい。

```java
ExecutionController__c ec = ExecutionController__c.getInstance()
```

一応、カスタム設定メソッドの動きの違いも検証してみた。

```java
Savepoint sp = Database.setSavepoint();

System.assertEquals(null, (Sample__c.getOrgDefaults() == null ? null : Sample__c.getOrgDefaults().Text__c));
System.assertEquals(null, (Sample__c.getInstance()== null ? null : Sample__c.getInstance().Text__c));
System.assertEquals(null, (Sample__c.getInstance(UserInfo.getProfileId())== null ? null : Sample__c.getInstance(UserInfo.getProfileId()).Text__c));
System.assertEquals(null, (Sample__c.getValues(UserInfo.getProfileId())== null ? null : Sample__c.getValues(UserInfo.getProfileId()).Text__c));
System.assertEquals(null, (Sample__c.getInstance(UserInfo.getUserId())== null ? null : Sample__c.getInstance(UserInfo.getUserId()).Text__c));
System.assertEquals(null, (Sample__c.getValues(UserInfo.getUserId())== null ? null : Sample__c.getValues(UserInfo.getUserId()).Text__c));

Sample__c orgDefault = new Sample__c(Text__c　=　'orgDefault');

insert orgDefault;

System.assertEquals('orgDefault', (Sample__c.getOrgDefaults() == null ? null : Sample__c.getOrgDefaults().Text__c));
System.assertEquals('orgDefault', (Sample__c.getInstance()== null ? null : Sample__c.getInstance().Text__c));
System.assertEquals('orgDefault', (Sample__c.getInstance(UserInfo.getProfileId())== null ? null : Sample__c.getInstance(UserInfo.getProfileId()).Text__c));
System.assertEquals(null, (Sample__c.getValues(UserInfo.getProfileId())== null ? null : Sample__c.getValues(UserInfo.getProfileId()).Text__c));
System.assertEquals('orgDefault', (Sample__c.getInstance(UserInfo.getUserId())== null ? null : Sample__c.getInstance(UserInfo.getUserId()).Text__c));
System.assertEquals(null, (Sample__c.getValues(UserInfo.getUserId())== null ? null : Sample__c.getValues(UserInfo.getUserId()).Text__c));

Sample__c profileDefault = Sample__c.getInstance(UserInfo.getProfileId());
profileDefault.Text__c = 'profileDefault';
insert profileDefault;

System.assertEquals('orgDefault', (Sample__c.getOrgDefaults() == null ? null : Sample__c.getOrgDefaults().Text__c));
System.assertEquals('profileDefault', (Sample__c.getInstance()== null ? null : Sample__c.getInstance().Text__c));
System.assertEquals('profileDefault', (Sample__c.getInstance(UserInfo.getProfileId())== null ? null : Sample__c.getInstance(UserInfo.getProfileId()).Text__c));
System.assertEquals('profileDefault', (Sample__c.getValues(UserInfo.getProfileId())== null ? null : Sample__c.getValues(UserInfo.getProfileId()).Text__c));
System.assertEquals('profileDefault', (Sample__c.getInstance(UserInfo.getUserId())== null ? null : Sample__c.getInstance(UserInfo.getUserId()).Text__c));
System.assertEquals(null, (Sample__c.getValues(UserInfo.getUserId())== null ? null : Sample__c.getValues(UserInfo.getUserId()).Text__c));

Sample__c userDefault = Sample__c.getInstance(UserInfo.getUserId());
userDefault.Text__c = 'userDefault';
insert userDefault;

System.assertEquals('orgDefault', (Sample__c.getOrgDefaults() == null ? null : Sample__c.getOrgDefaults().Text__c));
System.assertEquals('userDefault', (Sample__c.getInstance()== null ? null : Sample__c.getInstance().Text__c));
System.assertEquals('profileDefault', (Sample__c.getInstance(UserInfo.getProfileId())== null ? null : Sample__c.getInstance(UserInfo.getProfileId()).Text__c));
System.assertEquals('profileDefault', (Sample__c.getValues(UserInfo.getProfileId())== null ? null : Sample__c.getValues(UserInfo.getProfileId()).Text__c));
System.assertEquals('userDefault', (Sample__c.getInstance(UserInfo.getUserId())== null ? null : Sample__c.getInstance(UserInfo.getUserId()).Text__c));
System.assertEquals('userDefault', (Sample__c.getValues(UserInfo.getUserId())== null ? null : Sample__c.getValues(UserInfo.getUserId()).Text__c));

atabase.rollback(sp);
```


###テストクラスでの利用
テストクラスでは、まずレコード自体を登録する必要がありますが、普通のレコードと同じノリでinsertすると、組織のデフォルトとして設定されるようなので、基本的にはそれで十分かな。
いちおう、細かいテストのために、プロファイル/ユーザレベルでの設定を作る場合には、以下のような感じになります。

```java
ExecutionController__c ec = ExecutionController__c.getInstance(profileIdOrUserId);
ec.IsExecute__c= true;
insert ec;
```

###プロセスでの設定
$setup.<カスタム設定名>.<項目名>で参照できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126858/5194e581-7036-0441-af68-40edcf4bb513.png)
普通に「レコードが更新されたとき」に動くプロセスで、条件の分岐だけさせて、trueの場合に実際に実行したい処理を記述した、「別のプロセスから呼び出されたとき」に動くプロセスを設定するといいんじゃないかなと思います。

##入力規則での設定
参照の仕方は、プロセスと一緒です。
すべての入力規則で、本来設定したいチェック内容にプラスして、
```$Setup.ExecutionController__c.IsExecute__c && (実際のチェック)```
みたいな感じで設定すればよいかと思います。