CPQ scripting language reference
Summarize
Summary of CPQ scripting language reference
ServiceNow CPQ scripting uses a JavaScript-like language designed to dynamically modify field values and Bill of Materials (BOM) data through rules and enrichments. While it does not replicate full JavaScript functionality, it provides a powerful, evolving toolset tailored for product configuration. The scripting language supports essential operators, objects, and keywords to perform arithmetic, string manipulation, logical operations, and data handling within CPQ.
Show less
Supported Features
- Operators: Arithmetic (+, -, , /, %, ++, --), string concatenation (+), assignment (=, +=, -=), comparison (==, ===, !=, !==, >, <, >=, <=), and logical (&&, ||).
- Objects: Arrays, strings, numbers, booleans, maps, and dates are supported. Note that undefined, NaN, and null are not supported, and date objects can be referenced but not returned.
- Keywords: Includes var, let, const, new, control flow statements (if, else if, else, for, for/of), and return. While and unconditional for loops with break are not supported to avoid infinite loops. Functions are also unsupported; scripts should remain concise or leverage managed tables and table queries for complexity.
Practical Scripting Guidance
- Alternative syntax for unsupported operations: Use explicit multiplication or division assignments (e.g.,
number = number otherNumber;) andMath.pow(x, y)for exponentiation. - Type Conversion: Convert arrays and numbers to strings using
toString()or string concatenation, and convert numeric strings to numbers using arithmetic operations. - Type Checking: Use
LGK.isNumber(value)to check if a value is a number. - Accessing Object Properties: Use dot notation or bracket notation (e.g.,
objectName.propertyNameorobjectName["propertyName"]) to dynamically access properties, enabling more flexible script logic especially when combined with table lookups.
Example Use Case
The reference includes an example demonstrating how to replace repetitive conditional logic with a table lookup to dynamically set boolean and quantity fields based on a "shipState" field. This approach reduces script complexity by using data-driven decisions rather than multiple if statements.
Additional Resources
For advanced needs beyond the described capabilities, customers are encouraged to submit a support case via the ServiceNow Support portal. Related documentation covers debugging scripts, scripting best practices for configuration states, and sample scripts to assist with development.
View the operators, objects, and keywords that CPQ supports, together with information about type conversion, type checking, alternative scripts for unsupported operations, and accessing object properties.
CPQ uses a JavaScript-like language to dynamically change the value of fields and BOM data via rules and enrichments. JavaScript is a complex language built over almost thirty years, and while we are unable to replicate every piece of functionality that a developer would normally expect while coding, CPQ scripting remains a powerful tool to assist in the dynamic configuration of products.
The capabilities of CPQ scripting are always expanding. Check back to see the most up-to-date features.
Supported operators
Arithmetic operators:
- +
- Addition
- -
- Subtraction
- *
- Multiplication
- /
- Division
- %
- Modulus
- ++
- Increment
- --
- Decrement
String operators:
- +
- Concatenation
- +=
- Addition assignment
Assignment operators:
- =
- Assignment
- +=
- Addition assignment
- -=
- Subtraction assignment
Comparison operators:
- ==
- Equal to
- ===
- Equal value and equal type
- !=
- Not equal to
- !==
- Not equal value nor equal type
- >
- Greater than
- <
- Less than
- >=
- Greater than or equal to
- <=
- Less than or equal to
Logical operators:
- &&
- And
- ||
- Or
Supported objects
Each object supported can be declared with the following:
- [ ]
- Array
- " "
- String
- ( )
- Number
- true | false
- Boolean
- { }, new Map( )
- Map
- new Date( )
- Date
undefined, NaN, and null are unsupported.
Supported keywords
varletconstnewifelse ifelseforfor/ofreturn
We do not support while or unconditional for loops with break, because of the risk of infinite loops halting performance.
We do not support functions, as the script itself should be small enough to be considered one function. If your script is long with many conditions and variables, consider creating a managed table and using a table query. For more information about using managed tables and table queries, see Matrix Loader: CSV table upload and Minimizing table queries.
Alternative scripts for unsupported operations
Assignment multiplication and division (/= or *=): number = number * otherNumber;, number = number / otherNumber;
Exponentiation (x**y): Math.pow(x, y);
Type conversion
Convert arrays to strings: Array.toString()
Convert numbers to strings: [number] + ""
Convert numeric strings to numbers: [string] - 0
.length does work for strings.Type checking
The following returns a Boolean value indicating whether an input is a number: LGK.isNumber(123)
Accessing object properties
You can access the properties of map objects such as cfgRequest in two ways.
objectName.propertyName
//or
objectName["propertyName"]This is helpful in order to replace large amounts of repetitive code with results from a Table Lookup, since the “propertyName” text could instead be replaced by a variable.
For example, consider a blueprint with the following fields associated with it, and a managed table named shipstatebooleantest.
- shipState
- boolean1
- boolean2
- boolean3
- quantity1
- quantity2
- quantity3
| id | shipState | trueBoolean | quantityTest | rowQuantity |
| 1 | Arizona | boolean1 | quantity1 | 1 |
| 2 | Maine | boolean2 | quantity2 | 2 |
| 3 | California | boolean3 | quantity3 | 3 |
Instead of having an identical if statement check what shipState is and setting the Boolean values and quantities accordingly, you could instead replace it with only one if
statement that sets the values based on the results of a table lookup.
In the following On Configure/Reconfigure script, if the shipState field has a value, the fields that are returned by the lookup function
are set. If the shipState field is blank, then all Boolean and quantity fields are set.
if (cfgRequest.shipState.value != "" && cfgRequest.shipState.value != null){
var fieldMapping = lookup("Select trueBoolean,quantityTest,rowQuantity from shipstatebooleantest where shipState = :value", { "value": cfgRequest.shipState.value });
console.log(fieldMapping);
if (fieldMapping != []){
cfgRequest[fieldMapping[0].trueBoolean].set("value",true);
cfgRequest[fieldMapping[0].quantityTest].set("value",fieldMapping[0].rowQuantity);
}
}
else{
var fieldMapping = lookup("Select trueBoolean,quantityTest,rowQuantity from shipstatebooleantest");
console.log(fieldMapping);
for (var row of fieldMapping) {
cfgRequest[row.trueBoolean].set("value",true);
cfgRequest[row.quantityTest].set("value",row.rowQuantity);ea
}
} If your instance of CPQ needs functionality not described here, create a support case by using the ServiceNow Support portal. For step-by-step instructions, see Create a case on Now Support for CPQ Customers.