Customizing Products with Scripts Using Action Records and Functions

Action records let you customize products with scripts that can automate a series of repetitive tasks or perform advanced tasks, which would otherwise involve multiple manual steps. For example, you can automatically set a series of answers on the user interface or create items required by the configuration. Within a custom script stored in an action, you can use functions from the NetSuite CPQ library that enable you to provide advanced or custom interactions, as well as to read or modify data on the server. Some examples of functions are getValue(), showMessage(), and getData().

Actions become active if their rule matches the answers that users select on the product interface and are processed according to their sequence number. Actions with a lower sequence number run before actions with a higher sequence number.

However, NetSuite CPQ distinguishes between before-event actions and after-event actions depending on when they are verified and processed (if active) compared to the rest of building blocks (questions, answers, additional items, and so on). At every user selection or input on the interface, NetSuite CPQ verifies the building block rules and performs the related tasks (if active) in the following order:

  1. Before-event actions according to their sequence number.

  2. Other building blocks such as questions, answers, materials, and so on.

  3. After-event actions according to their sequence number.

  4. The user interface is refreshed to display changes.

After-event actions are those with the Run as after event box checked. All other actions are considered before-event. Before-event actions are processed before after-event actions even if they have a higher sequence number.

When working with NetSuite CPQ functions in custom client-side scripts, always call them through action records. For more information, see Using Action Records and NetSuite CPQ Functions in Modules and Other Custom Client-Side Scripts.

If you frequently use some NetSuite CPQ functions in action records, you can create common actions shared across all products to easily maintain the code, ensure consistency, and promote code reuse. To create a common action go to CPQ > Configurator > Common Actions and click the New CPQC Common Action button. Provide a name for the common action, enter the JavaScript functions related to the tasks to be performed, and save the record. After creating a common action, you can assign it to an action record through the Common Action field.

To create an action:

  1. In NetSuite, go to CPQ > Configurator > Product Maintenance.

  2. Click Edit next to the product you want to modify.

  3. On the Actions subtab, click New CPQC Action.

  4. Enter a descriptive name for the action.

    This name is displayed under Actions in the Audit menu of the user interface.

  5. In the Code field, enter a unique identifier for this action.

    You can use an abbreviated version of the name as a code to identify the action. The code must contain only uppercase letters, numbers, and underscore characters.

  6. Provide a sequence number to determine the order in which the action is processed.

    You can enter a negative or positive number—for example, −2 or 5.

  7. If NetSuite CPQ Configurator must verify and process (if active) the action after all other building blocks rules have been verified and processed, check the Run as after event box.

    For example, you can mark an action as an after-event if it needs to use the updated material list.

  8. To perform this action only the first time the condition expressed in its rule is met, check the Run only on first matching box. NetSuite CPQ Configurator performs the action again only if the rule condition becomes false and then true again.

  9. In the Rule field, provide the question and answer combination that determines whether NetSuite CPQ Configurator performs the action.

    Enter question and answer codes separated by the forward slash character. For example, A/1. Use operators to combine multiple question and answer sets. For example, A/1&B/2. For more information, see Activating Building Blocks with Rules.

  10. (Optional) To include an additional rule in the action rule, select a category. The action is performed if its rule and the category rule match questions or answers selected by users. For more information, see Working with Categories in NetSuite CPQ Configurator.

  11. To provide the tasks to be performed by the action, three options are available:

    • In the code editor, manually enter the NetSuite CPQ functions.

    • In the Add Action field, select the NetSuite CPQ functions you want to add to the code editor and follow the onscreen instructions.

    • In the Common Action field, select a common action shared across all products and use its code. If you use a common action, NetSuite CPQ Configurator disregards any function entered in the code editor.

    You can combine manually entered JavaScript functions with those selected from the Add Action field.

  12. Click Save.

Using Different Action Types

Two types of actions are available—client-side or server-side. Client-side actions contain scripts that run in the web browser, whereas server-side actions run on the server and can read or modify data on the server. Depending on their type, actions can work with different sets of functions.

