【フロー】任意の項目を特定の値に変更するときのみ画面フローから更新することを強制する

Salesforceで任意の項目を特定の値に変更するときのみ、画面フローから更新することを強制するような仕組みを考えてみます。

## 考える具体例
商談のフェーズを"Closed Won"へ変更するときのみ、画面フローから更新することを強制します。

:::note warn
ユーザが標準的にフェーズ項目を更新可能な方法として

- レコードページ
- リストビュー
- レポート
- API経由（データローダなど）

が存在することを考慮する必要があります。
:::

## 実装方法
### フェーズを成立へ変更するときのみ発火する入力規則を作成
「任意の値へ変更するときのみ」に関しては、

- 現在の値が"任意の値"に一致する かつ 項目の値が変更された
- 現在の値が"任意の値"に一致する かつ 過去の値が"任意の値"に一致しない

という2種類の考え方があります。
今回のケースでは前者を採用し、
```
AND(
  ISPICKVAL( StageName , "Closed Won" ) ,
  ISCHANGED( StageName )
)
```
として、任意のルール名とエラーメッセージを設定します。

:::note info
後者を適用すると、
```
AND(
  ISPICKVAL( StageName , "Closed Won" ) ,
  NOT( ISPICKVAL( PRIORVALUE( StageName ) , "Closed Won" ) )
)
```
となります。
:::

### 入力規則の動作確認
任意の商談でフェーズを"Closed Won"へ変更し、入力規則で設定したエラーメッセージが表示されることを確認します。

:::note info
画面状態の参考

<img width="1000" alt="入力規則のチェック" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/f5e8dfec-62de-231e-a2e7-b45edd5fae32.gif">
:::

### 入力規則を回避するためのチェックボックス項目を作成
上記で作成した入力規則では、すべての更新方法においてフェーズが"Closed Won"へ変更されたときに入力規則が発火してしまうため、チェックボックス項目を用いて入力規則の発火を回避できるようにします。
今回は商談へ下記のチェックボックス項目を作成します。

| プロパティ | 設定値 |
| :--: | :--: |
| 項目の表示ラベル | 成立更新時の入力規則を回避 |
| デフォルト値 | チェックなし |
| 項目名 | AvoidValidationForUpdateClosedWon |
| 項目レベルセキュリティ | システム管理者のみ参照可能 |
| ページレイアウト | 全てのチェックを外す |

:::note warn
項目レベルセキュリティで"参照可能"を設定すると、リストビュー等のユーザが任意の項目を表示・編集することが可能な機能から更新が可能になってしまいます。
:::

追加したチェックボックス項目を用いて入力規則の数式を下記のように変更します。
```
AND(
  NOT( AvoidValidationForUpdateClosedWon__c ) ,
  ISPICKVAL( StageName , "Closed Won" ) ,
  ISCHANGED( StageName )
)
```
このように変更することで、追加したチェックボックス項目が`TRUE`となるときに入力規則が発火しないように調整することができます。

### 画面フローを作成
下記の手順でフェーズを更新する画面フローを作成します。

#### 1. 入力リソースの作成
ツールボックスから下記のように新規リソースを作成します。

![Flow_Force_ScreenFlow_for_Update_入力変数_recordId.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/95528a8b-6fff-bbdf-f354-66ef94ad91b0.png)

:::note info
画面フローにおいて、入力で使用可能な変数のAPI参照名を「recordId」としておくと、クイックアクションへ画面フローを設定した際にアクションを起動したレコードの情報を画面フローへ与えることができます。
このとき、

- 変数のデータ型をテキストとした場合 = 入力される情報はレコードID
- 変数のデータ型をレコードとした場合 = 入力される情報はレコード

となります。
:::

#### 2. レコードの更新要素で入力規則を回避しながらフェーズを更新
開始要素の直下にレコードの更新要素を配置し、下記のように設定します。

![Flow_Force_ScreenFlow_for_Update_レコード更新.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/8dbdf59d-f1b6-3f91-bc97-11f6c87ea8c4.png)

#### 3. レコードの更新要素でフラグを更新
上記で配置したレコードの更新要素の直下に再びレコードの更新要素を配置し、下記のように設定します。

![Flow_Force_ScreenFlow_for_Update_チェック更新.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/d4a81ef7-e3d4-1398-b1d5-f9a7bbeab505.png)

#### 4. 画面フローを保存
下記のように設定を行い、フローを保存します。

![Flow_Force_ScreenFlow_for_Update_フロー保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/c8b11c9e-748e-e58e-60f4-ab5889a3a2f8.png)

:::note warn
フローの実行方法を「システムコンテキスト」に設定しなければ、チェックボックス項目の項目レベルセキュリティでエラーが発生します。
また、「共有あり」に設定しなければ、レコードレベルで編集権のないユーザも画面フローで更新できてしまいます。
:::

### クイックアクションの作成と配置
画面フローが作成できたので、商談のクイックアクションを下記のように作成し、「ページレイアウトのSalesforce モバイルおよび Lightning Experience のアクション」または「レコードページの動的アクション」へ配置します。

![Flow_Force_ScreenFlow_for_Update_アクション作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/2f68148b-c648-bbac-2366-3e22b88dba07.png)

### 動作確認
任意の商談で設定したアクションを実行します。（変更の適用には画面の更新が必要です）

:::note info
画面状態の参考

<img width="1000" alt="アクションのチェック" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/b8676a9c-63d9-60d6-9f09-b078528eaf91.gif">
:::

## 簡単な実装は完了
表題に関連する実装方法に関しては以上ですが、上記を実際の実務で使用する場合は権限に注意が必要になります。
フローの実行方法を「システムコンテキストの共有あり」に設定しているため、権限については問題ないように思えますが、「オブジェクト権限」の考慮ができていません。
つまり、商談の編集権がないユーザが画面フローを実行すると編集できてしまいますのでご注意ください。

追々、オブジェクト権限のチェックを行うフローの構築方法を紹介できればと思います。

## 追記
オブジェクト権限のチェックを行えるフローの構築方法をまとめました。

https://qiita.com/HNakazawa/items/535e59ce1b9556e85dc4