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.
- Template cx-subviewTemplate 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 FunctionFetches predicted record IDs. 
- Dynamic Table Layout subviewLayoutDefines which attributes of the predicted records to display. 
Here's an example of a custom subview displaying similar records:
Clone Existing Template to Display Similar Records
There are two approaches you can take:
- 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
- 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:
| 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 PartyIdfor Account,LeadIdfor Lead, orIdfor
                                    custom objects. | 
| query | This should remain unchanged, except for the keywhich must be set to the object
                                    identifier such asPartyIdfor Account,LeadIdfor Lead, orIdfor
                                    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 thevalueparameter
                                    and inparamsmake sure that operator key
                                    exist. | 
| context | The usecasecodeshould contain the use case
                                    ID of the model you want to display. ThesalesMlSubviewparameter 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 examplesite_cxsales_Extension/similarRecordsSubviewLayout | 
- 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. 
- Add an entry as follows for the subview label variable. Note: An existing variable calledsubviewLabelalready exists for standard objects.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.  
- Create call back function. You should already have a
                            callbackhelperregistered 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; });
- 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: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; });
- Create a Subview Layout as shown: