Loading
學習
目錄
選取篩選

          沒有結果
          沒有結果
          以下是搜尋小祕訣

          檢查關鍵字的拼字。
          使用較常見的搜尋字詞。
          選取較少篩選條件以擴大您的搜尋。

          搜尋所有 Salesforce 說明
          使用程序計畫架構

          使用程序計畫架構

          若要確保您的程序依正確順序執行,且定價一致套用至報價,請建立新的程序計畫。

          必要版本

          適用於:Lightning Experience
          適用於:啟用 Salesforce 定價的 Revenue Cloud EnterprisePerformanceUnlimitedDeveloper Edition
          需要的使用者權限
          建立和更新程序計畫定義:

          程序計畫存取權

          Salesforce 定價設計時間使用者

          建立、更新和刪除定價程序:

          程序計畫存取權

          Salesforce 定價設計時間使用者

          若要使用定價程序: Salesforce 定價執行階段使用者
          為 Apex 類別定義、編輯、刪除、設定安全性和設定版本設定: Author Apex

          想像一下您在航空公司工作並協助商務旅行者。現在,讓我們預訂航班!我們想要定價反映即時市場條件,並以客戶的當地貨幣顯示價格。

          在計算價格之前,我們會自動從外部系統中提取動態基本價格,以確保定價具有競爭力。我們也會套用預訂平台的折扣,並新增便利費。

          建立程序計畫後,我們會建立報價。接著,根據使用者的位置 (例如,印度),我們會將總價從 USD 轉換為 INR。

          開始之前,請確保您:

          • 已啟用 Salesforce 定價。
          • 擁有建立程序、程序計畫、產品和報價的權限。
          • 瞭解如何建立定價程序。若要深入瞭解定價程序,請參閱使用 Salesforce 定價 建立您的定價程序
          • 瞭解並瞭解如何使用「內容定義」。若要深入瞭解內容定義,請參閱 內容定義
          • 在您的定價程序和程序計畫中使用相同的內容定義。

          程序計畫定義可能很複雜,特別是在涉及 Apex 類別和不同的定價程序時。請遵循下列步驟來建立報價,並瞭解如何讓定價動態且準確,而無須複雜程序本身。

          開啟定價的程序計畫協調流程

          1. 進入「設定」,在「快速尋找」方塊中輸入 收入設定,然後選取「收入設定」。
          2. 尋找並啟用「定價程序計畫協調流程」。
          3. 尋找並啟用「排除預設和銷售交易類型定價程序」。

          建立商業產品

          1. 進入 App Launcher,尋找並選取「產品」。
          2. 建立名為 Delhi - New York 的商業產品。
            若要瞭解如何建立產品,請參閱 建立簡單產品並確保將「產品記錄類型」設定為「商業」。
          3. 將您的產品新增至目錄,並為其建立價目手冊項目。
          4. 進入「設定」,在「快速尋找」方塊中搜尋並選取「Salesforce 定價設定」。
          5. 在「同步化定價資料」區段中,按一下「同步化」。

          建立您的定價程序

          1. 建立定價程序並將其命名為「航班預訂定價程序」。
            若要建立定價程序,請遵循設定定價程序中的前 5 個步驟。
          2. 建立常數。這些常數會作為定價程序中固定值的預留位置。
            常數名稱 資料類型 預設值
            AdjType TEXT 百分比
            AdjValue NUMBER 5 個
            覆寫 TEXT 覆寫
            ConvFeeAdjType TEXT Amount
            ConvFeeAdjValue NUMBER -250
          3. 新增下列元素。
            1. 定價設定
            2. 價目表價格。使用「價目手冊項目 V2」 決策表格。
            3. 手動折扣。您需要新增三個手動折扣元素。
          4. 系統會新增第一個「手動折扣」元素,以計算航班的動態基本價格。對應這些變數。
            • 輸入變數
              • 調整類型:覆寫
              • 調整值:PartnerUnitPrice
              • 數量:LineItemQuantity
              • 輸入單價:ListPrice
            • 輸出變數
              • 淨單價:NetUnitPrice
          5. 系統會新增第二個「手動折扣」元素,以計算航班預訂的平台折扣。對應這些變數。
            • 輸入變數
              • 調整類型:AdjType
              • 調整值:AdjValue
              • 數量:LineItemQuantity
              • 輸入單價:PartnerUnitPrice
            • 輸出變數
              • 淨單價:NetUnitPrice
          6. 系統會新增最後一個「手動折扣」元素,以計算要向客戶收取航班預訂的便利性費用。
            • 輸入變數
              • 調整類型:ConvFeeAdjType
              • 調整值:ConvFeeAdjValue
              • 數量:LineItemQuantity
              • 輸入單價:NetUnitPrice
            • 輸出變數
              • 淨單價:NetUnitPrice
          7. 設定您的偏好設定以檢視定價資訊、設定檔存取權和排名資訊。
          8. 儲存您的程序。
          9. 啟用您的程序。

          您的程序應如下所示。為了清晰起見,我們已將每個「手動折扣」元素重新命名,以顯示其將執行的定價計算。若要重新命名元素,請按一下 編輯圖示並輸入您想要的名稱。

          程序計畫的定價程序

          定義 Apex 綁架的類別

          1. 進入「設定」,在「快速尋找」方塊中,輸入 Apex 類別,選取「Apex 類別」。
          2. 按一下「新增」。
          3. 第一個 Apex 類別是在從外部資料庫執行定價之前,從「定價」內容中提取所有「銷售交易項目」並以動態隨機基本價格 (介於 990 到 1200) 覆寫其 PartnerUnitPrice 標記的預先勾點。
            public class DynamicFlightBasePriceApex implements RevSignaling.SignalingApexProcessor {
            
                public RevSignaling.TransactionResponse execute(RevSignaling.TransactionRequest request) {
                    System.debug('Executing PREHOOK');
                    String contextId = request.ctxInstanceId;
                    Context.IndustriesContext industriesContext = new Context.IndustriesContext();
                    
                    //Query SalesTransactionItem nodes
                    Map<String, Object> inputQueryItem = new Map<String, Object>{
                        'contextId' => contextId,
                            'tags' => new List<String>{ 'SalesTransactionItem' }
                    };
                    Map<String, Object> itemQueryOutput = industriesContext.queryTags(inputQueryItem);
                    Map<String, Object> itemQueryResult = (Map<String, Object>)itemQueryOutput.get('queryResult');
                    List<Object> itemData = (List<Object>) itemQueryResult.get('SalesTransactionItem');
                    System.debug('QLI itemData=' + itemData);
            
                    // Generate random price between 990 and 1200
                    Decimal minPrice = 990;
                    Decimal maxPrice = 1200;
                    Decimal range = maxPrice - minPrice;
            
                    // Use Crypto.getRandomInteger() to generate a secure random number
                    Integer randomInt = Math.abs(Crypto.getRandomInteger());
                    Decimal randomPrice = minPrice + Math.mod(randomInt, range.intValue() + 1);
            
                    System.debug('Generated Random Price: ' + randomPrice);
                    
                    // STEP 3 - Build update list
                    List<Map<String, Object>> itemNodeUpdates = new List<Map<String, Object>>();
                    for (Object itemObj : itemData) {
                        Map<String, Object> itemNode = (Map<String, Object>) itemObj;
                        List<Object> dataPath = (List<Object>) itemNode.get('dataPath');
                        System.debug('Full item dataPath: ' + JSON.serialize(dataPath));
            			dataPath.remove(0); // Remove contextId
            			itemNodeUpdates.add(new Map<String, Object>{
                            'nodePath' => new Map<String, Object>{ 'dataPath' => dataPath },
                            'attributes' => new List<Object>{
                                new Map<String, Object>{
                                    'attributeName' => 'PartnerUnitPrice',
                                    'attributeValue' => randomPrice
                               }
                            }
                        });
                    }
                           
                    // STEP 4 - Submit context update
                    if (!itemNodeUpdates.isEmpty()) {
                        Map<String, Object> updateInput = new Map<String, Object>{
                            'contextId' => contextId,
                            'nodePathAndAttributes' => itemNodeUpdates
                        };
                        System.debug('--- PREHOOK: SUBMITTING CONTEXT UPDATE ---');
                        System.debug(JSON.serializePretty(updateInput));
                        industriesContext.updateContextAttributes(updateInput);
                    }
            
                    // Return the response
                    RevSignaling.TransactionResponse response = new RevSignaling.TransactionResponse();
                    response.status = RevSignaling.TransactionStatus.SUCCESS;
                    response.message = 'Apex executed successfully with Random Price: ' + randomPrice;
                    return response;
                }
            }
            
          4. 建立另一個 Apex 類別。
            此 Apex 類別是在定價後提取 NetUnitPrice 標籤並使用 85–86 之間的模擬動態轉換率,將其轉換為本地貨幣 INR (印度盧比),然後以新的 INR 價格更新「銷售交易項目」描述,為印度客戶提供本地化的定價可視性。
            public class ConvertFareToINRApex implements RevSignaling.SignalingApexProcessor {
            
                public RevSignaling.TransactionResponse execute(RevSignaling.TransactionRequest request) {
                    System.debug('Executing POSTHOOK');
                    String contextId = request.ctxInstanceId;
                    Context.IndustriesContext industriesContext = new Context.IndustriesContext();
                    
                    //Query SalesTransactionItem nodes
                    Map<String, Object> inputQueryItem = new Map<String, Object>{
                        'contextId' => contextId,
                            'tags' => new List<String>{ 'SalesTransactionItem' }
                    };
                    Map<String, Object> itemQueryOutput = industriesContext.queryTags(inputQueryItem);
                    Map<String, Object> itemQueryResult = (Map<String, Object>)itemQueryOutput.get('queryResult');
                    List<Object> itemData = (List<Object>) itemQueryResult.get('SalesTransactionItem');
                    System.debug('QLI itemData=' + itemData);
                    
                    //Query NetUnitPrice nodes
                    Map<String, Object> inputQueryItem2 = new Map<String, Object>{
                        'contextId' => contextId,
                            'tags' => new List<String>{ 'NetUnitPrice' }
                    };
                    Map<String, Object> itemQueryOutput2 = industriesContext.queryTags(inputQueryItem2);
                    Map<String, Object> itemQueryResult2 = (Map<String, Object>)itemQueryOutput2.get('queryResult');
                    List<Object> itemData2 = (List<Object>) itemQueryResult2.get('NetUnitPrice');
                    System.debug('NetUnitPrice itemData=' + itemData2);
                    Map<String, Object> netUnitTagData = (Map<String, Object>) itemData2.get(0);
                    Decimal netUnitPrice = (Decimal) netUnitTagData.get('tagValue');
                    netUnitPrice = netUnitPrice.setScale(2);
                    System.debug('NetUnitPrice Tag Value=' + netUnitPrice);
            
                    // Generate random price between 85.00 and 86.00 with decimals
                    Decimal minPrice = 85.00;
                    Decimal maxPrice = 86.00;
                    Decimal range = maxPrice - minPrice; 
                    Integer randomInt = Math.abs(Crypto.getRandomInteger());
                    Integer randomDecimalInt = Math.mod(randomInt, 100);
                    Decimal randomFraction = Decimal.valueOf(randomDecimalInt) / 100;
                    Decimal usdToInrRate = minPrice + randomFraction;
                    if (usdToInrRate > maxPrice) { 
                        usdToInrRate = maxPrice;
                    }
                    
                    // Calculate NetUnitPrice in INR
                    Decimal fareInInr = (netUnitPrice * usdToInrRate).setScale(2);
                    
                    String fareMessage = 'The Flight fare in INR is: ' + fareInInr + 
                                 ' (USD ' + netUnitPrice + 
                                 ' at rate ' + usdToInrRate + ')';
                    System.debug(fareMessage);
                    
                    // STEP 3 - Build update list
                    List<Map<String, Object>> itemNodeUpdates = new List<Map<String, Object>>();
                    for (Object itemObj : itemData) {
                        Map<String, Object> itemNode = (Map<String, Object>) itemObj;
                        List<Object> dataPath = (List<Object>) itemNode.get('dataPath');
                        System.debug('Full item dataPath: ' + JSON.serialize(dataPath));
            			dataPath.remove(0); // Remove contextId
            			itemNodeUpdates.add(new Map<String, Object>{
                            'nodePath' => new Map<String, Object>{ 'dataPath' => dataPath },
                            'attributes' => new List<Object>{
                                new Map<String, Object>{
                                    'attributeName' => 'SalesTrxnItemDescription',
                                    'attributeValue' => fareMessage
                               }
                            }
                        });
                    }
                        
                    
                    // STEP 4 - Submit context update
                    if (!itemNodeUpdates.isEmpty()) {
                        Map<String, Object> updateInput = new Map<String, Object>{
                            'contextId' => contextId,
                            'nodePathAndAttributes' => itemNodeUpdates
                        };
                        System.debug('--- PREHOOK: SUBMITTING CONTEXT UPDATE ---');
                        System.debug(JSON.serializePretty(updateInput));
                        industriesContext.updateContextAttributes(updateInput);
                    }
            
                    // Return the response
                    RevSignaling.TransactionResponse response = new RevSignaling.TransactionResponse();
                    response.status = RevSignaling.TransactionStatus.SUCCESS;
                    response.message = 'Apex executed successfully with Price in INR: ' + fareInInr;
                    return response;
                }
            }
            

          設定自訂程序計畫定義

          1. 進入「設定」,在「快速尋找」方塊中搜尋並選取「程序計畫定義」。
          2. 按一下「新增
          3. 指定這些詳細資料。
            1. 標題:航班預訂程序計畫
              按下 Tab 鍵以自動填入「開發人員名稱」。
            2. 流程類型:Revenue Cloud
            3. 主要物件:報價
            4. 內容定義:<內容定義名稱>
              您必須選擇針對使用個案設計的內容定義。不過,請確保這與您在建立定價程序時使用的內容定義相同。
            5. 請儲存您的變更。
          4. 開啟新建立的程序計畫定義記錄。
          5. 若要在「程序計畫區段」中新增您要的程序,請選取「新增」。
          6. 新增第一個區段以取得航班的動態基本價格。指定這些詳細資料。
            1. 類型:標準
            2. 名稱:DynamicBasePriceApex
            3. 區段類型:Apex
            4. 新增區段後,按一下 方向圖示 並指定以下詳細資料。
              1. 階段:定價
              2. 解決類型:預設
              3. Apex:DynamicFlightBasePriceApex
              應該如下所示:
              程序計畫區段
          7. 同樣地,新增另一個區段以執行定價計算,並以我們使用 Apex 預先關聯產生的價格覆寫基本價格。指定這些值。
            1. 類型:標準
            2. 名稱:FlightPriceCalculation
            3. 區段類型:定價程序
            4. 按一下 方向圖示 並指定這些詳細資料。
              1. 階段:定價
              2. 解決類型:預設
              3. 程序:Flight_Booking_Pricing_Procedure
          8. 最後,針對「帳單國家/地區」設定為「印度」的使用者新增此 Apex 後接點,新增區段以將價格從 USD 轉換為 INR (美元轉換為印度盧比)
            1. 類型:標準
            2. 名稱:ConvertFareToINR
            3. 區段類型:Apex
            4. 按一下 方向圖示 並指定這些詳細資料。
              1. 階段:定價
              2. 解決類型:以規則為基礎
              3. 條件需求:符合 所有條件 (AND)
              4. 資源:帳單對象國家
              5. 運算子:等於
              6. 輸出值:印度
              7. Apex:ConvertFareToINRApex
          9. 儲存,然後啟用您的手術計畫定義。

          驗證您的程序計畫執行

          若要確認程序計畫是否依照我們設定的順序執行,且定價正確,我們需要建立報價。

          1. 建立報價
            在「帳單對象」欄位中,輸入 印度
          2. 請儲存您的變更。
          3. 按一下「瀏覽目錄 」,然後將「德里 - 紐約」產品新增至報價。
          4. 將滑鼠停留在「Net Unit Price」值上以查看價格瀑布圖詳細資料。
            您會看見程序計畫的應用,以及您在定價程序中設定的折扣和新增項目。
            報價價格瀑布圖
          5. 若要檢視報價條列項目的已轉換匯率,請按一下報價條列項目列中的 檢視圖示 ,然後選取「檢視」。
          6. 「條列項目描述」會顯示您航班的本地化價格。
            報價條列項目描述
           
          正在載入
          Salesforce Help | Article