Loading
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Use Advanced Transaction Detail Line Pricing to Map Custom Fields

          Use Advanced Transaction Detail Line Pricing to Map Custom Fields

          Users can update custom fields on sales transaction items or sales transaction item details through pricing procedures by using the Advanced Detail Line Pricing feature. With this feature, users no longer need to use custom triggers or flows to update those fields. This feature is useful for amendment, renewal, and cancellation use cases.

          Required Editions

          Available in: Lightning Experience
          Available in: Enterprise, Unlimited, and Developer Editions of Revenue Cloud where Transaction Management is enabled
          User Permissions Needed
          To set up and use advanced detail line pricing:

          Salesforce admin

          AND

          Pricing Design Time User permission set

          Before you begin, complete these tasks.

          • To turn on the Advanced Detail Line Pricing feature, in Setup, find and select Revenue Settings, and then turn on the Advanced Detail Line Pricing setting.
          • Configure your pricing procedure.

          Update Revenue Pricing Procedure

          To configure advanced detail line pricing, modify your revenue pricing procedure.

          1. From the App Launcher, find and select Pricing Procedures, and then select a pricing procedure to update.
          2. Modify the pricing procedure by adding a new map line item element as the second element next to the pricing setting in the pricing procedure.
          3. Add context tag mappings to the map line item.

            Input Variable

            Output Variable

            LineItem

            SalesTrxnItemDetailSource

            LineItemQuantity

            ItemDetailQuantity

            NetUnitPrice

            ItemDetailNetUnitPrice

            price_water_fall

            DetailPriceWaterfallIdentifier

            InputUnitPrice

            ItemDetailUnitPrice

            ItemBillingReference

            ItemDetailBillingReference

            ItemNetTotalPrice

            ItemDetailTotalPrice

            TotalLineAmount

            ItemDetailTotalLineAmount

            EffectiveFrom

            ItemDetailEffectiveFrom__std

            EffectiveTo

            ItemDetailEffectiveTo__std

            PricingTermCount

            ItemDetailPricingTermCount__std

            itemTransientEndDate

            ItemDetailTransientEndDate__std

            ItemPricingSource

            ItemDetailPricingSource__std

            DerivedPricingAttribute

            ItemDetailDerivedPricingAttribute__std

            ItemGroupSummarySubtotal

            ItemDetailGroupSummaryTotal__std

            ListPrice

            ItemDetailListPrice__std

            IsContracted

            ItemDetailIsContracted__std

            ItemContractPrice

            ItemDetailContractPrice__std

            STI_TenantName__c

            STID_TenantName__c

            After adding the context tag mappings, you’ll see the default mappings between SalesTransaction and SalesTransactionItemDetail with updated context definitions.

          Update Derived Pricing Discovery Procedure

          If you're using derived pricing, make additional changes to your discovery procedure after completing changes to your revenue pricing procedure. These changes are necessary to determine valid contributing and derived products.

          1. From the App Launcher, find and select Discovery Procedures, and then select a discovery procedure to update.
          2. Add two new elements to the discovery procedure to price derived products: Discovery Settings and Map Line Item.
            Add these variables to discovery settings.
            • Input Variable: Line Item
            • Output Variable: LineItem
            Add these variables to the map line item.
            • Input Variable: SalesTransactionItem
            • Output Variable: SalesTransactionItemDetail

            Add these additional variables to the map line item.

            Input Variable

            Output Variable

            LineItem

            SalesTrxnItemDetailSource

            EffectiveFrom

            ItemDetailEffectiveFrom__std

            EffectiveTo

            ItemDetailEffectiveTo__std

            DerivedPricingAttribute

            ItemDetailDerivedPricingAttribute__std

          3. Support custom fields by using pricing procedures for amend, renew, and cancel (ARC) use cases.
            Custom field setup is applicable if you use ARC APIs and want to use custom fields.
            1. Add custom fields to the QuoteLineItem, QuoteLineItem Detail, OrderProduct, and OrderProductDetails objects.
            2. In the context definition, create an entry for these custom fields in both SalesTransactionItem and SalesTransactionItemDetail nodes.
            3. Create the required mappings in QuoteEntitiesMapping and OrderEntitiesMapping.
          4. Modify the revenue pricing procedure for custom fields.
            1. In the pricing procedure, modify the MapLineItem element to add a mapping between SalesTransactionItem.CustomField and SalesTransactionItemDetail.CustomField.
            2. Create any necessary customization elements within the pricing procedure to assign a value to SalesTransactionItem.CustomField.

              The pricing procedure automatically detects if a specific line has detail entries and writes to SalesTransactionItemDetail.CustomField if they exist. Otherwise, it writes to SalesTransactionItem.CustomField.

              During new sale transactions, CustomField on SalesTransactionItem is populated. For ARC scenarios with detail lines, the detail line is written to CustomField on SalesTransactionItemDetail. If no detail lines are created for ARC, the detail line is it written to CustomField on SalesTransactionItem.

          5. To write custom fields on QuoteLineItem or OrderProducts with detail lines, complete this additional setup involving procedure plans and Apex classes.
            1. Enable a procedure plan. In Setup, find and select Revenue Settings, and turn on the Procedure Plan Orchestration for Pricing setting.
            2. Create a procedure plan for the quote and order.
            3. In the procedure plan, verify all steps include the MapLineItem element. Modify the mappings based on the fields used in the pricing procedure.
            4. Use this ApexCustomFieldHandler Apex class example, which you can enhance to update multiple custom fields if required. This class queries SalesTransactionItem and SalesTransactionItemDetail nodes, extracts custom field values from detail items, and then updates the corresponding custom fields on SalesTransactionItem.
          Example
          Example
          global class ApexCustomFieldHandler implements RevSignaling.SignalingApexProcessor {
          
              public virtual class BaseException extends Exception {}
              public class OtherException extends BaseException {}
              
              public RevSignaling.TransactionResponse execute(RevSignaling.TransactionRequest request) {
                  
                  String contextId = request.ctxInstanceId;
                  Context.IndustriesContext industriesContext = new Context.IndustriesContext();
                  
          
                  // STEP 2 - Query SalesTransactionItem nodes
                  Map<String, Object> inputQueryItem = new Map<String, Object>{
                      'contextId' => contextId,
                      'tags' => new List<String>{ 'SalesTransactionItem', 'SalesTransactionItemDetail' }
                  };
                  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');
                  List<Object> itemDetailData = (List<Object>) itemQueryResult.get('SalesTransactionItemDetail');
          
          
                  Map<String, String> salesTransactionItemIdToCustomAggregatedValue = new Map<String, String>();
                  
                  // STEP 3 - Custom Field Value from SalesTransactionItemDetail
                  for(Object itemDetailObj : itemDetailData) {
                      Map<String, Object> itemDetailNode = (Map<String, Object>) itemDetailObj;
                      Map<String, Object> detailTagMap = (Map<String, Object>) itemDetailNode.get('tagValue');
                      
                      String lineItemId = (String)((Map<String, Object>) detailTagMap.get('SalesTrxnItemDetailParent')).get('tagValue');
                      String cfValue = (String)((Map<String, Object>) detailTagMap.get('STID_TenantName__c')).get('tagValue');
                      
                      System.debug('Custom Field Value for Detail Item' + cfValue);
                      if(cfValue != null) {
                          salesTransactionItemIdToCustomAggregatedValue.put(lineItemId, cfValue);
                      }
                  }
          
          
                  // STEP 4 - 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;
                      Map<String, Object> tagMap = (Map<String, Object>) itemNode.get('tagValue');
                      
                      String lineItemId = (String)((Map<String, Object>) tagMap.get('LineItem')).get('tagValue');
                      
                      List<Object> dataPath = (List<Object>) itemNode.get('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' => 'STI_TenantName__c',
                                  'attributeValue' => salesTransactionItemIdToCustomAggregatedValue.get(lineItemId)
                              }
                          }
                      });
                  }
          
                  // STEP 5 - Create collection context update
                  if (!itemNodeUpdates.isEmpty()) {
                      Map<String, Object> updateInput = new Map<String, Object>{
                          'contextId' => contextId,
                          'nodePathAndAttributes' => itemNodeUpdates
                      };
                      
                      //Step 6 - Update context
                      System.debug('--- PREHOOK: SUBMITTING CONTEXT UPDATE ---');
                      System.debug(JSON.serializePretty(updateInput));
                      industriesContext.updateContextAttributes(updateInput);
                  }
          
                  RevSignaling.TransactionResponse response = new RevSignaling.TransactionResponse();
                  response.status = RevSignaling.TransactionStatus.SUCCESS;
                  return response;
              }
          }
          
          Important
          Important To add custom field information to Asset State Period and Asset Action Source, create appropriate cross-context mappings.
           
          Loading
          Salesforce Help | Article