Salesforce 承認プロセス:効率的なワークフロー自動化のためのアーキテクチャ

Salesforce プロフェッショナル(今回は Salesforce コンサルタント)として、私はビジネスプロセスの効率化と統制強化に日々取り組んでいます。その中でも、承認プロセス (Approval Process) は、Salesforce が提供する最も強力で頻繁に活用される宣言的自動化ツールの一つです。本記事では、承認プロセスの技術的な深掘りと、ビジネスへの応用、そしてそのベストプラクティスについて詳細に解説します。

概要とビジネスシーン

Salesforce 承認プロセスは、レコードの保存または変更に基づいて、特定の条件を満たす場合に、定義されたステップと承認者による承認フローを自動的に適用し、ビジネスプロセスの統制、効率化、コンプライアンス遵守を担保するコア機能です。これにより、手作業による承認漏れや遅延を防ぎ、監査可能な履歴を提供します。

実際のビジネスシーン

シーンA:金融業界 - 融資申請承認
ある銀行では、顧客からの融資申請が手作業で審査されており、承認プロセスに数日を要していました。さらに、複数担当者による承認が必要な場合、進捗状況の把握が困難で、コンプライアンスリスクも存在しました。
ソリューション:Salesforce の承認プロセスを導入し、融資額とリスクレベルに応じた多段階承認フローを自動化しました。申請がシステムに登録されると自動的に承認プロセスが開始され、担当役員から最終決裁者まで電子的に回付されます。承認状況はリアルタイムで可視化され、承認履歴は自動的に記録されます。
定量的効果:融資承認リードタイムを平均50%短縮し、手作業によるエラー率を90%削減しました。コンプライアンス監査対応の時間も大幅に短縮され、顧客満足度が向上しました。

シーンB:製造業 - 見積書承認
大規模な製造業では、複雑な製品構成や特殊な割引が適用される見積書の作成において、営業担当者、製品マネージャー、財務担当者など複数部門の承認が必要でした。承認経路が複雑で、メールベースのやり取りでは承認漏れや遅延が頻繁に発生し、見積もり提出が遅れることで商機を逃すことがありました。
ソリューション:Salesforce Opportunity オブジェクトに見積書承認プロセスを設定しました。金額、割引率、製品カテゴリなどの条件に基づいて、必要な承認者を動的に決定し、並列承認や直列承認を組み合わせたフローを構築。承認・却下時には自動的にステータス更新やメール通知が行われるようにしました。
定量的効果:見積もり発行リードタイムを30%短縮し、承認漏れをほぼゼロにすることで、営業効率が向上し、受注率にも貢献しました。

シーンC:製薬業界 - 臨床試験変更承認
製薬企業では、進行中の臨床試験計画に対する変更は、厳格な規制要件に従い、多数の専門家や規制当局の承認を必要とします。手作業による文書回覧や署名プロセスは時間がかかり、変更の追跡や監査証跡の確保が非常に困難でした。
ソリューション:Salesforce Custom Object で「臨床試験変更要求」を作成し、承認プロセスを導入しました。このプロセスは、変更の性質(軽微な変更、重大な変更など)に基づいて、必要な承認者グループ(医学専門家、統計学者、品質保証担当者)に自動的に依頼を送ります。すべての承認ステップとコメントは詳細な監査証跡として保存されます。
定量的効果:変更申請の処理時間を平均20%短縮し、規制遵守のための監査対応時間を大幅に削減しました。これにより、新たな臨床試験の開始や医薬品承認申請プロセスが加速されました。


技術原理とアーキテクチャ

Salesforce 承認プロセスは、特定のオブジェクトのレコードに対して、事前に定義されたルールに従って複数のユーザーが承認または却下を行うためのメカニズムです。レコードが承認プロセスのエントリー条件 (Entry Criteria) を満たすとプロセスが開始され、承認者に対して承認依頼が送られます。

