Salesforce Partner User Role Names

When you enable the first Salesforce external user on a Partner Account, a user Role Hierarchy gets created for that Account. The new role hierarchy rolls up to the account owner. The three roles in this role hierarchy are Partner User, Partner Manager, and Partner Executive. When you create contacts on the Partner Account and convert them to external users, assign one of these roles to them.

Set the number of roles in Digital Experience Site Settings.


1. Use "Enable As Partner" quick action to enable the Account as Partner Account.


2. Use Enable Partner User from the Contact record.


3. Check the user's role.


4. We can update the Role.


"Converting circular structure to JSON" Exception in JavaScript

Sample code to Reproduce the issue:
let obj = {};
obj.a = "A";
obj.b = obj;
console.log( JSON.stringify( obj ) );


JSON.stringify() method does not support the circular references. So we have to remove the circular references before converting the object to JSON.

Fix for the above code:

let obj = {};
let obj1 = { "value" : "B" };
obj.a = "A";
obj.b = obj1;
console.log( JSON.stringify( obj ) );
 
 

How to find Date fields in the objects in Salesforce?

In the following sample code, I have searched Date data type fields in Account, Lead and Opportunity objects.

Sample Code:
Set < String > listsObjs = new Set < String > { 'Account', 'Lead', 'Opportunity' };      
Map < String, Schema.SObjectType > globalDescription = Schema.getGlobalDescribe();   

for ( String obj : listsObjs ) {  
    
    Schema.sObjectType objType = globalDescription.get( obj );  
    Schema.DescribeSObjectResult objResult = objType.getDescribe();   
    Map<String , Schema.SObjectField > mapFieldList = objResult.fields.getMap();    
    
    for ( Schema.SObjectField objField : mapFieldList.values() ) {    
        
        Schema.DescribeFieldResult fieldResult = objField.getDescribe();    
        String fieldLabel = fieldResult.getLabel().toLowerCase();  
        Schema.DisplayType fielddataType = fieldResult.getType();
        
        if ( fielddataType == Schema.DisplayType.Date ) {   
            
            System.debug( 'Field Label is ' + fieldLabel );            
            System.debug ( objType + '.' + fieldResult.getName() );  
            
        }  
        
    }  
    
}  

 
Output:
 

How to remove or adjust fields in Add Contact Roles in Salesforce?


To remove or adjust fields in Add Contact Roles in Salesforce, update the Search Layout in the Contact Object. The fields from the Contact Search Layout is used in the Add Contact Roles Screen.

1. Go to Object Manager. Select the Contact Object. Select Search Layouts.


2. Find the layout used for the profile and adjust it accordingly.


Output:
 
 

Video Reference:

Remove or adjust fields in Add Contact Roles in Salesforce

How to give Agents ability to see other Agents status without using Omni-Supervisor in Salesforce?


To give Agents ability to see other Agents status without using Omni-Supervisor in Salesforce, report on User Presence entity can be used. 
 
1. Create a Custom Report Type on User Presences object.


2. Create a report using the report type created in Step 1.


Video Reference:

How to give Agents ability to see other Agents status without using Omni Supervisor in Salesforce?

Salesforce Omni-Channel Audio Settings


Starting Summer '22 Release, Omni-Channel notification audio can be customised in the Presence Configuration Audio Settings Sections.

Check the following steps for adjusting the Omni-Channel notification audio.

1. Create a Static Resource with sound file with any of the following extensions.
aac, flac, mp3, ogg, opus, and wav


2. Update the Audio Settings in the Presence Configuration.


Video Reference:

Salesforce Omni-Channel Audio Settings

How to find whether apex is currently executed in Trigger Context in Salesforce?

Trigger.isExecuting can be used to find whether apex is currently executed in Trigger Context in Salesforce.

Sample Code:
System.debug( 'Is it in trigger context ' + Trigger.isExecuting );

Output:


SERVER_ERROR A problem was encountered on the server Exception in Salesforce Open CTI

If you get {"success":false,"returnValue":null,"errors":[{"code":"SERVER_ERROR","description":"A problem was encountered on the server."}]} Exception in Salesforce Open CTI, make sure the agent is assigned to a Softphone Layout.

1. Go to Softphone Layouts in Salesforce Setup.


2. Create a new Softphone Layout if found nothing.

3. Click Softphone Layout Assignment and assign it to the agents Profiles.

How to do Callout before creating records in a Custom Object in Salesforce?


1. Sample Custom Object.


2. Create Remote Site Settings for API Endpoint.


