Find Lookup Records

Use this sample JavaScript script in the Quote Line Calculator to query records within the plugin and to set each quote line’s Description field using fields from those records.

Required Editions
Available in: Salesforce CPQ Winter ’16 and later

Each version of these JavaScript code samples exports all of the methods that the calculator looks for, and documents their parameters and return types.

Use conn.query before you use loops that require lookup information so that you can avoid JSON errors with resolving loops.

Javascript 

1export function onAfterCalculate(quote, lines, conn) {
2	if (lines.length > 0) {
3		var productCodes = [];
4		lines.forEach(function(line) {
5			if (line.record['SBQQ__ProductCode__c']) {
6				productCodes.push(line.record['SBQQ__ProductCode__c']);
7			}
8		});
9		if (productCodes.length) {
10			var codeList = "('" + productCodes.join("', '") + "')";
11			/*
12			 * conn.query() returns a Promise that resolves when the query completes.
13			 */
14			return conn.query('SELECT Id, SBQQ__Category__c, SBQQ__Value__c FROM SBQQ__LookupData__c WHERE SBQQ__Category__C IN ' + codeList)
15				.then(function(results) {
16					/*
17					 * conn.query()'s Promise resolves to an object with three attributes:
18					 * - totalSize: an integer indicating how many records were returned
19					 * - done: a boolean indicating whether the query has completed
20					 * - records: a list of all records returned
21					 */
22					if (results.totalSize) {
23						var valuesByCategory = {};
24						results.records.forEach(function(record) {
25							valuesByCategory[record.SBQQ__Category__c] = record.SBQQ__Value__c;
26						});
27						lines.forEach(function(line) {
28							if (line.record['SBQQ__ProductCode__c']) {
29								line.record['SBQQ__Description__c'] = valuesByCategory[line.record['SBQQ__ProductCode__c']] || '';
30							}
31						});
32					}
33				});
34		}
35	}
36	return Promise.resolve();
37}

Javascript Using Method-Chaining 

This plugin uses method-chaining style to construct the query, which is useful when you want to dynamically construct your queries.

1/**
2 * Created on 9/27/16.
3 */
4export function onAfterCalculate(quote, lines, conn) {
5	if (lines.length) {
6		var codes = [];
7		lines.forEach(function(line) {
8			var code = line.record['SBQQ__ProductCode__c'];
9			if (code) {
10				codes.push(code);
11			}
12		});
13		if (codes.length) {
14			var conditions = {
15				SBQQ__Category__c: {$in: codes}
16			};
17			var fields = ['Id', 'Name', 'SBQQ__Category__c', 'SBQQ__Value__c'];
18			/*
19			 * Queries can also be constructed in a method-chaining style.
20			 */
21			return conn.sobject('SBQQ__LookupData__c')
22				.find(conditions, fields)
23				.execute(function(err, records) {
24					if (err) {
25						return Promise.reject(err);
26					} else {
27						var valuesByCategory = {};
28						records.forEach(function(record) {
29							valuesByCategory[record.SBQQ__Category__c] = record.SBQQ__Value__c;
30						});
31						lines.forEach(function(line) {
32							if (line.record['SBQQ__ProductCode__c']) {
33								line.record['SBQQ__Description__c'] = valuesByCategory[line.record['SBQQ__ProductCode__c']] || '';
34							}
35						});
36					}
37				});
38		}
39	}
40	return Promise.resolve();
41}