主要コンポーネントと依存関係

  • 承認プロセス (Approval Process): 全体的なフロー設定。どのオブジェクトに適用するか、開始条件、承認ステップ、アクションなどを定義します。
  • エントリー条件 (Entry Criteria): 承認プロセスが開始されるための条件。フィールドの値や複雑な数式に基づいて定義されます。
  • 承認ステップ (Approval Steps): 承認プロセスの各段階。各ステップには、そのステップに進むための条件(任意)、割り当てる承認者、承認タイプ(最初の承認者、全員など)、および承認/却下時のアクションが設定されます。
  • 承認者 (Approver): 承認依頼を受け取るユーザーまたはグループ。ユーザー、キュー、関連ユーザー(例:レコード所有者のマネージャー)、階層項目(例:ユーザーのカスタム階層フィールド)などから選択できます。
  • 初期提出アクション (Initial Submission Actions): レコードが承認プロセスに提出された直後に実行されるアクション。
  • 承認アクション (Approval Actions): 各ステップでレコードが承認されたときに実行されるアクション。
  • 却下アクション (Rejection Actions): 各ステップでレコードが却下されたときに実行されるアクション。
  • 最終承認アクション (Final Approval Actions): プロセス全体が最終的に承認されたときに実行されるアクション。
  • 最終却下アクション (Final Rejection Actions): プロセス全体が最終的に却下されたときに実行されるアクション。
  • 取り消しアクション (Recall Actions): 承認依頼が取り消されたときに実行されるアクション。
  • ロック (Record Lock): 承認プロセス中にレコードをロックし、承認者以外のユーザーによる編集を防ぐ機能。

データフロー

ステップ 説明 関連コンポーネント
1. レコード作成/更新 ユーザーが対象オブジェクトのレコードを作成または更新します。 対象オブジェクト
2. エントリー条件評価 レコードが承認プロセスのエントリー条件 (Entry Criteria) を満たすかシステムが確認します。 Approval Process (Entry Criteria)
3. プロセス開始 条件を満たした場合、承認プロセスが開始され、初期提出アクション (Initial Submission Actions) が実行されます。レコードはロックされる場合があります。 Approval Process (Initial Submission Actions, Record Lock)
4. 承認ステップ実行 現在の承認ステップの承認者 (Approver) に承認依頼が送信されます(メール通知、ベル通知など)。 Approval Step (Assigned Approver)
5. 承認/却下 承認者が依頼されたレコードを承認または却下します。 承認者 (Approver)
6. アクション実行 承認・却下に応じて、定義された承認アクション (Approval Actions) または却下アクション (Rejection Actions) が実行されます。 Approval Step (Actions)
7. 次のステップへ/プロセス終了 承認された場合、次の承認ステップに進むか、すべてのステップが完了すれば最終承認アクション (Final Approval Actions) が実行され、プロセスが完了します。却下された場合は、最終却下アクション (Final Rejection Actions) が実行され、プロセスが終了します。 Final Approval Actions, Final Rejection Actions

ソリューション比較と選定

Salesforce で承認プロセスを実現する方法はいくつかあります。それぞれのソリューションにはメリット・デメリットがあり、適切な選択が重要です。

ソリューション 適用シーン パフォーマンス Governor Limits 複雑度
Approval Process (標準) 標準的な多段階承認(直列/並列)、承認履歴の自動管理、コンプライアンス要件、管理者がコードなしで設定したい場合。 中 (標準機能として最適化済み) DMLやSOQLの直接的な制限を受けにくいが、内部アクション(Field Updateなど)が間接的に影響する可能性あり。 低〜中 (宣言的)
Flow (承認アクション) 非常に動的な承認者決定ロジック、カスタム承認UIの構築、承認プロセスと連携する複雑な自動化(例: 外部システム連携、関連レコードの大量更新)が必要な場合。 高 (フローエンジンは高速) フローのGovernor Limitsに従う (例: 2000要素、50000 DML行、100 SOQLクエリ)。複雑なフローでは考慮が必要。 中〜高 (宣言的だがロジックは複雑に)
Custom Apex (カスタム承認) Approval Process や Flow では実現できない非常に特殊な要件、大量のレコードに対するプログラムによる承認(例: バッチ承認)、外部システムとのリアルタイムかつ複雑な連携。 高 (開発の自由度が高い) Apex の Governor Limits に厳しく影響 (例: 150 DML、100 SOQL、10秒 CPUタイム)。Bulkify(一括処理)の設計が必須。 高 (プログラミング)

