Conga Product Documentation

Welcome to the new doc site. Some of your old bookmarks will no longer work. Please use the search bar to find your desired topic.

download

Enabling Auto-Reapproval on Proposal and Proposal Line Items

This API takes several parameters and updates the reapproval data in the process instance so that proposal line items can be automatically reapproved when resubmitted after finalizing new items in the cart. This API is available in the base Approvals package.

API

Signature

updateApprovalData

webService static Boolean updateApprovalData(Id instanceId, String sObjectType, Id contextObjId, List oldContextObjIds, List newContextObjIds)

Request Parameters

Name

Type

Required?

Description

instanceId

ID

Yes

The process instance ID currently running in the system

sObjectType

String

Yes

The sObject type used to identify the object type

contextObjId

ID

Yes

The ID of the context object

oldContextObjIds

List<ID>oldContextObjIds

Yes

The list of approval data context object IDs to be replaced

newContextObjIds

List<ID> newContextObjIds

Yes

The list of new approval data context object IDs

Response Parameter

Name

Type

Required

Description

Ok

Boolean

Yes

Defines if the operation was successful. Returns true if yes, otherwise false.

Code Sample

The sample below enables you to execute auto-reapprovals over proposal line items by considering input parameters such as process instance, sObject type, context object, and lists of old and new context object IDs. These IDs represent the proposal line-item IDs before and after the cart is finalized. You can use this API, for example, when a quote or proposal is approved but the approvals manager changes the discount from 10 to 15% on a proposal line item. You can resubmit the approval request for reapproval. The system honors the auto-reapproval criteria, using which, a request once approved by certain assignees is auto-approved.

/** *Apttus Approvals Management *CustomProposalLineItemTrigger *@2017 Apttus Inc. All rights reserved. */ trigger CustomProposalLineItemTrigger on Apttus_Proposal__Proposal_Line_Item__c (before delete, after insert) { if (Trigger.isBefore && Trigger.isDelete) { // save map of old line items to attributes before they are deleted CustomProposalLineItemSupport.doBeforeDelete(Trigger.old, Trigger.oldMap); } if (Trigger.isAfter && Trigger.isInsert) { // update reapproval data with new line items after they are inserted CustomProposalLineItemSupport.doAfterInsert(Trigger.new, Trigger.newMap); } } /** *Apttus Approvals Management *CustomProposalLineItemSupport * @2017 Apttus Inc. All rights reserved. */ public with sharing class CustomProposalLineItemSupport extends CustomApprovalsConstants { // line item types private static final String LINETYPE_PRODUCT = 'Product/Service'; private static final String LINETYPE_OPTION = 'Option'; // proposal private static final String PROPOSAL_SOBJECT_TYPE = 'Apttus_Proposal__Proposal__c'; private static ID quoteId = null; // associated process instance private static Apttus_Approval__ApprovalProcessInstance__c quoteProcessInstance = null; // map of old line item ids to attribute key private static Map<ID,String> oldLineId2KeyMap = new Map<ID,String>(); // map of new line item attribute key to id private static Map<String,ID> newLineKey2IdMap = new Map<String,ID>(); // map of old line item ids to new line item ids private static Map<ID,ID> lineOldId2NewIdMap = new Map<ID,ID>(); /** * Process old ProposalLineItems before they are deleted when a cart is finalized * @param oldLineItems - a list of the old versions of the sObject records * @param oldLineItemsMap - a map of IDs to the old versions of the sObject records */ public static void doBeforeDelete( List<Apttus_Proposal__Proposal_Line_Item__c> oldLineItems, Map<ID, Apttus_Proposal__Proposal_Line_Item__c> oldLineItemsMap) { // iterate over line items about to deleted for (Integer i=0; i<oldLineItems.size(); i++) { Apttus_Proposal__Proposal_Line_Item__c oldLineItem = oldLineItems[i]; // get quote from line item quoteId = oldLineItem.Apttus_Proposal__Proposal__c; // get line item attributes String lineNumber = String.valueOf(oldLineItem.Apttus_QPConfig__PrimaryLineNumber__c); String lineType = oldLineItem.Apttus_QPConfig__LineType__c; String productId = null; if (lineType == LINETYPE_PRODUCT) { productId = oldLineItem.Apttus_Proposal__Product__c; } else if (lineType == LINETYPE_OPTION) { productId = oldLineItem.Apttus_QPConfig__OptionId__c; //productId = oldLineItem.Apttus_QPConfig__ProductOptionId__c; } String chargeType = oldLineItem.Apttus_QPConfig__ChargeType__c; // create attribute key String oldLineKey = lineNumber + ':' + productId + ':' + chargeType; // save in map oldLineId2KeyMap.put(oldLineItem.Id, oldLineKey); } } /** * Process new ProposalLineItems after they are inserted when a cart is finalized * @param newLineItems - a list of the new versions of the sObject records * @param newLineItemsMap - a map of IDs to the new versions of the sObject records */ public static void doAfterInsert(List<Apttus_Proposal__Proposal_Line_Item__c> newLineItems, Map<ID, Apttus_Proposal__Proposal_Line_Item__c> newLineItemsMap) { // iterate over line items about to deleted for (Integer i=0; i<newLineItems.size(); i++) { Apttus_Proposal__Proposal_Line_Item__c newLineItem = newLineItems[i]; // get quote from line item quoteId = newLineItem.Apttus_Proposal__Proposal__c; // get line item attributes String lineNumber = String.valueOf(newLineItem.Apttus_QPConfig__PrimaryLineNumber__c); String lineType = newLineItem.Apttus_QPConfig__LineType__c; String productId = null; if (lineType == LINETYPE_PRODUCT) { productId = newLineItem.Apttus_Proposal__Product__c; } else if(lineType == LINETYPE_OPTION) { productId = newLineItem.Apttus_QPConfig__OptionId__c; //productId = newLineItem.Apttus_QPConfig__ProductOptionId__c; } String chargeType = newLineItem.Apttus_QPConfig__ChargeType__c; // create attribute key String newLineKey = lineNumber + ':' + productId + ':' + chargeType; // save in map newLineKey2IdMap.put(newLineKey, newLineItem.Id); } // create map of old line item ids to new line item ids Set<ID> oldLineItemIds = oldLineId2KeyMap.keySet(); List<ID> newLineItemIds = new List<ID>(); for (String oldLineItemId : oldLineItemIds) { // get attribute key String attrKey = oldLineId2KeyMap.get(oldLineItemId); // lookup key in new line items map String newLineItemId = null; if(newLineKey2IdMap.containsKey(attrKey)) { newLineItemId = newLineKey2IdMap.get(attrKey); newLineItemIds.add(newLineItemId); // associate old key with new one lineOldId2NewIdMap.put(oldLineItemId, newLineItemId); } } // update reapprovals data by calling API in approvals package List<ID> oldContextObjIds = new List<ID>(oldLineItemIds); List<ID> newContextObjIds = newLineItemIds; system.debug(LoggingLevel.INFO,'sObjectType='+PROPOSAL_SOBJECT_TYPE); system.debug(LoggingLevel.INFO,'contextObjId='+quoteId); system.debug(LoggingLevel.INFO,'oldContextObjIds='+oldContextObjIds); system.debug(LoggingLevel.INFO,'newContextObjIds='+newContextObjIds); if (!oldContextObjIds.isEmpty() && !newContextObjIds.isEmpty() && oldContextObjIds.size() == newContextObjIds.size()) { // get process instance associated with the old quote Apttus_Approval__ApprovalProcessInstance__c instanceSO = getProcessInstance(quoteId); system.debug(LoggingLevel.INFO,'instanceSO='+instanceSO); // call API to update reapproval data Boolean ok = Apttus_Approval.ApprovalsWebService.updateApprovalData(instanceSO.Id, PROPOSAL_SOBJECT_TYPE, quoteId, oldContextObjIds, newContextObjIds); system.debug(LoggingLevel.INFO,'Apttus_Approval.ApprovalsWebService.updateApprovalData='+ok); } } /** * Get process instance for the given proposal id * @param proposalId * @return process instance object */ private static Apttus_Approval__ApprovalProcessInstance__c getProcessInstance(ID proposalId) { List<Apttus_Approval__ApprovalProcessInstance__c> instanceList = [select Id, Name, LastModifiedDate, LastModifiedById, LastActivityDate, CreatedDate, CreatedById, Apttus_Approval__Status__c, Apttus_Approval__StartTime__c, Apttus_Approval__ReassignmentEmailTemplate__c, Apttus_Approval__PrevProcessInstanceId__c, Apttus_Approval__NotifyOnlyEmailTemplate__c, Apttus_Approval__InstanceNumber__c, Apttus_Approval__EscalationEmailTemplate__c, Apttus_Approval__EndTime__c, Apttus_Approval__Data__c, Apttus_Approval__ConsolidationVersionNumber__c, Apttus_Approval__CancellationEmailTemplate__c, Apttus_Approval__BusinessObjectType__c, Apttus_Approval__BusinessObjectLink__c, Apttus_Approval__BusinessObjectId__c, Apttus_Approval__AssignmentEmailTemplate__c, Apttus_Approval__ApprovalProcessId__c From Apttus_Approval__ApprovalProcessInstance__c where Apttus_Approval__BusinessObjectId__c = :proposalId order by CreatedDate DESC limit 1]; if ( ! nullOrEmpty(instanceList)) { return instanceList[0]; } return null; } /** * Checks if the given string value is null or empty. * @param strValue the string to check * @return <code>true</code> if the string value is null or empty, <code>false</code> otherwise */ public static Boolean nullOrEmpty(String strValue) { // check if null or zero length string return (strValue == null || strValue.trim().length() == 0); } /** * Checks if the given list of objects is null or empty. * @param objList the list of objects to check * @return <code>true</code> if the list is null or empty, <code>false</code> otherwise */ public static Boolean nullOrEmpty(List<Object> objList) { // check if null or empty return (objList == null || objList.isEmpty()); } }