3. Sample Code to override the Standard New button in the custom object.

Apex Class:
public class CreateCustomerRecord {
    
    @AuraEnabled( cacheable = true )  
    public static String fetchCustomerDetails( String strCustomerNo ) {
        
        String endpoint = 'http://www.thomas-bayer.com/sqlrest/CUSTOMER/' + strCustomerNo + '/';
        String strOutput = '{';
        HTTP h = new HTTP();
        HTTPRequest req = new HTTPRequest();
        req.setEndPoint( endpoint );
        req.setMethod( 'GET');
        HTTPResponse res = h.send(req);
        Dom.Document doc = res.getBodyDocument();
        Dom.XMLNode customer = doc.getRootElement();
        
        for ( Dom.XMLNode child : customer.getChildElements() ) {
            
            strOutput += '"' + child.getName() + '" : "' + child.getText() + '", ';
            
        }
        
        strOutput = strOutput.removeEnd( ', ' );
        strOutput += '}';
        System.debug( 'strOutput ' + strOutput );
        return strOutput;
        
    }
    
}

Lightning Web Component:
HTML:
<template>
    <lightning-card title="New Customer Record Creation">
        <div class="slds-m-around_medium">
            <lightning-input type="text" label="Enter Customer Number" onchange={onCustomerNoChange}></lightning-input>
            <lightning-button label="Get Customer Details" onclick={fetchCustomerDetails}></lightning-button>
            <lightning-record-edit-form
                object-api-name="Customer__c"
                onsuccess={handleSuccess}>
                <lightning-messages></lightning-messages>
                <lightning-input-field
                    field-name="First_Name__c"
                    disabled=true
                    value={strFirstName}>
                </lightning-input-field>
                <lightning-input-field
                    field-name="Last_Name__c"
                    disabled=true
                    value={strLastName}>                    
                </lightning-input-field>
                <lightning-input-field
                    field-name="Id__c"
                    disabled=true
                    value={strId}>                    
                </lightning-input-field>
                <lightning-input-field
                    field-name="Street__c"
                    disabled=true
                    value={strStreet}>
                </lightning-input-field>
                <lightning-input-field
                    field-name="City__c"
                    disabled=true
                    value={strCity}>                    
                </lightning-input-field>
                <lightning-button
                    type="submit"
                    name="submit"
                    label="Create Customer Record">
                </lightning-button>
            </lightning-record-edit-form>
        </div>
    </lightning-card>
</template>

JavaScript:
import { LightningElement, api } from 'lwc';
import fetchCustomerDetails from '@salesforce/apex/CreateCustomerRecord.fetchCustomerDetails';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { NavigationMixin } from 'lightning/navigation';

export default class CreateCustomerRecord extends NavigationMixin( LightningElement ) {

    strCustomerNumber;
    strId;
    strFirstName;
    strLastName;
    strStreet;
    strCity;

    onCustomerNoChange( event ) {

        this.strCustomerNumber = event.detail.value;

    }

    fetchCustomerDetails() {

        console.log( 'strCustomerNumber is', this.strCustomerNumber );
        fetchCustomerDetails( { strCustomerNo : this.strCustomerNumber } )    
        .then( result => {  
            
            console.log( 'Retrieved data is ' +  result );
            let customerRecord = JSON.parse( result );
            this.strId = customerRecord.ID;
            this.strFirstName = customerRecord.FIRSTNAME;
            this.strLastName = customerRecord.LASTNAME;
            this.strStreet = customerRecord.STREET;
            this.strCity = customerRecord.CITY;

        } )  
        .catch( error => {  

            console.error( 'Error Occured is', JSON.stringify( error ) );  

        } );  

    }

    handleSuccess( event ) {

        let recId = event.detail.id;
        console.log( 'recId is', recId );
        this.dispatchEvent(
            new ShowToastEvent( {
                title: 'Success',
                message: event.detail.apiName + ' created.',
                variant: 'success',
            } )
        );
        this[ NavigationMixin.Navigate ]({
            type: 'standard__recordPage',
            attributes: {
                recordId: recId,
                objectApiName: 'Customer__c',
                actionName: 'view'
            }
        });

    }

}

js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>
 
Lightning Aura Component:
<aura:component
    implements="lightning:actionOverride,force:hasRecordId,force:hasSObjectName">
    <c:createCustomerRecord/>
</aura:component>


4. Override the New button with the Lightning Aura Component.


Output:
 


Video Reference:

Do Callout before creating records in a Custom Object in Salesforce

Salesforce Interview Questions with Answers Part 71