Approval Process を使用すべき場合

  • ✅ 標準的な承認フロー(直列・並列)でビジネス要件が十分に満たされる場合。
  • ✅ 承認履歴と監査証跡を自動で管理したい場合。
  • ✅ 管理者がコードを書かずに設定・メンテナンスを行いたい場合。
  • ✅ 承認者がユーザー、キュー、またはレコード所有者のマネージャーといった階層フィールドで決定できる場合。
  • ❌ 承認者を非常に動的に(例: 複雑な計算結果に基づき、毎回異なるロジックで)決定する必要がある場合。
  • ❌ 承認ユーザーインターフェース (UI) を完全にカスタマイズしたい場合。
  • ❌ 承認アクションとして、Flow や Apex などのより複雑な自動化を直接トリガーしたい場合(ただし、Approval Process のアクションから Flow を呼び出すことは可能)。

実装例

Salesforce の承認プロセスは主に宣言的な設定で行われますが、その構造を理解するためには Metadata API で取得できる XML 定義が非常に役立ちます。以下は、Opportunity オブジェクトに対するシンプルな承認プロセスのメタデータ定義例です。

この例では、Opportunity の AmountStageName に基づいて、まずマネージャー、次いで CFO (キュー) による承認を行う二段階のプロセスを定義しています。最終承認・却下時には Opportunity のカスタムフィールド IsApproved__c を更新します。