The functions can be categorized as follows:

  • Universal functions – Work with questions and answers. For example, getValue() and setValue().

  • User interface functions – Work with and change the look and feel of the user interface. For example, showMessage(), customizeUI(), and getProgress().

  • Window interaction functions – Work with the parent window. For example, queryParent() and sendMessage().

  • Status functions – Work with the NetSuite CPQ Configurator statuses (startup, running, final). For example, submitConfig().

  • Database functions – Read and write data to the database on the server. For example, getData(), getItemPrice(), and createRecord().

Only server-side actions can work with functions that make requests to the database, while client-side actions cannot access the database directly but can request information by calling server-side actions. Both server-side and client-side actions work with the functions that interact with questions and answers. Client-side actions can also work with functions that interact with the user interface, the parent window, and statuses.

The following table summarizes the available function types for client-side and server-side actions.

Client-Side Actions

Server-Side Actions

Universal functions

Universal functions

User interface functions

Database functions

Window interaction functions

Status Functions

User interface functions, window interaction functions, and status functions are considered client-side functions because they work only in client-side actions. Database functions are considered server-side functions because they work only in server-side functions. For more information about the function types, see List of Functions.

To create a server-side function, check the Run on server box on the action record. Actions without this option enabled are considered client-side.

Server-side and client-side actions can be written in JavaScript ES5 and ES6. However, asynchronous functions must always be stored in client-side actions. Server-side and client-side actions run synchronously when activated by their rule. Server-side action can also run asynchronously when called by the runAction() function.

Extensive server-side actions must be called asynchronously through the runAction() function so that the upcoming actions do not freeze the browser window by waiting for its response. In the rule of a server-side action called through runAction(), you must enter X(*/*) — the always false operator —because the action is not activated by answers selected by users on the interface.

The following examples show how to call a server-side action asynchronously from a client-side action:

            runAction('ACTION_CODE').done(callback); 

          
            (async function() {
    //code 
    await runAction('ACTION_CODE');
    //code 
})(); 

          

In the first example, the callback function will run after the server-side action has completed its task. For more information about using the runAction() function, see Performing Multiple Server Requests.

Establishing Client-Server Communication

Server-side actions cannot access the window object to obtain information from the client, and client-side actions cannot access the server. Client and server-side actions can share information through:

  • Questions and answers – Client-side and server-side actions can store and obtain information from questions and answers through universal functions, such as setValue() and getValue(). After submitting the configuration, this information is saved to the configuration record. With this option, you can share information from client to server and the other way around. Use this option to share a small amount of data that will be displayed on the user interface or used in rules.

    For more information about implementing questions and answers in client-server communication, see Transferring Data Using Questions and Answers.

  • The scratchpad variable – A temporary variable of type object available both in client- and server-side actions. In the scratchpad variable, you can store any data type and transfer it from client to server and the other way around. After submitting the configuration, the scratchpad variable gets cleared and is not saved to the configuration record. Use this option for large amounts of data that do not need to be stored in the configuration record.

    The following example shows how to save data obtained from the server to the scratchpad variable.

                    scratchpad.companyname = customer.companyname; 
    
                  

    The following example shows how to save data obtained from the client to the scratchpad variable.

                    scratchpad.sku = prompt('Enter the item SKU'); 
    
                  

    For more information about implementing the scratchpad variable in client-server communication, see Transferring Data Using the Scratchpad Variable.

  • Code exec generated tables – Client-side and server-side actions can store and obtain data through CE-generated tables because they act like variables. However, data must have a table-like structure in the form of an array of objects where each element of the array is a row, and each key of the object is a column. Use this option to share data from the server to the client when you work with input box picklist answers. To share data from the client to the server, use the scratchpad variable.

    For more information about transferring data with CE-generated tables, see Transferring Data from Server to Client with CE-Generated Tables.

  • QTables – Client-side and server-side actions can store and obtain information from qTables because they act like variables. However, data must have a table-like structure. Use this option to share data from the server to the client when you need to display the information on the user interface in a table format. To share data from the client to the server, use the scratchpad variable.

    For more information about transferring data with qTables, see Transferring Data from Server to Client with QTables.

Related Topics

General Notices