Managing CLM
Overview
The CPQ package provides functionalities to cover the contract lifecycle management (referred in this documentation as CLM). Those functionalities allow one to create initial contracts and modify contracts by creating amendment or renewal thus enabling contract lifecycle management.
SETUP
There’s a few steps that need to be done in order to setup in SFDC the CLM functionality.
Layout
- Once you’ve installed the Manage Package, the first step is to make sure the right quote layout is selected.
- Navigate to Settings > Objects
- Click on the ‘PROS Quote object’
- Then click on ‘Page Layout Assignment’
- Make sure you’re using the Quote Layout (CLM) where it’s required.
- In order to use the CLM Module you need to create a Mapping Set.
- Navigate to PROS Mapping Sets (add it to your available Tabs if not present by default).
Select ‘OUT (Contract Management)’ in the dropdown list called ‘Mapping Type’.
to Understanding the communication from Content to Overview tab – Mapping OUT
- One must make sure to use the same Synchronization Column as the one chosen to be used in the Quote Model.
- Select ‘OUT (Contract Management)’ in the dropdown list called ‘Mapping Type’.
- Select ‘OUT (Contract Management)’ in the dropdown list called ‘Mapping Type’.
- By default, PROS recommends using the column named ContractSyncID
For more information on how to configure your Quote Model for CLM please refer to QUOTE DESIGNER AND CUSTOMISATION GUIDE
Additional Step
In Salesforce.com there is an additional step that may need to be configured in order to see exact information regarding the contract line items type (new, deleted, unchanged or modified).
- Go to settings > Translation Workbench
- Make sure the translation workbench is “Enabled”
- Make sure a language (in our example English) is set to “Active”
PROS Objects
Several PROS objects are used to handle the Contract Lifecycle Management. They are represented in the following UML diagram of the Objects Hierarchy:
PROS QUOTE OR THE CLM
The PROS Quote has 4 custom fields used in the CLM context:
| FIELD LABEL | API NAME | DATA TYPE |
|---|---|---|
| Contract Amendment Date | CameleonCPQ ContractAmendmentDate c | Date |
| Contract End Date | CameleonCPQ ContractEndDate c | Date |
| Contract Start Date | CameleonCPQ ContractStartDate c | Date |
| Contract Type | CameleonCPQ ContractType c | Picklist |
NB: Those custom fields are only visible if the CLM Layout is active.
Please refer to the section CLM Setup to see how to configure your layout in order to get the CLM functionalities.
Moreover the PROS Quote has one specific Button as well as one specific Action (for SFDC Lightning) associated to it. This button/action is only visible if the CLM layout is active.
| LABEL | NAME | TYPE |
|---|---|---|
| Create Contract | CLM_Create_Contract | Detail Page Button (OnClick Javascript) |
| Create Contract | CLM_Create_Contract_Action | Custom APEX |
PROS MASTER CONTRACT
The PROS Master Contract is the entity that regroup all contracts active or not.
| FIELD LABEL | API NAME | DATA TYPE |
|---|---|---|
| Create By | CreatedBy | Lookup(User) |
| Last Modified By | LastModifiedBy | Lookup(User) |
| MasterContract Name | Name | Text(80) |
| Owner | Owner | Lookup(User,Queue) |
PROS CONTRACT
The PROS Contract is the entity that bear the information useful to a contract (such as Start Date, End Date, Contract Type, Renewal Type, etc.).
Custom Fields of the PROS Contract:
| FIELD LABEL | API NAME | DATA TYPE |
|---|---|---|
| Account Id | CameleonCPQ AccountId c | Lookup(Account) |
| Contact Id | CameleonCPQ ContactId c | Lookup(Contact) |
| Contract End Date | CameleonCPQ ContractEndDate c | Date |
| Contract Start Date | CameleonCPQ ContractStartDate c | Date |
| Contract Type | CameleonCPQ ContractType c | Picklist |
| Expiration Alert | CameleonCPQ ExpirationAlert c | Number(18, 0) |
| Parent Contract | CameleonCPQ ParentContractId c | Master-Detail(PROS Master Contract) |
| Partner | CameleonCPQ PartnerId c | Lookup(Account) |
| Quote | CameleonCPQ QuoteId c | Lookup(PROS Quote) |
| Renewal Type | CameleonCPQ RenewalType c | Picklist |
| Status | CameleonCPQ Status c | Picklist |
The PROS Contract has two specific Buttons associated to it. These buttons are only visible if the CLM layout is active.
| LABEL | NAME | TYPE |
|---|---|---|
| Contract Amendment | CLM_Contract_Amendment | Detail Page Button (OnClick Javascript) |
| Contract Renewal | CLM_Contract_Renewal | Detail Page Button (OnClick Javascript) |
They are provided as an example and you can use it as a template to create a new contract type. On both buttons, the OnClick Javascript code could be implemented as follows:
Example : Contract Amendment OnClick JS Sample
createQuoteFromContractNoUI('AMENDMENT', false, false)
Example : Contract Renewal OnClick JS Sample
createQuoteFromContractNoUI('RENEWAL', true, false)
Here is an example of how the function createQuoteFromContractNoUI could be implemented:
function createQuoteFromContract(qFcParams) {
toggleWaitingScreen();
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.CPQContract_VFCtrl.createQuoteFromContract_Part1}',
'{!Contract c.Id}',
qFcParams,
function(clmInfo1, event1) {
if (event1.status) {
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.CPQContract_VFCtrl.createQuoteFromContract_Part2}',
'{!Contract c.Id}',
clmInfo1.objectId,
qFcParams,
function(clmInfo2, event2) {
if (event2.status) {
top.location.href = top.location.href = '/'+clmInfo2.objectId;
}
if (event2.type == 'exception') {
alert('{!$Label.MSG_CLM_CFQ_ERROR} (1)' + event2.message);
top.location.href = '{!URLFOR($Action.CameleonCPQ Contract c.View, Contract c.Id)}';
return false;
}
},
{ buffer: false, escape: true, timeout: 120000 }
);
}
if (event1.type == 'exception') {
alert('{!$Label.MSG_CLM_CFQ_ERROR} (2)' + event1.message);
top.location.href = '{!URLFOR($Action.CameleonCPQ Contract c.View, Contract c.Id)}';
return false;
}
},
{ buffer: false, escape: true, timeout: 120000 }
);
}
function createQuoteFromContractNoUI(contractType,refreshItems,replaceItems) {
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.CPQContract_VFCtrl.getNewOptions}',
function(qFcParams, event) {
if (event.status) {
qFcParams.contractType = contractType;
qFcParams.refreshItems = refreshItems;
qFcParams.replaceItems = replaceItems;
createQuoteFromContract(qFcParams);
}
if (event.type == 'exception') {
alert('{!$Label.MSG_CLM_CFQ_ERROR} (3)' + event.message);
return false;
}
},
{ buffer: false, escape: true, timeout: 120000 }
);
}
function normalizeDate(dateVal){
return ((dateVal!=null&&dateVal.length>0) ? new Date(dateVal).toUTCString() : new Date().toUTCString());
}
function toggleWaitingScreen(){
$jq("#waitingScreen").toggleClass("hidden");
$jq("#_gModal_Message").html("In progress..");
}
APEX Controller
@RemoteAction
global static CPQCLM_Utils.QuoteFromContractParameters getNewOptions() {
return new CPQCLM_Utils.QuoteFromContractParameters();
}
@RemoteAction
global static CPQCLM_Utils.CLMInfo createQuoteFromContract_Part1(final Id contractID, CPQCLM_Utils.QuoteFromContractParameters quoFctrParams) {
return CPQCLM_Utils.createQuoteFromContract_Part1(contractID, quoFctrParams);
}
@RemoteAction
global static CPQCLM_Utils.CLMInfo createQuoteFromContract_Part2(final Id contractID, final Id clonedQuoteID, CPQCLM_Utils.QuoteFromContractParameters quoFctrParams) {
return CPQCLM_Utils.createQuoteFromContract_Part2(contractID, clonedQuoteID, quoFctrParams);
}
The two Booleans parameters have the following meaning:
- If RefreshItems is equal to true, then the quote is relaunched and prices are updated. Otherwise none of this happens
- If ReplaceItems is equal to true, the items that are deprecated in the quote are replaced by corresponding items as defined in the catalog via the replacement link of the item. If ReplaceItems equals false no replacement is made and the deprecated items are kept as is.
PROS CONTRACT LINE ITEMS
Contract Lines Items of a Contract are automatically populated from the CPQ quote via an implicit mapping mechanism.
| FIELD LABEL | API NAME | DATA TYPE |
|---|---|---|
| Contract | CameleonCPQ ContractId c | Master-Detail(PROS Contract) |
| Item Description | CameleonCPQ ItemDescr c | Text(255) |
| Quantity | CameleonCPQ Quantity c | Number(15, 2) |
| State | CameleonCPQ ContractLineType c | Picklist |
| Sync ID | CameleonCPQ ContractSyncID c | Text(255) |
| Total Price1 | CameleonCPQ TotalPrice1 c | Currency(15, 2) |
| Total Price2 | CameleonCPQ TotalPrice2 c | Currency(15, 2) |
In details:
- ItemDescr
- Quantity
- ContractLineType
- ContractSyncID
- TotalPrice1
- TotalPrice2Note: For more information on how to configure your Quote Model for CLM please refer to QUOTE DESIGNER AND CUSTOMIZATION GUIDE
Apex ClassCPQCLMUtils
The class CPQCLMUtils contains the Contracts API methods that can be used to create contract through triggers or buttons.
APEX CLM Type definition
enum ContractType {CREATION, RENEWAL, AMENDMENT, RETENTION, EXTENSION}
Map<ContractType, Integer> CONTRACT_TYPES_MAPPINGS = new Map<ContractType, Integer> { ContractType.CREATION => 1, ContractType.RENEWAL => 2, ContractType.AMENDMENT => 3, ContractType.RETENTION => 4, ContractType.EXTENSION => 5 }; enum RenewalType
{ONETIME, AUTOMATIC} Map<RenewalType, Integer> RENEWAL_TYPES_MAPPINGS = new Map<RenewalType, Integer> { RenewalType.ONETIME => 0, RenewalType.AUTOMATIC => 1 }; class CLMInfo { Id objectId; String status; String errorMessage; } class QuoteFromContractParameters { String renewalType; String contractType; Date contractStartDate; Date contractEndDate; Boolean refreshItems; Boolean replaceItems;
} class ContractFromQuoteParameters { ID quoteID; String contractType; Date contractStartDate; String contractStartDateString; Date contractEndDate; String contractEndDateString; }
APEX functions available
enum ContractType {CREATION, RENEWAL, AMENDMENT, RETENTION, EXTENSION}
Map<ContractType, Integer> CONTRACT_TYPES_MAPPINGS = new Map<ContractType, Integer> {
ContractType.CREATION => 1,
ContractType.RENEWAL => 2,
ContractType.AMENDMENT => 3,
ContractType.RETENTION => 4,
ContractType.EXTENSION => 5
};
enum RenewalType {ONETIME, AUTOMATIC}
Map<RenewalType, Integer> RENEWAL_TYPES_MAPPINGS = new Map<RenewalType, Integer>
{
RenewalType.ONETIME => 0,
RenewalType.AUTOMATIC => 1
};
class CLMInfo {
Id objectId;
String status;
String errorMessage;
}
class QuoteFromContractParameters {
String renewalType;
String contractType;
Date contractStartDate;
Date contractEndDate;
Boolean refreshItems;
Boolean replaceItems;
}
class ContractFromQuoteParameters {
ID quoteID;
String contractType;
Date contractStartDate;
String contractStartDateString;
Date contractEndDate;
String contractEndDateString;
}
APEX functions available
CLMInfo createContractFromQuote(
ContractFromQuoteParameters,
ContractType
)
CLMInfo createQuoteFromContract_Part1(
Id contractID,
QuoteFromContractParameters
)
CLMInfo createQuoteFromContract_Part2(
Id contractID,
Id clonedQuoteID,
QuoteFromContractParameters
)
ContractType getContractType(String)
ContractType getContractType(Integer)
RenewalType getRenewalType(String)
RenewalType getRenewalType(Integer)
Id cloneQuote(String, Map<String, Object>)
CreateQuoteFromContract_Part1 returns a CLMInfo object containing the Salesforce.com Quote ID that we need to pass in createQuoteFromContract_Part2.
createQuoteFromContract_Part2 must be called once the DB transaction of Part1 is completed. (either Part2 can be launched on success of Part1 or in a future method).
Create a Contract
In order to create a Contract one must start from a Quote.
- Create a quote in CPQ
- Go into PROS Quotes and press “New”
- Give it a name and optionally fill in the Contract Start Date and/or the Contract End Date if known.
- Then press Save
- This is the quote after it has been saved. One should press on the Content tab in order to go into the CPQ quoting engine
- Once the desired items or configurable items are added to the quote, press “Overview” to trigger the synchronization back into SFDC. This will redirect back to the SFDC PROS Quote.
- Then press “Create Contract”. This will display a pop-up to pick a Start Date and an End Date or modify existing ones if any.
- Clicking on OK will result in a PROS Contract created, and populated with information passed from the contract specific fields of the PROS Quote, and with the PROS Contract Line items that have been synchronized from the CPQ Quote.Note: For more information on the PROS Contract Line Items please refer to the PROS Contract Line Items section of this page
- Note that on a first contract, the state of each PROS Contract Line Items is set to “-“.
- Note as well that the information contained in the cart in the
columns ItemDescr, Quantity, TotalPrice1, TotalPrice2 and ContractLineType are implicitly mapped back into SFDC
- In the next section where a contract is amended/renewed they will bear a different state according to the modifications made
Modify a Contract (Amendment or Renewal)
Now that the contract is created, two buttons are provided by default to modify it. If more contract types are to be handled this is the place where you might want to create new buttons to deal with them.
- You can modify a Contract, by either ‘Amending’ it or ‘Renewing’ it.
- When clicking on one of those buttons, a new quote is created, by cloning the previous one linked with the contract. It specifies the kind of modification, either an amendment or a renewal, thanks to the name and the type.
- Click on the Content tab in order to go into the CPQ quoting engine.
- In CPQ Quote, the products and their characteristics can be modified, added or deleted at will.
- In this example here the quantity of the second printer is changed as well as its associated discount. The last printer of the cart is also deleted and a new Dell laptop has been added to the cart.
- In this example here the quantity of the second printer is changed as well as its associated discount. The last printer of the cart is also deleted and a new Dell laptop has been added to the cart.
- It ends up looking like this:
- Click on Overview to synchronize the information back in SFDC:
- Once the contract is created as described in the previous section (i.e. by pressing “Create Contract” from the PROS Quote after the CPQ Quote has been synchronized into SFDC):
- The comparison algorithm is called to compare the current quote content with the previous quote content.
- The PROS contract line items and their state are populated based on the results of the comparison algorithm.
- In the current example it has detected that the first item is unchanged
- The second item has been modified (quantity and discount)
- The third item is new (the Dell Laptop that was added)
- The fourth item is unchanged
- The first items is deleted.
- The PROS contract line items and their state are populated based on the results of the comparison algorithm.
- The comparison algorithm is called to compare the current quote content with the previous quote content.
- Note that deleted items are always listed at the end of the Contract Line ItemsWarning: The ContractSyncID is essential for the comparison, do make sure it’s properly computed in your cart.
For more information on how to configure your Quote Model in order to choose which set of column to use for the comparison and to compute a meaningful ContractSyncID please refer to QUOTE DESIGNER AND CUSTOMIZATION GUIDE
