You are here:
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, |
Implemented interface |
Callable |
Method |
getTokenData, which is called from invokeMethod(). |
Global object invoke method |
|
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.
|
Include tokenDataQueryInfo |
Containing the following keys (and might also contain other information that custom class implementers can add and maintains state):
|
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 {
}
}