1. What is Service Appointment?
A Service Appointment is an appointment for a field service technician to perform work for a customer.

2. What is Work Order?
A work order represents work to be performed on products.

3. What is Work Order Line Item?
A work order line item is a child record of a work order. It represents a specific subtask on a work order.

4. Field Service Lightning Health Check
FSL Health Check, also called as Integrity Checker, evaluates the status of Field Service Lightning, warns about critical issues and recommends solutions for the issues.

1. Open Field Service Admin App.
2. Navigate to Field Service Settings.
3. Click Health Check on the left side panel.

5. SuppressWarnings Annotation
The @SuppressWarnings annotation does nothing in Apex but can be used to provide information to third party tools.

Example:

Third party tools that do code scanning.

 

6. Scheduling Recipes in Salesforce Field Service Lightning
Declarative Optimization recipes to address common scheduling Challenges. When the Service Appointments get canceled or shortened or overlap, then the appointments can be added, removed or adjusted automatically.
Four Categories of Scheduling Recipes:
1. Canceled Appointments
2. Shortened Appointment
3. Late-End Overlap
4. Emergency Overlap

Steps:
1. Open Field Service Admin App.
2. Navigate to Field Service Settings.
3. Click Automated Scheduling on the left side panel.

6. How to render or display list in Salesforce Visualforce page?
Page Block Table, Data Table, Data List and Apex Repeat can be used to render list in Visualforce page. 

7. How to set field values to null using SOAP API in Salesforce?
fieldsToNull() can be used to set field values to null using SOAP API.

Sample Code:
sObject objContact = new sObject();  
objContact.type = "Contact";  
// Set the value of LastName to null  
objContact.fieldsToNull = new String[] { "LastName" }; 

8. How to make callouts from the Batch Apex?
Use "Database.AllowsCallouts" to make callouts from the Batch Apex.

9. Salesforce Security 
1. Implement Multi Factor Authentication(MFA)
2. Use Security Health Check
This is available in Salesforce Setup. It is a free.
3. Login IP Ranges
Avoids users logging in from non trusted IP Ranges.
4. Salesforce Shield
Helps additional encryption. Enables us to encrypt data at rest and not just when transmitted over a network.
5. Password Policies
We can expire the password in certain perion like 1 year, etc.
We can avoid resuing old passwords.
We can avoid weak passwords by setting Minimum password length and Password Complexity requirement.

10. Platform Events
Use Salesforce Platform Events to connect business processes in Salesforce and external apps through the exchange of real-time event data. Salesforce Platform events are secure and scalable messages that contain data. Publishers publish event messages that subscribers receive in real time. To customize the data published to the external apps, define Platform Event fields.

11. Different types of Flows in Salesforce
1. Screen Flow:
This can be launched from Quick Action.
https://www.infallibletechie.com/2022/02/how-to-pass-record-id-to-flow-in.html

2. Scheduled Flow:
Automatically run in specified interval like daily, weekly, etc This runs in background.
https://www.infallibletechie.com/2020/09/salesforce-scheduled-flow.html

3. Record-Triggered Flow:
Runs when a record is created, updated or deleted. This runs in background like trigger or process builder.

4. Platform Event-Triggered Flow:
This runs when it is subscribed to a Platform Event.

5. Autolaunched Flow:
It runs in the background. This will be invoked by Apex, process builder, REST API, etc.

6. Omni-channel Flow:
It is mainly to route records to agents via Omni-channel.
https://www.infallibletechie.com/2022/03/how-to-route-cases-using-status-field.html

7. Flow Orchestrator:
Used to group multiple business process to be executed in multiple steps.
https://www.infallibletechie.com/2022/03/simple-flow-orchestrator-in-salesforce.html

12. How to make Report Export to login Screen in Salesforce for additional security?
In Session Security Level Policies section, set Reports and Dashboards to Raise session to high assurance when exporting or printing.

13. Difference between Call Dialog and Redirect to Dialog in Salesforce Einstein Bot
Call Dialog: 
Call Dialog retains the context of the conversation and returns the conversation back to the original dialog after the second dialog(called dialog) is completed. 

Redirect to Dialog: 
Redirect to Dialog interrupts the current dialog and starts another dialog. Unlike Call Dialog, Redirect to Dialog is a one-way transfer to the new dialog.

14. Difference between Sales Dialer and Open CTI in Salesforce?
Sales Dialer in Salesforce provides a way to provision numbers and make calls directly from Salesforce application. However, if you already have a telephony system in place, Open CTI is the way to go since it integrates to that existing system. Service Cloud Voice is advance of both Sales Dialer and Open CTI.

