You are here:
Using a Custom Class in Templates for Omnistudio Document Generation
You must include the following when you create a custom class to use in a Microsoft Word or Microsoft PowerPoint document template.
Rule |
Entry |
|---|---|
Namespace prefix |
|
Implemented interface |
namespace.VlocityOpenInterface2 |
Method |
getTokenData, which is called from invokeMethod() |
Global object invoke method |
|
Statements |
See below |
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 document template |
Specify whether data needs to fetched from 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):
|
Statements:
{
Boolean success = true;
if(methodName == 'getTokenData')
success = getTokenData(inputs, output, options);
}
return success;
}
/* CustomTokenDataExtractor
*
*
* Sample implementation that can be used to create custom extraction of Contract and
* ContractLineItems using two separate Data Mapper Extractors.
*/
global with sharing class CustomTokenDataExtractor implements namespace.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 = 'SAM Header Extract';
/**
* Specify the Data Mapper Extractor for contract lines data
*/
private static final String DR_EXTRACT_LINEITEMS = 'SAM Line Extract';
/**
* Specify the namespace prefix of deployed package
*/
private static final String NAMESPACE_PREFIX = 'omnistudio__';
/**
*
*/
private static final String COUNT_LINE_ITEMS;
/**
*
*/
private static final String QUERY_DRMAP_ITEM;
/**
* Initialize queries to be used to include namespace prefix
*/
static
{
String queryLineItems =
'SELECT count() ' +
'FROM OrderItem ' +
'WHERE IsDeleted!=true AND OrderId=:contractId';
COUNT_LINE_ITEMS = queryLineItems.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);
}
public Object call(String action, Map<String, Object> args) {
Map<String, Object> input = (Map<String, Object>)args.get('input');
Map<String, Object> output = (Map<String, Object>)args.get('output');
Map<String, Object> options = (Map<String, Object>)args.get('options');
return invokeMethod(action, input, output, options);
}
public 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);
omnistudio.DRProcessResult drProcessResult = omnistudio.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) 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);
omnistudio.DRProcessResult drProcessResult = omnistudio.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)
{
//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;
return 5;
}
/**
*
*/
private Integer countContractItems(Id contractId)
{
Integer contractItems = Database.countQuery(COUNT_LINE_ITEMS);
System.debug('countContractItems:contractItems -> ' + contractItems);
return contractItems;
}
/**
*
*/
class CustomTokenDataExtractorException extends Exception {
}
}