<?xml version="1.0" encoding="UTF-8"?>
<ApprovalProcess xmlns="http://soap.sforce.com/2006/04/metadata">
    <active>true</active> <!-- 承認プロセスが有効かどうか -->
    <allowRecall>true</allowRecall> <!-- 提出者が承認依頼を取り消せるかどうか -->
    <apiVersion>59.0</apiVersion> <!-- 使用する API バージョン -->
    <approvalPageFields> <!-- 承認ページに表示する Opportunity のフィールド -->
        <field>Name</field>
        <field>Amount</field>
        <field>StageName</field>
    </approvalPageFields>
    <approvalRequestEmailTemplate>unfiled$public/Salesforce_Default_Approval_Request_Email</approvalRequestEmailTemplate> <!-- 承認依頼メールテンプレート -->
    <approvalSteps> <!-- 承認ステップの定義 -->
        <approvalStep>
            <allowDelegate>true</allowDelegate> <!-- 承認者が承認を委任できるか -->
            <assignedApprover> <!-- 承認者の割り当て -->
                <approver>
                    <name>Manager</name> <!-- 階層項目 (ここではレコード所有者のマネージャー) -->
                    <type>UserHierarchyField</type>
                </approver>
                <whenMultipleApprovers>FirstResponse</whenMultipleApprovers> <!-- 複数の承認者がいる場合の承認タイプ (FirstResponse = 最初の承認で完了) -->
            </assignedApprover>
            <entryCriteria> <!-- このステップに進むための条件 (Opportunity.Amount > 100000 かつ StageName が Proposal/Price Quote) -->
                <booleanFilter>1 AND 2</booleanFilter>
                <criteriaItems>
                    <field>Opportunity.Amount</field>
                    <operation>greaterThan</operation>
                    <value>100000</value>
                </criteriaItems>
                <criteriaItems>
                    <field>Opportunity.StageName</field>
                    <operation>equals</operation>
                    <value>Proposal/Price Quote</value>
                </criteriaItems>
            </entryCriteria>
            <label>Manager Approval</label> <!-- ステップの表示名 -->
            <name>Manager_Approval</name> <!-- ステップのAPI参照名 -->
            <rejectBehavior> <!-- 却下時の動作 (却下リクエスト) -->
                <type>RejectRequest</type>
            </rejectBehavior>
        </approvalStep>
        <approvalStep>
            <allowDelegate>true</allowDelegate>
            <assignedApprover>
                <approver>
                    <name>CFO_Queue</name> <!-- キューを承認者として割り当て -->
                    <type>Queue</type>
                </approver>
                <whenMultipleApprovers>FirstResponse</whenMultipleApprovers>
            </assignedApprover>
            <entryCriteria> <!-- このステップに進むための条件 (Opportunity.Amount > 500000) -->
                <booleanFilter>1</booleanFilter>
                <criteriaItems>
                    <field>Opportunity.Amount</field>
                    <operation>greaterThan</operation>
                    <value>500000</value>
                </criteriaItems>
            </entryCriteria>
            <label>CFO Approval</label>
            <name>CFO_Approval</name>
            <rejectBehavior>
                <type>RejectRequest</type>
            </rejectBehavior>
            <previousApprovalStep>Manager_Approval</previousApprovalStep> <!-- 前のステップ (Manager Approval の後) -->
        </approvalStep>
    </approvalSteps>
    <enableMobileDeviceAccess>true</enableMobileDeviceAccess> <!-- モバイルデバイスからのアクセスを許可 -->
    <entryCriteria> <!-- 承認プロセス全体を開始するための条件 (Opportunity.IsApproved__c が false かつ StageName が Proposal/Price Quote) -->
        <booleanFilter>1 AND 2</booleanFilter>
        <criteriaItems>
            <field>Opportunity.IsApproved__c</field>
            <operation>equals</operation>
            <value>false</value>
        </criteriaItems>
        <criteriaItems>
            <field>Opportunity.StageName</field>
            <operation>equals</operation>
            <value>Proposal/Price Quote</value>
        </criteriaItems>
    </entryCriteria>
    <finalApprovalActions> <!-- 最終承認時のアクション (Opportunity の IsApproved__c を true に更新) -->
        <actionType>FieldUpdate</actionType>
        <name>Update_Opportunity_Status_Approved</name>
        <type>WorkflowFieldUpdate</type>
    </finalApprovalActions>
    <finalApprovalRecordLock>true</finalApprovalRecordLock> <!-- 最終承認時にレコードをロック -->
    <finalRejectionActions> <!-- 最終却下時のアクション (Opportunity の IsApproved__c を false に更新) -->
        <actionType>FieldUpdate</actionType>
        <name>Update_Opportunity_Status_Rejected</name>
        <type>WorkflowFieldUpdate</type>
    </finalRejectionActions>
    <finalRejectionRecordLock>false</finalRejectionRecordLock> <!-- 最終却下時にレコードのロックを解除 -->
    <label>Opportunity Approval Process</label> <!-- プロセスの表示名 -->
    <processOrder>1</processOrder> <!-- 複数の承認プロセスがある場合の実行順序 -->
    <recallActions> <!-- 取り消し時のアクション -->
        <actionType>FieldUpdate</actionType>
        <name>Update_Opportunity_Status_Recalled</name>
        <type>WorkflowFieldUpdate</type>
    </recallActions>
    <recordEditability>AdminOrCurrentApprover</recordEditability> <!-- 承認中のレコード編集権限 (管理者または現在の承認者のみ) -->
    <showApprovalHistory>true</showApprovalHistory> <!-- 承認履歴を表示するか -->
</ApprovalProcess>

