Loading
Feature Disruption - Service Cloud VoiceRead More
Feature degradation | Gmail Email delivery failureRead More
Omnistudio Document Generation
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
          Sample Custom Class for Hyperlinks and Rich Text

          Sample Custom Class for Hyperlinks and Rich Text

          Using the getTokenData method in a custom class, you can pull the hyperlink and rich text data. You must include these elements when you create a custom class to use in a Microsoft Word or Microsoft PowerPoint document template.

          Rule

          Entry

          Namespace prefix

          For example, clm_dailyins238.

          Implemented interface

          Callable

          Method

          getTokenData, which is called from invokeMethod().

          Global object invoke method

          String methodName, Map<String,Object> inputs, Map<String,Object> outputs, Map<String,Object> options.

          Token mappings (view these by selecting View Token List from the document template you're creating)

          In the output of getTokenData under the key "tokenMap," contains data queried or fetched from the database through Omnistudio Data Mappers that follows expected token mappings defined in the document template.

          Specify whether data must be fetched from the database.

          In the output of getTokenData, set “hasMoreTokenData” to true or false.

          Data Mapper definitions

          In the example custom class below, two Data Mappers are required. Both Data Mapper definitions must follow the token mappings defined in the document template.

          • A Data Mapper that extracts non-repeating information, such as account or contract information (first call to be made).

          • A Data Mapper that extracts repeating information, in this case, contract line items (succeeding calls).

          Include tokenDataQueryInfo

          Containing the following keys (and might also contain other information that custom class implementers can add and maintains state):

          • TotalItems, the total number of contract line items the contract has.

          • PageOffset, the number of contract line items to be queried or fetched in a call.

          • RecordNumber, index from where the contract line items to be queried or fetched should start.

          • The key “tokenDataQueryInfo” to include pagination and query information.

          A custom implementation uses this token format for hyperlink and rich text:

          {  "rows": [    
           {      
             "RTB_richToken": "<p>Rich Text Token 2</p>",      
             "Name": "CL2",      
             "stdcharge": 0,      
             "prd": "IPhone13",      
             "productId": "01tRO000000JoZKYA0"    
          },    
           {      
             "HYP_test": "www.google.com",      
             "RTB_richToken": "<p>Rich Text 1</p>",      
             "Name": "CL1",      
             "stdcharge": 0,      
             "prd": "Galaxy S20",      
             "productId": "01tRO000000JoZPYA0"    
            }  
           ]
          }

          Here's an example of a custom class to retrieve the hyperlink and rich text data:

          global with sharing class CustomTokenDataExtractor implements clm_dailyins238.VlocityOpenInterface2 
          {
              /**
               * Limit support to contract lines to 2000. 
               * Contract lines exceeding 2000 will throw exception.
               */
              private static final Integer MAXIMUM_ALLOWABLE_LINE_ITEMS = 2000;
              
              /**
               * Message used when Data Mapper processing encountered any error
               */
              private static final String ERROR_DR_MESSAGE = 'Error encountered while processing request. Please check log for details.';
              
              /**
               * Message used when contract line items exceed 2000 rows
               */
              private static final String ERROR_DATASET = 'Dataset exceeds maximum allowable line items.';
          
              /**
               * Message used when method name supplied is not 'getTokenData'
               */
              private static final String ERROR_UNSUPPORTED = 'Unsupported method. Only method [getTokenData] is supported.';
          
              /**
               * Specify the Data Mapper Extractor for header data
               */
              private static final String DR_EXTRACT_HEADER = 'Data Mapper Extract';
          
              /**
               * Specify the Data Mapper Extractor for contract lines data
               */
              private static final String DR_EXTRACT_LINEITEMS = 'Custom Line Extract';
          
              /**
               * Specify the namespace prefix of deployed package
               */
              private static final String NAMESPACE_PREFIX = 'clm_dailyins238__';
              
              /**
               * 
               */
              private static final String COUNT_CONTRACT_LINES;
              
              /**
               * 
               */
              private static final String QUERY_DRMAP_ITEM;
               
              /**
               * Initialize queries to be used to include namespace prefix
               */
              static
              {
                  String queryContractLines = 
                      'SELECT count() ' +
                      'FROM $nmspc$ContractLineItem__c ' +
                      'WHERE IsDeleted!=true AND $nmspc$ContractId__c=:contractId';
                  
                  COUNT_CONTRACT_LINES = queryContractLines.replace('$nmspc$', NAMESPACE_PREFIX);
                  
                  String queryDrMapItem = 
                      'SELECT Id, $nmspc$FilterValue__c ' +
                      'FROM $nmspc$DRMapItem__c ' +
                      'WHERE $nmspc$FilterOperator__c=\'LIMIT\' AND Name=:extractDR';
                  
                  QUERY_DRMAP_ITEM = queryDrMapItem.replace('$nmspc$', NAMESPACE_PREFIX);
              }
              
              /**
               * 
               */
              global Object invokeMethod(
                  String methodName, 
                  Map<String, Object> input,
                  Map<String, Object> output, 
                  Map<String, Object> options) 
              {
                  Boolean success = false;
                      
                  System.debug('invokeMethod:methodName -> ' + methodName);
                  System.debug('invokeMethod:input-> ' + input);
                  
                  if (methodName == 'getTokenData') 
                  {
                      success = getTokenData(input, output, options);
                  } 
                  else 
                  {
                      throw new CustomTokenDataExtractorException(ERROR_UNSUPPORTED);
                  }
          
                  System.debug('invokeMethod:output -> ' + output);
                  System.debug('invokeMethod:success -> ' + success);
                  return success;
              }
          
              /**
               *
               */
              private Boolean getTokenData(
                  Map<String, Object> input, 
                  Map<String, Object> output, 
                  Map<String, Object> options)
              {        
                  Boolean success = false;
                  
                  Id contractId = (Id) input.get('contextId');
                  if (countContractItems(contractId) > MAXIMUM_ALLOWABLE_LINE_ITEMS)
                  {
                      throw new CustomTokenDataExtractorException('Dataset exceeds maximum allowable line items.');
                  }
                  
                  if (!input.containsKey('tokenDataQueryInfo')) 
                  {
                      success = getContractTokenData(input, output, options);
                  } 
                  else 
                  {
                      success = getContractItemsTokenData(input, output, options);
                  }
                  
                  System.debug('getTokenData:success -> ' + success);
                  return success;
              }
              
              /**
               *
               */
              private Boolean getContractTokenData(
                  Map<String, Object> input, 
                  Map<String, Object> output, 
                  Map<String, Object> options)
              { 
                  Boolean success = false;
                  
                  /**
                   * TODO: Data Mapper is submitted as input parameter, but is not actually used in this method.
                   *       Do we remove or retain reference?
                   */
                  Map<String, Object> dataMapperMap = (Map<String, Object>) input.get('dataMapperMap');
                  
                  Id contractId = (Id) input.get('contextId');
                  
                  List<Map<String, Object>> DRinputs = new List<Map<String, Object>>();
                  Map<String, Object> DRinput = new Map<String, Object>();
                  
                  DRinput.put('Id', contractId); 
                  DRinputs.add(DRinput);
                  
                  clm_dailyins238.DRProcessResult drProcessResult = clm_dailyins238.DRGlobal.process(DRInputs, DR_EXTRACT_HEADER);
                  System.debug('getContractTokenData:drProcessResult ->' + drProcessResult);
                  
                  if (!drProcessResult.hasErrors())
                  {
                      Map<String, Object> paginationInformation = initializePaginationInfo(contractId);
                      Integer totalItems = (Integer) paginationInformation.get('totalItems');  
                      output.put('hasMoreTokenData', totalItems > 0);
                      output.put('tokenMap', drProcessResult.toJson());
                      output.put('tokenDataQueryInfo', paginationInformation);
          
                      success = true;
                  }
                  else 
                  {
                      throw new CustomTokenDataExtractorException(ERROR_DR_MESSAGE);
                  }
                  
                  System.debug('getContractTokenData:output -> ' + output);
                  System.debug('getContractTokenData:success -> ' + success);
                  return success;
              }
              
              /**
               *
               */
              private Boolean getContractItemsTokenData(
                  Map<String, Object> input, 
                  Map<String, Object> output, 
                  Map<String, Object> options)
              { 
                  Boolean success = false;
                  
                  Map<String, Object> paginationInformation = 
                      (Map<String, Object>) Json.deserializeUntyped((String) input.get('tokenDataQueryInfo'));
                  
                  /**
                   * TODO: Data Mapper is submitted as input parameter, but is not actually used in this method.
                   *       Do we remove or retain reference?
                   */
                  Map<String, Object> dataMapperMap = (Map<String, Object>) input.get('dataMapperMap');
                  
                  Id contractId = (Id) input.get('contextId');
                  Integer recordNumber = (Integer) input.get('recordNumber');
                  //Integer recordNumber = (Integer) paginationInformation.get('recordNumber');
                  
                  List<Map<String, Object>> DRinputs = new List<Map<String, Object>>();
                  Map<String, Object> DRinput = new Map<String, Object>();
                  
                  DRinput.put('Id', contractId);     
                  DRinput.put('recordNumber', recordNumber);
                  DRinputs.add(DRinput);
                  
                  clm_dailyins238.DRProcessResult drProcessResult = clm_dailyins238.DRGlobal.process(DRInputs, DR_EXTRACT_LINEITEMS);   
                  System.debug('getContractItemsTokenData:drProcessResult -> ' + drProcessResult);
                 
                  if (!drProcessResult.hasErrors())
                  {
                      if (!paginationInformation.containsKey('pageOffset')) 
                      {
                          Integer pageOffset = getPageOffset(DR_EXTRACT_LINEITEMS);
                          paginationInformation.put('pageOffset', pageOffset);
                      }
                      
                      updatePageOffset(paginationInformation);
                      
                      Boolean hasMoreData = updateHasMoreData(paginationInformation);
                      
                      output.put('tokenMap', drProcessResult.toJson());
                      output.put('tokenDataQueryInfo', paginationInformation);
                      output.put('hasMoreTokenData', hasMoreData);
                      
                      success = true;
                  }
                  else 
                  {
                      throw new CustomTokenDataExtractorException(ERROR_DR_MESSAGE);
                  }
                          
                  System.debug('getContractItemsTokenData:output -> ' + output);
                  System.debug('getContractItemsTokenData:success -> ' + success);
                  return success;
              }
              
              /**
               *
               */
              private Boolean updateHasMoreData(Map<String, Object> pageInfo) 
              {
                  Integer totalItems = (Integer) pageInfo.get('totalItems');
                  Integer recordNumber = (Integer) pageInfo.get('recordNumber');
                  
                  Boolean hasMoreData = totalItems > recordNumber ? true : false;
                  
                  System.debug('updateHasMoreData:hasMoreData -> ' + hasMoreData);
                  return hasMoreData;
              }
              
              /**
               *
               */
              private void updatePageOffset(Map<String, Object> pageInfo) 
              {
                  Integer pageOffset = (Integer) pageInfo.get('pageOffset');
                  Integer recordNumber = (Integer) pageInfo.get('recordNumber');
                  
                  Integer nextPageOffset = recordNumber + pageOffset;
                  
                  System.debug('updatePageOffset:nextPageOffset -> ' + nextPageOffset);
                  pageInfo.put('recordNumber', nextPageOffset);
              } 
              
              /**
               *
               */
              private Map<String, Object> initializePaginationInfo(Id contractId) 
              { 
                  Integer totalItems = countContractItems(contractId);
                      
                  Map<String, Object> paginationInformation = new Map<String, Object>();
                  paginationInformation.put('queryHeader', true);
                  paginationInformation.put('queryLine', true);
                  paginationInformation.put('recordNumber', 0);
                  paginationInformation.put('totalItems', totalItems);
                  
                  System.debug('initializePaginationInfo:paginationInformation -> ' + paginationInformation);
                  return paginationInformation;
              }
          
              /**
               * 
               */
              private Integer getPageOffset(String extractDR) 
              {
                  clm_dailyins238__DRMapItem__c mapItem = Database.query(QUERY_DRMAP_ITEM);
                  Integer pageOffset = Integer.valueOf(mapItem.get(NAMESPACE_PREFIX + 'FilterValue__c'));
          
                  System.debug('getPageOffset:pageOffset -> ' + pageOffset);
                  return pageOffset;
              }
              
              /**
               *
               */
              private Integer countContractItems(Id contractId) 
              {
                  Integer contractItems = Database.countQuery(COUNT_CONTRACT_LINES);
                  
                  System.debug('countContractItems:contractItems -> ' + contractItems);
                  return contractItems;
              }
          
              /**
               *
               */
              class CustomTokenDataExtractorException extends Exception {
                  
              }
          }
           
          Loading
          Salesforce Help | Article