Salesforce 売上予測ディープダイブ:技術アーキテクト向け API と実装ガイド


背景と応用シーン

Salesforce の Forecasting (コラボレーティブ売上予測) は、単なるレポート機能ではありません。営業チームのパイプラインを可視化し、将来の売上を予測するための強力な経営ツールです。営業マネージャー、役員、そして個々の営業担当者は、この機能を通じてリアルタイムに近いデータに基づいた意思決定を行うことができます。

技術アーキテクトの視点から見ると、Forecasting は多くのカスタムソリューションの基盤となり得ます。例えば、以下のような応用シーンが考えられます。

  • カスタム UI の構築:標準の売上予測画面では表現しきれない独自の KPI やグラフを組み合わせた、カスタムの Lightning Web Components (LWC) を開発する。
  • 外部システム連携:ERP や BI ツールに Salesforce の予測データを連携させ、全社的な予算計画や経営分析に活用する。
  • 高度な分析:過去の予測データと実績データを比較し、予測精度を分析するカスタムロジックを実装する。
  • 自動化処理:特定の予測金額(例えば、Commit カテゴリの金額)が目標を大幅に下回った場合に、マネージャーへ自動でアラートを送信する Apex トリガーやフローを構築する。

これらのシナリオを実現するためには、Salesforce が提供するデータモデルと API を深く理解することが不可欠です。本記事では、Salesforce Forecasting の技術的な側面に焦点を当て、その原理、プログラムからのアクセス方法、そして実装上の注意点を解説します。


原理説明

Salesforce の売上予測は、複数のオブジェクトと概念が連携して機能しています。その中核をなすのは、商談 (Opportunity) オブジェクトのデータを、ユーザーのロール階層に基づいて集計する仕組みです。

主要な概念とオブジェクト

Forecasting Type (売上予測種別): 予測の基準となるデータを定義します。例えば、商談の「金額」に基づく予測、「数量」に基づく予測、あるいはカスタム通貨項目に基づく予測などを設定できます。

Forecast Category (売上予測分類): 各商談が予測の中でどのカテゴリに分類されるかを示します。「パイプライン (Pipeline)」、「最善達成予測 (Best Case)」、「達成予測 (Commit)」、「完了 (Closed)」などがデフォルトで用意されており、商談のフェーズ (Stage) に連動して自動的に設定されます。

Role Hierarchy (ロール階層): データの集計 (ロールアップ) は、Salesforce のロール階層に基づいて行われます。マネージャーは自分の部下の予測を閲覧・集計でき、そのデータはさらに上位の階層へとロールアップされていきます。

Quotas (売上目標): 各ユーザーやテリトリーに設定される売上目標です。予測データと目標データを比較することで、達成率をリアルタイムで把握できます。このデータは ForecastingQuota オブジェクトに格納されます。

ForecastingItem: 特定のユーザー、期間、予測種別における集計済みの予測データを格納する重要なオブジェクトです。このオブジェクトに対して SOQL を実行することで、予測データを直接取得することが可能です。

データへのアクセス方法

プログラムから売上予測データにアクセスするには、主に2つの方法があります。

1. SOQL (Salesforce Object Query Language): ForecastingItem, ForecastingQuota, ForecastingOwnerAdjustment などのオブジェクトに直接クエリを実行する方法です。個々のユーザーの特定の予測値を取得するような、比較的シンプルなユースケースに適しています。しかし、階層全体の複雑なロールアップを再現するには、複数のクエリと複雑なロジックが必要になる場合があります。

2. Analytics REST API: より推奨されるアプローチは、Analytics REST API の Forecasting Facts リソースを利用することです。この API は、Salesforce のバックエンドで計算された信頼性の高い集計済み予測データを、シンプルな HTTP リクエストで取得できるように設計されています。階層全体のデータや、マネージャー調整を含む複雑なデータを取得する際に非常に強力です。

アーキテクトとしては、要件に応じてこれらの方法を使い分ける判断が求められます。カスタム UI でリアルタイムの集計値を表示する場合は Analytics REST API が、特定のユーザーのデータをバッチ処理で取得するだけなら SOQL が適しているでしょう。


示例コード

ここでは、前述した2つのアクセス方法について、具体的なコード例を示します。

1. SOQL による ForecastingItem の取得

この例では、Apex を使用して特定のユーザーと期間におけるコミットされた予測金額を取得します。ForecastingItem オブジェクトは、予測が有効化されている場合にのみ利用可能です。