実装ロジック解析:

  • この XML は、機会 (Opportunity) オブジェクトに適用される承認プロセスを定義しています。
  • <entryCriteria> タグは、この承認プロセスが開始されるための全体的な条件を指定します。ここでは、IsApproved__c フィールドが false で、StageNameProposal/Price Quote であることが求められます。
  • <approvalSteps> 内で二つのステップが定義されています。
    • 最初のステップ Manager_Approval は、Amount が 100,000 ドル以上で、StageNameProposal/Price Quote の場合にトリガーされます。承認者は、レコード所有者のマネージャー (UserHierarchyField) です。
    • 二番目のステップ CFO_Approval は、Manager_Approval の後に続き、Amount が 500,000 ドル以上の場合にトリガーされます。承認者は CFO_Queue というキューに割り当てられます。
  • <finalApprovalActions><finalRejectionActions> は、それぞれ最終承認時と最終却下時に実行されるアクションを定義しています。ここでは、Opportunity のカスタムフィールド IsApproved__c を更新するフィールド更新アクションが設定されています。
  • <finalApprovalRecordLock> は最終承認時にレコードをロックするか、<finalRejectionRecordLock> は最終却下時にレコードのロックを解除するかを設定します。
  • <recordEditability> は、承認プロセス中にレコードを編集できるユーザーを制御します。ここでは「管理者または現在の承認者のみ」と設定されています。

注意事項とベストプラクティス

権限要件

承認プロセスを適切に利用するには、関連するユーザーに適切な権限が付与されている必要があります。

  • レコードの作成/編集: 承認プロセスを開始するレコードに対するオブジェクトの「作成」および「編集」権限。
  • 承認依頼の提出: プロファイルの「承認プロセスを提出」権限、または「レコードを編集」権限。
  • 承認/却下: 「承認承認を承認」または「すべての承認承認を変更」という権限(標準プロファイルには通常含まれるが、カスタムプロファイルでは明示的な付与が必要)が必要です。承認者は、承認するレコードに対する「参照」権限も必要です。
  • 承認履歴の参照: 「すべてのデータ参照」権限、またはオブジェクトに対する「参照」権限。
  • 委任: 承認を委任されるユーザーには、「承認承認を承認」権限が必要です。

Governor Limits

承認プロセス自体が直接的に Salesforce の厳しい Governor Limits に抵触することは稀ですが、承認アクションとして実行されるワークフローアクション、フロー、または Apex コードはこれらの制限の影響を受けます。

  • DML ステートメント: 1回のトランザクションで実行できる DML 操作は最大 150 回
  • SOQL クエリ: 1回のトランザクションで実行できる SOQL クエリは最大 100 回
  • CPU タイム: 同期 Apex コードの実行時間は最大 10 秒
  • 非同期 Apex 呼び出し: 1日あたり最大 250,000 回の非同期 Apex メソッド(Queueable, Batch, Future, Scheduled Apex)を実行できます。これは、承認プロセスからフローや Apex を呼び出し、その中で非同期処理を行う場合に考慮すべき制限です。

特に、大量のレコードに対して承認プロセスが同時に実行され、それぞれのアクションが複雑なフローや Apex をトリガーする場合、これらの制限に注意し、バルク対応(Bulkify)されたコード設計を心がける必要があります。

エラー処理

承認プロセスで発生しうる一般的なエラーとその解決策:

  • 「レコードは現在ロックされているため、変更できません。」: 承認プロセス中にレコードがロックされている場合に発生します。プロセス設定の「レコードの編集可能性 (Record Editability)」を確認し、必要に応じて設定を変更するか、最終却下アクションでレコードのロックを解除するように設定します。
  • 「承認者がいません。」: 承認ステップに割り当てられた承認者が存在しない、または無効なユーザーである場合に発生します。承認ステップの承認者設定、関連するキュー、または階層フィールドの値を確認してください。
  • 「ワークフローアクションが失敗しました。」: 承認プロセス内のフィールド更新やフロー呼び出しなどのアクションが何らかの理由で失敗した場合。デバッグログを有効にし、失敗したアクションの詳細を調査してください。

