Configure the App with Custom Scripts

You can further configure the app to match your business requirements by writing custom scripts using JavaScript that enforce validations and rules, whether you're online or offline. This powerful feature lets you write scripts that can trigger on an event of your choosing, for any top-level parent object and child object. For example, you can create a script that will make the product field mandatory when you create an opportunity.

How to Create a Script

You can create custom scripts for all objects, or for a specific object. Here's how you create a custom scripts for a specific object:

  1. Select the sandbox you want use for your configuration.

  2. Select Navigator > Application Composer > Mobile Application Setup.

  3. Click the CX Sales Mobile Scripts tab at the top of the Mobile Application Setup page.

  4. To create a script for a top-level parent object, select the object you want to write a script for, and then select the event that will trigger your script. You can choose one of these events:

    • On Create (triggered when a new record is created in the mobile app).

    • Before Save (triggered before a record is saved).

    • After Save (triggered after the app has saved the record).

    • On Field Value Change (triggered when a user changes the value of a field and then taps out of the field).

    • On Edit (triggered when a user edits a record).

  5. To create a script for a child object, select the top-level parent object, then select the relevant child object in the Opportunities Children section. Finally, select the event that will trigger your script.

    Note: If you want to create validation for a child object's Before Save or After Save event, you have to use the parent object's Before Save or After Save event.
  6. Click the plus icon in the <Event Name> Scripts section.

  7. Enter the script name and description.

  8. (Optional) If you want the script to work for particular regions, select geographical regions for the script. The script will work for users who have your selected regions as their country preference setting in the CX Sales app.

    Note: A script can have multiple regions associated to it, but the same region can't be assigned to more than one active script for the same object and event.

    If you want to restrict your script to trigger for certain user roles, you will need to specify these by writing a JavaScript script

  9. Click Create and create your script.

  10. Click Validate to check whether your script has any errors. The validation checks include checks for nested functional calls and anything else in the script that will cause it to run forever in an infinite loop.

  11. When you're finished, click Save.

How to Create a Custom Function

You can also create a custom function (known as a utility function) that will be available for all objects in all of your scripts. Here's how:

  1. Follow steps 1 to 6 in the How to Create a Script section, and then click the plus icon in the Utility Functions section.

  2. Create your function. Make sure that you include "_C" in the function, so that the function is designated as a utility function, and is included in the System Functions list (see the Feature That Helps You to Create Your Scripts section below for details about System Functions). Once it's in the System Functions list, you can access your utility function from any custom script. Here's an example of the format:

    function example_c() {
    var a = 100;
    a = 100+a
    }
  3. Click Validate and then Save.

Feature That Helps You to Create Your Scripts

When you're creating your scripts it's important that you enter the correct object and field values, so to help you with this you can type Control + Space in the script box and a list of objects and fields are displayed. Pick the object or field that you want to include and the correct value is added to your script.

This feature also enables you to use the System Functions that auto-populate APIs into your script. Type Control + Space, scroll down to the System Functions section, and you will see a list of APIs that you can use. You can use these APIs, for example, to find out the device's operating system and the current position of the user. In the System Functions section, you can also see the Utility Functions that you have created. See the Library of System Functions for Custom Scripts topic for a list of the System Functions that are available and how you can use them.

Test Your Script

To help you test your script, you can use the CXCoreLogger class methods in your script to write warning, error, or info messages. You can then review the messages to debug the script.

After debugging the script, test the script in CX Sales Mobile, and then publish the sandbox when you're done. See the Test Your Configurations topic for details about how to check your configurations in CX Sales Mobile.

Script Examples

Here are some examples of how you can create custom validation and rules:

Object, Event, and Requirements

Example Script

Object: Opportunity

Event: OnCreate

Requirement: Auto-populate the name

and owner field for the Opportunity.

var oracleCxmOutcome = new Result("");
var currentRow = await getCurrentRow();
var userPref = await getUserPreferences();
var partyName = userPref.getPartyName();
currentRow.setColumn('PartyName1',partyName);
currentRow.setColumn('Name', 'StandardScript'+new Date().toISOString().substring(0, 10));
oracleCxmOutcome.setMessage('MESSAGE_TYPE_SUCCESS', '' ,  'OOB Script for oppty-OnCreate executed');

Object: Opportunity

Event: BeforeSave

Requirement: Update the Opportunity Revenue

amount based on child revenue amounts.

var oracleCxmOutcome = new Result('');
var currentRow = await getCurrentRow();
var childRev = currentRow.getColumn('ChildRevenue');
	let totalAmount = 0;
if(childRev) {
let items = currentRow.getColumn('ChildRevenue').items;
		if(items) {
			items.forEach((item) => {
				totalAmount = totalAmount + item.RevnAmount;
			});
		}
}
	currentRow.setColumn('Revenue',totalAmount);

Object: Opportunity

Event: AfterSave

Requirement: Add a note to the opportunity,

if the opportunity isn't newly created.

var oracleCxmOutcome = new Result('');
var optiRow = await getCurrentRow();
if(!optiRow.isNew()) {
    var opptyNote = await createNewRow(true, 'opportunities', 'Note');
    var noteTxt = 'VGhpcyBOb3RlIHdhcyBjcmVhdGVkIHRocm91Z2ggc2NyaXB0IGZvciBvcHB0eSAtIA==';
    opptyNote.setColumn('NoteTxt',noteTxt);
    optiRow.setColumn('Note',opptyNote);
    oracleCxmOutcome.setModifiedObject(optiRow);
}

Object: Opportunity

Event: OnFieldValueChange - Status Code

Requirement: If the status code value is changed

to WON/LOST, and the win/loss reason isn't specified,

then the ReasonWonLostCode field is made mandatory,

and a message is displayed 'Please specify win/loss reason.'

var oracleCxmOutcome = new Result('');
var optyRow = await getCurrentRow();
var statusCode = optyRow.getColumn('StatusCode');
var reasonWonLostCode = optyRow.getColumn('ReasonWonLostCode');

if((statusCode === 'WON' || statusCode === 'LOST') && (!reasonWonLostCode)) {
    oracleCxmOutcome.setMessage('MESSAGE_TYPE_SUCCESS', '' ,  'You have selected' + statusCode);
    optyRow.setColumnMandatory('ReasonWonLostCode', true);
    oracleCxmOutcome.setMessage('MESSAGE_TYPE_ERROR', '' ,  'Please specify win/loss reason');
}

 if(statusCode !== 'WON' && statusCode !== 'LOST') {
 optyRow.setColumn('ReasonWonLostCode',null);
 optyRow.setColumnMandatory('ReasonWonLostCode', false);
 }

Object: Opportunity Revenue

Event: OnCreate

Requirement: The OnCreate event for the child object called Opportunity Revenue auto-populates its custom field values.

var optiRow = getCurrentRow();
const optyRow = getCurrentRow();
const childRev = getCurrentChildRow();
var oracleCxmOutcome = new Result("");
childRev.setColumn('CXM_Text_c','Single Text');
childRev.setColumn('CXM_Date_c',"2020-03-20");
childRev.setColumn('CXM_CC_c',true);
childRev.setColumn('CXM_Perc_c',.32);
childRev.setColumn('CXM_Num_c',5000);
childRev.setColumn('CXM_LText_c','RGVtbyB0ZXh0IHRvIGJlIGVudGVyZWQ=');

oracleCxmOutcome.setMessage("MESSAGE_TYPE_SUCCESS", "", "OnCreate on Child:");

Object: Opportunity

Event: OnFieldValueChange

Field: Dynamic choice list whose filter value is being checked.

Requirement: Trigger error if user attempts to select a dynamic choice list value that doesn't meet filter criteria.

Prerequisite: Include filter criteria field (in this example, the Account Type) in filter object Picker page on CX Sales Mobile

var oracleCxmOutcome = new Result('');
const optyRow = getCurrentRow();
const accountsQuery = query('accounts'); //query accounts or another object, depending on the use case
accountsQuery.setParameters('PartyId', optyRow.getColumn('account_dcl_Id_c')); //be sure to use the ID field for your DCL here, not the name field
try {
const accountsResponse = accountsQuery.execute();
if (accountsResponse && accountsResponse.length > 0) {
if(accountsResponse[0].getColumn('OrganizationDEO_LSAccountType_c') !== 'SERVICE_CENTER'){ //This checks to see if the filter criteria applied to the DCL are met
  oracleCxmOutcome.setMessage('MESSAGE_TYPE_ERROR', '' ,  'You must choose an organization that is a Service Center. Choose the Service Centers list in the Show filter.');
oracleCxmOutcome.setOutcomeQualifier("OUTCOME_TYPE_FAILURE"); //The error message here indicates that Service Centers is the name of the saved Workspace Search, and is the filter the user should select
}
}
} catch (e) {
//failed to get accounts response
}

Object: Opportunity

Event: BeforeSave

Requirement: Trigger error if user attempts to save a record with an invalid dynamic choice list value.

Prerequisite: Include filter criteria field (in this example, the Account Type) in filter object Picker page on CX Sales Mobile

var oracleCxmOutcome = new Result('');
const optyRow = getCurrentRow();
const accountsQuery = query('accounts'); //query accounts or another object, depending on the use case
accountsQuery.setParameters('PartyId', optyRow.getColumn('account_dcl_Id_c')); //be sure to use the ID field for your DCL here, not the name field
try {
const accountsResponse = accountsQuery.execute();
if (accountsResponse && accountsResponse.length > 0) {
if(accountsResponse[0].getColumn('OrganizationDEO_LSAccountType_c') !== 'SERVICE_CENTER'){ //This checks to see if the filter criteria applied to the DCL are met
  oracleCxmOutcome.setMessage('MESSAGE_TYPE_ERROR', '' ,  'You must choose an organization that is a Service Center. Choose the Service Centers list in the Show filter.');
oracleCxmOutcome.setOutcomeQualifier("OUTCOME_TYPE_FAILURE"); //The error message here indicates that Service Centers is the name of the saved Workspace Search, and is the filter the user should select
}
}
} catch (e) {
//failed to get accounts response
}