// Apex Controller
public with sharing class ForecastController {
    
    @AuraEnabled(cacheable=true)
    public static Decimal getCommitForecastForCurrentUser() {
        // 現在のユーザーIDを取得
        Id currentUserId = UserInfo.getUserId();

        // 現在の会計四半期の開始日を取得
        // 注意: 実際のコードでは、対象期間を動的に決定する必要があります
        Date currentQuarterStartDate = Date.today().toStartOfQuarter();

        // ForecastingItemからデータを取得
        // ForecastingItemCategory: 'Commit' (達成予測) を指定
        // OwnerId: 現在のユーザーを指定
        // Period.StartDate: 期間の開始日を指定
        // ForecastingTypeId: 組織で有効な予測種別IDを指定 (ここではハードコードしていますが、実際は動的に取得すべきです)
        List<ForecastingItem> forecastItems = [
            SELECT AmountWithoutManagerAdjustment 
            FROM ForecastingItem 
            WHERE ForecastingItemCategory = 'Commit'
            AND OwnerId = :currentUserId
            AND Period.StartDate = :currentQuarterStartDate
            AND ForecastingTypeId = '01IT00000000001AAA' // このIDは組織ごとに異なります
            LIMIT 1
        ];

        if (!forecastItems.isEmpty()) {
            // マネージャー調整を含まない金額を返す
            return forecastItems[0].AmountWithoutManagerAdjustment;
        } else {
            return 0;
        }
    }
}

コードの注釈:

  • この SOQL は、指定したユーザー (OwnerId)、期間 (Period.StartDate)、カテゴリ (ForecastingItemCategory) の予測データをピンポイントで取得します。
  • ForecastingTypeId は、組織で設定されている予測種別のIDです。SOQL や Tooling API を使って動的に取得することが推奨されます。
  • AmountWithoutManagerAdjustment は、マネージャーによる調整額を含まない、担当者自身の予測金額です。調整額を含む場合は AmountWithoutOwnerAdjustment などを参照します。
  • この方法は、特定のデータポイントを取得するには効率的ですが、階層全体のデータを集計するには不向きです。

2. Analytics REST API による予測データの取得

この例では、Apex から HTTP コールアウトを行い、Analytics REST API の Forecasting Facts エンドポイントにアクセスします。この方法は、Salesforce が内部で行っているロールアップ計算済みの結果を取得できるため、非常に強力です。

まず、API コールアウトを行うために、リモートサイト設定 (Remote Site Setting) に Salesforce の My Domain URL (例: `https://yourdomain.my.salesforce.com`) を登録する必要があります。

// Apex Service Class
public with sharing class ForecastApiService {

    // Analytics REST API を呼び出して予測データを取得するメソッド
    @AuraEnabled
    public static String fetchForecastingFacts() {
        // 組織で有効な予測種別ID (例: Opportunity Revenue)
        // このIDは実際の環境に合わせて変更する必要があります
        String forecastingTypeId = '01IT00000000001AAA'; 

        // APIエンドポイントの構築
        String endpoint = URL.getSalesforceBaseUrl().toExternalForm() + 
                          '/services/data/v58.0/analytics/forecasting-facts' +
                          '?forecastingType=' + forecastingTypeId;
        
        // HTTPリクエストを作成
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        // セッションIDをヘッダーに設定して認証
        req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());

        Http http = new Http();
        HttpResponse res = null;
        String responseBody = '';

        try {
            // HTTPリクエストを送信
            res = http.send(req);

            if (res.getStatusCode() == 200) {
                // 成功した場合、レスポンスボディを返す
                responseBody = res.getBody();
            } else {
                // エラー処理
                System.debug('Error calling Forecasting Facts API. Status: ' + res.getStatus() + ' Body: ' + res.getBody());
                responseBody = 'Error: ' + res.getStatusCode();
            }
        } catch(Exception e) {
            // 例外処理
            System.debug('Exception during Forecast API call: ' + e.getMessage());
            throw new AuraHandledException(e.getMessage());
        }

        return responseBody;
    }
}

コードの注釈:

  • このコードは、現在のユーザーのコンテキストで Analytics REST API を呼び出します。API はそのユーザーの可視性に基づいてデータを返します。
  • エンドポイントに forecastingType クエリパラメータを指定することで、どの予測種別のデータを取得するかを定義します。
  • 認証には現在のユーザーの Session ID を利用しています。これは、Visualforce や Aura/LWC から呼び出される Apex コントローラ内で安全に利用できる方法です。
  • 返却される JSON レスポンスには、階層データ (forecastingHierarchies) や集計データ (facts) が含まれており、非常にリッチな情報を持っています。この JSON をパースすることで、カスタム UI を構築できます。
  • この方法は、階層全体のデータを効率的に取得したい場合に最適です。