パフォーマンス最適化

  • シンプルさを追求する: 必要最小限の承認ステップと条件に留め、不必要な複雑さを避けます。複雑なロジックは Flow や Apex にオフロードし、承認プロセスからはシンプルな Field Update などに留めることを検討します。
  • エントリー条件の厳密化: 承認プロセスが開始されるためのエントリー条件を可能な限り具体的に設定し、無関係なレコードで承認プロセスが不必要にトリガーされるのを防ぎます。
  • フローと Apex の活用: 承認プロセスのアクションで実現できない複雑なロジックや外部システム連携が必要な場合は、承認プロセスから Flow を呼び出し、その Flow 内で Apex を実行するなどして柔軟性を持たせます。ただし、この場合も Flow や Apex の Governor Limits に注意し、効率的な設計を心がけます。
  • レコードロックの適切な使用: 承認プロセス中にレコードをロックすることでデータの整合性を保てますが、ユーザーの利便性を損なう可能性もあります。必要な期間だけロックし、最終却下時などには解除するなど、状況に応じた設定を検討してください。

よくある質問 FAQ

Q1:承認プロセスでレコードを編集できないのはなぜですか?

A1:レコードが承認プロセス中にロックされている可能性が高いです。承認プロセスの設定で「レコードの編集可能性 (Record Editability)」を確認してください。通常は「管理者のみ」または「管理者および現在の承認者」に設定されています。提出者が編集できるようにしたい場合は、承認プロセスから一時的に取り消すか、プロセスの設定を変更する必要があります。

Q2:承認プロセスが開始されない場合、どうデバッグしますか?

A2:まず、対象レコードが承認プロセスのエントリー条件 (Entry Criteria) を満たしているか再確認してください。それでも開始されない場合は、ユーザーのデバッグログを有効にし、レコードを保存(または承認プロセスを開始する操作)した際に生成されるログを確認します。ログには、ワークフロー評価ルール(Workflow Rule Evaluation)やフロー(Flow Execution)の評価結果が含まれており、条件が満たされなかった理由がわかる場合があります。

Q3:大量の承認申請が発生した場合、パフォーマンスに影響はありますか?

A3:通常、Salesforce の承認プロセス自体はスケーラブルに設計されています。しかし、承認アクションとして定義されているワークフロー、フロー、または Apex トリガーが大量の DML 操作や SOQL クエリを実行する場合、それらが Governor Limits に抵触し、パフォーマンスが低下したりエラーが発生したりする可能性があります。大量承認を扱う場合は、非同期処理(例: Batch Apex)や一括処理(Bulkify)を考慮したアクション設計が重要です。監視指標としては、Apex Jobs (非同期ジョブの場合) や、Salesforce の Health Check から組織の全体的なパフォーマンスを確認できます。


まとめと参考資料

Salesforce 承認プロセスは、ビジネスプロセスにおける統制、効率性、コンプライアンスを強化するための不可欠なツールです。宣言的な設定で強力な自動化を実現できる一方で、その技術的な動作原理、他のソリューションとの比較、そしてGovernor Limitsやベストプラクティスを深く理解することが、堅牢でスケーラブルなソリューションを構築するための鍵となります。

重要なポイント

  • 承認プロセスは、ビジネス要件に応じて柔軟な多段階承認フローを構築できます。
  • 宣言的ツールでありながら、FlowやApexと組み合わせることで高度な自動化が可能です。
  • エントリー条件、承認ステップ、承認者、アクションの各コンポーネントを適切に設計することが重要です。
  • Governor Limits、権限、エラー処理に関する注意点を理解し、ベストプラクティスに従うことで、予期せぬ問題を回避できます。
  • Metadata APIを通じてXML定義を理解することは、トラブルシューティングや移行作業において非常に有用です。

公式リソース

コメント