15. Not Processed Salesforce Bulk Job Status
The batch job with this status won’t be processed by Salesforce.
 
This status is assigned
1. When a job is aborted while the batch job is queued.
2. For bulk API queries, if the job has PK(Primary Key) chunking enabled, this state is assigned to the original batch that contains the query when the subsequent batches are created. After the original batch is changed to this state, you can monitor the subsequent batches and retrieve each batch’s results when it’s completed.
https://www.infallibletechie.com/2022/05/not-processed-salesforce-bulk-job-status.html

Not Processed Salesforce Bulk Job Status

The batch job with this status won’t be processed by Salesforce.

 
This status is assigned
1. When a job is aborted while the batch job is queued.
2. For bulk API queries, if the job has PK(Primary Key) chunking enabled, this state is assigned to the original batch that contains the query when the subsequent batches are created. After the original batch is changed to this state, you can monitor the subsequent batches and retrieve each batch’s results when it’s completed.

Reference Article:
https://developer.salesforce.com/docs/atlas.en-us.222.0.api_asynch.meta/api_asynch/asynch_api_batches_interpret_status.htm

How to find whether the Voice Call was routed to a different user before the current User in Salesforce Service Cloud Voice?

When the Voice Call is routed from one agent to another agent in Salesforce, there will be an entry in AgentWork entity. Check the following example. The Voice call was routed to an agent. Since the agent didn't pick, Status of the Agent Work is set to Unavailable and then it got routed to another agent. So, there are two entries in the Agent Work entity for one Voice Call record.

Report
 
 
Sample SOQL
SELECT Id, RequestDateTime, AcceptDateTime, AssignedDateTime, CloseDateTime, DeclineDateTime, OriginalGroupId, PendingServiceRoutingId, UserId, User.Name, WorkItemId, AgentCapacityWhenDeclined, CapacityPercentage, CapacityWeight, Status
FROM AgentWork
WHERE WorkItemId = '0LQ4W000000TQumWAG'


How to quickly setup Open CTI and test their methods from Browser Console in Salesforce?


1. Install the Amazon CTI Package.

2. Go to Call Centers in Setup. Select "Amazon Connect Lightning Adapter". Click Manage Call Center Users and assign yourself.


3. Go to App Manager. Edit the App. Add "Open CTI Softphone" to it.


4. Open the App. Use Browser Developer tool. Select sfdcSoftPhone. Run the following JS.

To show Create Contact screen with Email defined:
sforce.opencti.screenPop( {
    type : sforce.opencti.SCREENPOP_TYPE.NEW_RECORD_MODAL,
    params : { entityName : 'Contact' , defaultFieldValues: { Email:'[email protected]' } },
    callback : function( result ) { console.log( 'Result is', JSON.stringify( result ) ) }
} );

To create Contact record and show:
sforce.opencti.saveLog( {
    value:{ entityApiName : "Contact", FirstName : "Testing", LastName : "Testing" },
    callback: function( result ) {
        console.log( 'Result is', JSON.stringify( result ) );
        console.log( 'Record Id is', result.returnValue.recordId );
        sforce.opencti.screenPop( {
            type : sforce.opencti.SCREENPOP_TYPE.SOBJECT,
            params : { recordId : result.returnValue.recordId },
            callback : function( result ) { console.log( 'Result is ' + JSON.stringify( result ) ) }
        } );
    }
} );
 
To search and show records:

sforce.opencti.searchAndScreenPop( {
    searchParams : "Testing" ,
    queryParams : '',
    callType : "inbound",
    deferred:true,
    callback: function( result ) { console.log( 'Result is ' + JSON.stringify( result ) ) }
} );


Video Reference:

How to quickly setup Open CTI and test their methods from Browser Console in Salesforce

How to check and display based on the list size in Salesforce Visualforce Page and Apex?

Sample Code:
Visualforce Page:
<apex:page controller="SampleVFPageController">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockSection >
                <apex:inputText label="Enter Account Name" value="{!strAccName}"/>
            </apex:pageBlockSection>
            <apex:pageBlockButtons >
                <apex:commandButton value="Fetch Account" action="{!fetchAccounts}"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
        <apex:pageBlock rendered="{! listAccounts.size > 0 }">
            <apex:pageBlockTable value="{!listAccounts}" var="objAcc">
                <apex:column value="{!objAcc.Name}"/>
                <apex:column value="{!objAcc.Industry}"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
        <apex:pageMessage summary="No Matching Accounts found!!!" 
            severity="info" 
            rendered="{! AND( NOT( ISBLANK( strAccName ) ), listAccounts.size == 0 ) }" />
    </apex:form>
