How can I display similar records identified by Machine Learning models in Oracle Sales?

As a sales administrator, you can display similar records identified by your own custom Machine Learning model in Oracle Sales by using a ready to use template model to display records details in a similar records fold-out panel.

You can also add custom subview templates for any Sales Machine Learning use case predictions for both standard and custom objects using the following predefined configurations:
  • Template cx-subview

    Template definition is available for accounts, or a new one can be created if needed. For other objects you need to create a new subview.

  • Callback Function

    Fetches predicted record IDs.

  • Dynamic Table Layout subviewLayout

    Defines which attributes of the predicted records to display.

Here's an example of a custom subview displaying similar records:

Sample screenshot of a custom subview displaying similar records

Clone Existing Template to Display Similar Records

There are two approaches you can take:

  1. Clone an existing template: This involves copying an existing subview template Similar Records Template and changing it to suit your needs. This can be faster if the existing template is already close to your requirements and can only be used for Accounts
  2. Add a new template: You can create a new template from scratch, giving you full control over the structure and parameters from the beginning.

Regardless of the approach, the final template would look something like this:

Screenshot of sample code of the final similar records template

If creating a new template, the following properties must be configured:
Name Description
resource This is the name of the object you’re working with (for example, Account, Lead, Custom Object). The alias ensures that your subview definition is unique because multiple sub views can use the same resource (object). The primary key should correspond to the object’s identifier, such as PartyId for Account, LeadId for Lead, or Id for custom objects.
query This should remain unchanged, except for the key which must be set to the object identifier such as PartyId for Account, LeadId for Lead, or Id for custom objects. The value will be empty, as it will be populated with the predicted record IDs. This is handled by the callback function, which fetches and assigns the recommended ID).
Note:
To use Elastic endpoint to call the record details you need to remove provider: "adfRest" in the value parameter and in params make sure that operator key exist.
context The usecasecode should contain the use case ID of the model you want to display. The salesMlSubview parameter must always be set to true for any subview defined for a similar records template. This helps identify the subview and triggers the callback function to retrieve the predicted record ID(s).
title The string value entered here will be used as the subheading when accessing the subview.
subviewLayoutId It's best practice to add your applications extension ID and a slash (/) after as a prefix to your subviewLayoutId. For example site_cxsales_Extension/similarRecordsSubviewLayout
If you added the subview template manually in the template-page (rather than clone an existing subview), the JSON code block which exposes the subview template you created won't get generated. You must add it manually as follows:
  1. Add the following entry to the JSON file. You must also add the alias mentioned in the subview template as the key for exposing your subview template.

    Screenshot highlighting JSON alias code block as the key for exposing your subview template.

  2. Add an entry as follows for the subview label variable.
    Note: An existing variable called subviewLabel already exists for standard objects.

    Screenshot highlighting the variable entry for exposing your subview template.

    The entry in the subview label will need your key and value. Key would be the key used to expose your subview template. Value would decide the action name ( prefixing with 'Show' ) that shows up in action bar.

    Sample screenshot displaying the Constant for the subview Label used by the Show action

  3. Create call back function. You should already have a callbackhelper registered before calling a subview.
    Note: You can track the action chain this callback calls from the listener registered.

    You can update the action chain to call the machine learning specific chain to fetch the predicted records IDs and update the query parameter of the subview. Here's a sample of the code:

    define([
      'vb/action/actionChain',
      'vb/action/actions',
      'vb/action/actionUtils',
    ], (
      ActionChain,
      Actions,
      ActionUtils
    ) => {
      'use strict';
     
      class onBeforeInvokeSubviewCallbackChain extends ActionChain {
     
        /**
         * @param {Object} context
         */
        async run(context, { event }) {
          const { $layout, $extension, $responsive, $user } = context;
          const { query, parentResource, parentRow, fragmentContext } = event;
     
     
          if (fragmentContext.salesMlSubview) {
            // Calling our subview specific action chain.
            const callChainExecuteSalesMLQueryChainResult = await Actions.callChain(context,
             {
              chain: 'executeSalesMLQueryChain',
              params: {
                usecaseCode: fragmentContext.usecasecode,
                partyId: parentRow.Id
              },
            });
            if(callChainExecuteSalesMLQueryChainResult.length > 0){
              query[0].params[0].value = callChainExecuteSalesMLQueryChainResult;
            }
          }
             
          return event.detail.done(query);    
        }
      }
     
      return onBeforeInvokeSubviewCallbackChain;
    });
  4. Create an action chain which calls your endpoint and returns a list of predicted record IDs. This function should be defined from the dynamic layouts of the custom object ( thunder sign ) as shown:

    Sample action chain which calls an endpoint and returns a list of predicted record IDs

    Here's a sample of the code:
    define([
      'vb/action/actionChain',
      'vb/action/actions',
      'vb/action/actionUtils',
      'vx/oracle_cx_salesUI/ui/self/applications/cx-sales/resources/utils/RestHelperEndpoint',
    ], (
      ActionChain,
      Actions,
      ActionUtils,
      RestHelperEndpoint
    ) => {
      'use strict';
     
      class executeSalesMLQueryChain extends ActionChain {
     
        /**
         * Action chain which calls salesMLQuery details when similar records subview is called
         * @param {Object} context
         * @param {Object} params
         * @param {string} params.usecaseCode usecase code of the salesML model we want to call
         * @param {string} params.partyId Id of the record we need to fetch predictions for
         */
        async run(context, { usecaseCode, partyId }) {
          const { $layout, $extension, $responsive, $user } = context;
          let similarRecordsRest = RestHelperEndpoint.get("cx_salesml/postSalesMLQueryAPI");
          let similarRecordsBody = {
            "UseCaseCode": usecaseCode,
            "QueryMetadata": "whereClause:Id =" + partyId + ";numberOfRows:5"
          };
          let recordIds = [];
          try {
            const similarRecordsResponse = await similarRecordsRest.body(similarRecordsBody).fetch();
            if (similarRecordsResponse && similarRecordsResponse.body) {
              let similarRecordsJSON = similarRecordsResponse.body;
              if (similarRecordsJSON && Array.isArray(similarRecordsJSON)) {
                for (let similar of similarRecordsJSON){
                  if(recordIds.length >= 5)
                    break;
                  recordIds.push(parseInt(similar.PARTYID, 10));
                }
              }
            }
          }catch(e){
            //Logger.info('similar-records-subview exception: ' + e);
          }
          return recordIds;
        }
      }
     
      return executeSalesMLQueryChain;
    });
  5. Create a Subview Layout as shown:

    Sample screenshot of the Dynamic Table section of the Rule Sets