注意事項

権限 (Permissions)

売上予測データへのアクセスには、適切な権限が必要です。

  • プロファイル/権限セット: ユーザーは「売上予測の参照 (View Forecasts)」権限を持っている必要があります。また、API を利用するためには「API の有効化 (API Enabled)」権限が必須です。
  • 階層に基づくアクセス: ユーザーは、売上予測階層(通常はロール階層と一致)において自分自身および配下のユーザーのデータにのみアクセスできます。API 経由のアクセスもこのルールに従います。
  • オブジェクト権限: 商談や売上目標などの関連オブジェクトに対する参照権限も必要です。

API 制限 (API Limits)

Salesforce の標準的なガバナ制限が適用されます。

  • SOQL クエリ: 1トランザクションあたりの SOQL クエリ数 (100回) や取得行数 (50,000行) の制限に注意してください。特に、階層をループしてクエリを発行するような実装は避けるべきです。
  • API コールアウト: Analytics REST API を使用する場合、コールアウトの制限 (1トランザクションあたり100回) が適用されます。また、組織全体での24時間あたりの API コール数にもカウントされます。
  • パフォーマンス: 頻繁に更新されるデータを表示するカスタム UI を作成する場合、Platform Cache などを利用して API のレスポンスをキャッシュし、コール数を削減する戦略を検討することが重要です。

エラー処理 (Error Handling)

堅牢なアプリケーションを構築するためには、適切なエラーハンドリングが不可欠です。

  • API コールアウトを行う際は、try-catch ブロックで例外を捕捉し、HTTP ステータスコード (200 以外) を適切に処理してください。特に、権限不足 (403 Forbidden) や不正なリクエスト (400 Bad Request) などのケースを考慮する必要があります。
  • SOQL クエリでは、QueryException が発生する可能性(例:ユーザーが必要な項目へのアクセス権を持っていない)を考慮し、ハンドリングしてください。

データの同期

商談データが更新されてから、それが売上予測の集計値に反映されるまでには、わずかなタイムラグが存在する可能性があります。売上予測のロールアップは非同期で処理されるためです。リアルタイム性が非常に重要な要件である場合は、この点をユーザーに周知するか、設計で考慮する必要があります。


まとめとベストプラクティス

Salesforce の Forecasting 機能は、API を通じてプログラムからアクセスすることで、その可能性を大きく広げることができます。最後に、技術アーキテクトとして心得るべきベストプラクティスをまとめます。

  1. 適切なツールを選択する: 単純なデータポイント(例:自分の今期のコミット額)を取得する場合は SOQL が手軽です。しかし、階層全体の集計データやマネージャー調整を含む複雑なデータを扱う場合は、Analytics REST API の Forecasting Facts リソースを利用することを強く推奨します。これは、Salesforce の標準機能と同じ計算ロジックに基づいた、最も信頼性の高い方法です。
  2. データモデルを深く理解する: コーディングを始める前に、ForecastingItem, ForecastingType, ForecastingQuota と、商談、ロール階層の関係性を完全に理解してください。データモデルの理解が、効率的で正確なコードを書くための鍵となります。
  3. キャッシュ戦略を導入する: 特にカスタム UI を構築する場合、API コール数を最小限に抑えるためにキャッシュは不可欠です。Platform Cache を活用して API のレスポンスを一定期間保持することで、パフォーマンスを劇的に改善し、API 制限の消費を抑えることができます。
  4. 権限と共有ルールを尊重する: カスタムソリューションは、Salesforce の共有モデルを尊重して設計する必要があります。コードは常に実行ユーザーのコンテキストで動作させ(with sharing)、本来アクセスできないはずのデータが表示されることのないように徹底してください。
  5. 非同期処理を考慮する: 大量の予測データを処理・連携するような要件では、Apex の非同期処理(Queueable, Batch Apex)を活用して、ガバナ制限を回避し、システムのパフォーマンスへの影響を最小限に抑えるべきです。

これらの原則に従うことで、Salesforce Forecasting を活用した、スケーラブルで堅牢なカスタムソリューションを構築することができるでしょう。

コメント