CPQ – Consortia! (Quote by Location)

Have you ever wanted to Quote by location? Do you have a client who MUST be able to quote by location? Look no further! Well, look a LITTLE further. Like down this article. This solution involves Account Hierarchy, some Custom Fields, Quote Line Groups, a Fieldset, a Process Builder, a Price Rule, and a QCP! But have no fear, it is all right HERE!

Set Up Account Hierarchy
This solution works with the out of the box Account Hierarchy mechanism in Salesforce. Make sure your accounts are set up accordingly. Parent Accounts that have child (location) Accounts.

Custom Fields
Quote Line Group
– Add Location Field. Lookup(Account)
– Make sure you set up the filter to only show Accounts where Quote Line Group: Account ID = Location: Parent Account ID

– Add Location Name Field. Formula -> point this to Location__r.Name

Quote Line, Opportunity Product, Subscription, Asset, Order Product
– Add Location Field. Lookup(Account) (Same field! All objects!)

Quote Line Groups
Add the Location field to the Line Editor fieldset on Quote Line Group.

Create fieldset called “CPQ_Lookup” with Account Name and Address fields in it.

Custom Script – QCP
Here is the QCP (Javascript) code that copies the Location account’s Name value to the Quote Line Group’s Name field.

export function onAfterCalculate(quote, lines, conn) {
    quote.groups.forEach(function(group) {
        if (group.record != null) {
            group.record['SBQQ__Account__c'] = quote.record['SBQQ__Account__c'];
            if(group.record['Location_Name__c'] != null && group.record['Location_Name__c'] != '') {
                group.record['Name'] = group.record['Location_Name__c'];
    return Promise.resolve();

Create the QCP as a Custom Script record.
– Quote Fields

– Quote Line Group Fields

Configure the Custom Script as the Quote Calculator Plugin in the CPQ Package Settings.

Price Rule
A Price Rule to copy the Location lookup field value from Quote Line Group to Quote Line.
– No conditions, after calculate.
– Target Field: Location__c
– Formula: SBQQ__Group__r.Location__c

Process Builder (Optional)
A Process Builder to automatically set Ordered = True on the Primary Quote when Stage changes to Closed Won. You don’t really need this. It’s a nice to have automation.

Install Links
You made it! Here’s some install links for your time and dedication to your (your customer’s) configuration needs.
Sandbox | Production

After Install
– Setup -> Objects -> Order -> Page Layout -> Order Product Related List -> Add Location Field
– Setup -> Objects -> Quote Line Group -> Fieldsets -> Line Editor -> Add the Location field.
– Run the below script in the execute anonymous popup in the developer console. This installs the Price Rule record and Custom Script record.
(Click here to open the developer console in production and here to open it in sandbox.)
NOTE: Do not forget the step after the script below… πŸ˜ƒ


– Setup -> Salesforce CPQ -> Configure -> Plugins Tab -> Quote Calculator Plugin Field -> QCP

8 thoughts on “CPQ – Consortia! (Quote by Location)

  1. Hi Dennis,
    I’m doing the last step on my own (“A Price Rule to copy the Location lookup field value from Quote Line Group to Quote Line”).
    I created the Price Rule, and in the “Related” tab I’m trying to create a new Price Action — but I cannot find the “Location__c” field in the Target Field picklist. I’ve checked in my “Quote Line” object and I’m sure I created the “Location__c” field.

    Any idea?

  2. Hi, when creating the custom field “Location” in the Quote Line Group, there’s an issue with the filter to only show Accounts. In my org there isn’t “Quote Line Group: Account ID”, the ID field isn’t there to be selected (error: Field not found).
    Any idea?

  3. I am trying to loop through each group to get group level line info separately.

    Like I have 2 groups in QCP. Group1 and Group2
    I can use
    quote.groups.forEach(function(group) {

    // here I want to loop again for every group

    is this possible?


    1. quote.groups.forEach(function(group) {

      // here I want to loop again for every group

      quote.groups.forEach(function(innergroup) {

      Yes this is possible. πŸ™‚

  4. Hello Dennis and thank you for your amazing content.
    Have reviewed many of your articles and wanted to ask you on whether or not you plan to “migrate” the portions of your solutions from PB to flows on projects you worked in the past?

    1. Yes! This is an ongoing and slow process at the moment. There are quite a few active projects happening right now so this sort of thing gets delayed. Eventually everything will be flow and offered in the appexchange. πŸ‘πŸ»

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.