</apex:page>

Apex Class:
public class SampleVFPageController {
    
    public String strAccName { get; set; }
    public List < Account > listAccounts { get; set; }
    
    public SampleVFPageController() {
        
        listAccounts = new List < Account >();
        
    }
    
    public void fetchAccounts() {
        
        try {
            
            String strAccNamePattern = '%' + strAccName + '%';
            listAccounts = [ 
                SELECT Id, Name, Industry 
                FROM Account 
                WHERE Name LIKE: String.escapeSingleQuotes( strAccNamePattern )
            ];
            
        } catch ( Exception e ) {
            
            ApexPages.addMessage( 
                new ApexPages.Message( ApexPages.Severity.ERROR, e.getMessage() ) 
            );
            
        }
        
    }
    
}

Output:



How to route chats to a different team if the current team is full of capacity in Salesforce?


Fallback Routing can be used to route chats to a different team if the current is full of capacity in Salesforce.
 
Please check the following implementation. If Team A from Chat Button A is full of capacity or not available, then the chats will be routed to the Team B of Chat Button B.
 
1. Create Two queues for the two teams.
 
2. Create two Chat buttons.
 
Button for Team A:
 

Button for Team B:
 


3. Use the fallback routing.
//An array of button IDs, user IDs, or userId_buttonId
embedded_svc.settings.fallbackRouting = [ '5738c000000QrsX', '5738c000000Qrsc' ]; 


Output:


Reference Article:

Video Reference:

Route chats to a different team if ... x
Route chats to a different team if the current team is full of capacity in Salesforce

Asynchronous Trigger in Salesforce using Change Data Capture

1. Setup/Enable Change Data Capture.

In this example, I have enabled Case object.
 
2. Create a Trigger.
Sample Trigger:
trigger CaseChangeEventTrigger on CaseChangeEvent ( after insert ) {
    
    for ( CaseChangeEvent event : Trigger.New ) {
      
        System.debug( 'Event is ' + event );
        
   }

}

3. Setup Debug Logs for Automated Process user to check the logs.


Test Class for Change Data Capture Trigger:
@isTest
private class CaseChangeEventTriggerTest {
    
    static testMethod void testCDC() {
        
        Test.enableChangeDataCapture();
        insert new Case(
            Subject = 'Testing',
            Origin = 'Phone'
        );
        Test.getEventBus().deliver();
        
    }
    
}

How to send SMS notification in Salesforce Flow?

 Using the following setup and implementation, we can send SMS notification using Salesforce Flow. In the below implementation, I have used a custom object.

Messaging Channel is needed. It's not a free feature. Digital Engagement Messaging license is needed to get Messaging Channel. 


Steps:
1. Create a Messaging Template.


2. Create a Flow.



Note:
1. Messaging channel requires Digital Engagement Licenses.
2. Phone_Number__c is custom Phone data type field on the Custom Object.

How to create a LightningMessageChannel in Salesforce using VS Code?

To create a LightningMessageChannel, use the below steps

1. Open VS Code.

2. Create a Folder with the name "messageChannels" under force-app\main\default.


3. Create a file with Channel name followed by suffix ".messageChannel-meta.xml".


4. Add the below content(Change the variable names and add/remove as needed).

Sample Code:
<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>SampleChannel</masterLabel>
    <isExposed>true</isExposed>
    <description>This is a sample Lightning Message Channel.</description>
    <lightningMessageFields>
        <fieldName>variable1</fieldName>
        <description>Variable 1</description>
    </lightningMessageFields>
    <lightningMessageFields>
        <fieldName>variable2</fieldName>
        <description>Variable 2</description>
    </lightningMessageFields>
</LightningMessageChannel>


5. Add the below in your package.xml.

    <types>
        <members>*</members>
        <name>LightningMessageChannel</name>
    </types>


6. Deploy the MessageChannel to the Source Org by selecting SFDX: Deploy this Source to Org.


How to create Case when agents are not available in Salesforce Embedded Chat?


"Offline support" feature in the Embedded Service Deployment can be used to log case when the agents are not available. The "Offline support" feature will display Case Form when the agents are offline.
 
1. Enable "Offline support" in the Embedded Service Deployment.


2. Add the fields.


Video Reference:

Create Case when agents are Offline in Salesforce Embedded Chat