Salesforce Admin Jobs

Path for Learning: 
https://trailhead.salesforce.com/career-path/admin

For jobs, check the following link:
 
To know the Roles of a System Admin in Salesforce, check the following link

How to use Custom Permission in Salesforce Validation Rule?

Custom Permission can be checked in Validation Rule. Use $Permission.Custom_Permission_Name in the Validation Rule to check. If the User have Custom Permission via profile or permission set, then it will return true. Else, it will return false.
 
Check the following simple Validation Rule on Account object to prevent Account records creation with Type "Business Account" and without Custom Permission "Create_Business_Account".

Custom Permission:

Validation Rule:

Output:


Custom Permissions can be assigned to the Users using Profile or Permission Set.


How to use searchAndScreenPop() for Case Search in Salesforce Open CTI?

sforce.opencti.searchAndScreenPop() method is used to search records from the objects selected in the softphone layout for a given string.

Sample code with Case Number search:
sforce.opencti.searchAndScreenPop( {
    searchParams : "300002365" ,
    queryParams : '',
    callType : "inbound",
    deferred:true,
    callback: function( result ) { console.log( 'Result is ' + JSON.stringify( result ) ) }
} );

Here, 300002365 is the Case Number to search the Case Record.

Sample code with Case Subject search:
sforce.opencti.searchAndScreenPop( {
    searchParams : "Test Subject" ,
    queryParams : '',
    callType : "inbound",
    deferred:true, callback: function( result ) { console.log( 'Result is ' + JSON.stringify( result ) ) }
} );

Here "Test Subject" is the Subject of the Case record to search.

Note:
1.  If the screen pop is not working or not searching the records from the objects selected in the softphone layout, please try in incognito mode.

2. Many times, clearing cache and cookies helps you to test the changes. Testing within few minutes after the changes in the softphone layout should be avoided. If you want to test instantly, use Incognito Mode or clear browser cookies and cache.

Opportunities and Contact Role Salesforce Report

1. Create a Report with "Opportunities with Contact Roles" Report Type.
 
 
2. Group it by Account Name, Opportunity Name and Contact Id.
 
 

Allow reparenting in Salesforce Master Detail Relationship

In a Master Detail Relationship, records cannot be reparented. However, to allow child records in master-detail relationships on custom objects to be reparented, enable "Allow reparenting" option in the master-detail relationship definition.


When this option is enabled, users can change the parent of the child records. When the parent is changed for a child record, then the child record access will move to the new parent record since sharing for the child record is inherited from the parent record in a master detail relationship.

"Show All Updates" link Salesforce Chatter Feed

If Feed Tracking is enabled for an object, then old value and new value are displayed as the Chatter Feeds.

Note:
If there are more than two feed-tracked field  values changes in one single transaction, then it displays a "Show All Updates" link. If you click the "Show All Updates" link, then it will display all the field values changes.

 
Show All Updates link is shown since it has more than two fields values changes in one single transaction.

 

Salesforce MFA after Sandbox Refresh

When the users login into the Sandbox after the Refresh, it will prompt them to setup the MFA again.
Note:
The configuration in Authenticator App won't be automatically deleted after the Sandbox Refresh. It has to manually deleted before setting up again for the Sandbox after the Refresh.

Previously configured MFA for the Sandbox will be Invalidated due to Org id change.
Note:
Org Id changes after the Salesforce Sandbox Refresh.

If you want to avoid MFA in the Sandbox, do a post refresh activity to remove the MFA Permission from the Profiles and Permission Sets.

Check the following for best practices and more information on this:

Salesforce Chats Time Tracking Reports

Tracking Start and End Time of the Chats:

1. Create a Report Type with the Object Chat Transcripts.


2. Add Start Time and End Time while creating the Report.


Agent and Visitor Time Tracking:
1. Create a Report Type with Chat Transcripts as Primary Object and Chat Transcript Events as related object.


2. Create a Report with the above Report Type.

3. Group the Report by Chat Transcript name. Add Chat Transcript Event, Time, Agent: Full Name, Type and Detail fields to the report.


System.QueryException: unexpected token: '' in Salesforce

System.QueryException: unexpected token: '<EOF>' exception in Salesforce occurs due to Malformed Query String.

If you are dynamically building the query, use System.debug() to print the query.

Generated Debug log to find the query that failed and the exact SOQL. Check whether the SOQL is generated correctly.

Sample SOQL with the exception:
String strSOQL = 'SELECT Id, Company FROMLead';
System.debug( Database.query( strSOQL ) );


In the above SOQL, there should space between FROM and Lead.

How to iterate list in Salesforce Visualforce Page?

Page Block Table, Data Table, Data List and Apex Repeat can be used to render list in Visualforce page. Check the sample code for reference.

Sample Code:
Visualforce Page:
<apex:page controller="SamplePageController">  
    <apex:pageBlock title="Page Block Table">
        <apex:pageBlockTable value="{!listAccounts}" var="acc">
            <apex:column value="{!acc.Name}"/>
            <apex:column value="{!acc.Type}"/>
            <apex:column value="{!acc.Industry}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
    <apex:pageBlock title="Data Table">    
        <apex:dataTable value="{!listAccounts}" var="acc" border="2">
            <apex:column value="{!acc.Name}"/>
            <apex:column value="{!acc.Type}"/>
            <apex:column value="{!acc.Industry}"/>
        </apex:dataTable>
    </apex:pageBlock>
    <apex:pageBlock title="Data List">   
        <apex:dataList value="{!listAccounts}" var="acc">
            {!acc.Name} - {!acc.Type} - {!acc.Industry}
        </apex:dataList>
    </apex:pageBlock>
    <apex:pageBlock title="Apex Repeat">   
        <apex:pageBlockSection columns="3">
            <apex:repeat value="{!listAccounts}" var="acc">
                <apex:pageBlockSectionItem >{!acc.Name}</apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >{!acc.Type}</apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >{!acc.Industry}</apex:pageBlockSectionItem>
            </apex:repeat>
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>

Apex Class:
public class SamplePageController {
    
    public List < Account > listAccounts { get; set; }
    
    public SamplePageController() {
        
        listAccounts = [ SELECT Id, Name, Industry, Type FROM Account LIMIT 5 ] ;
        
    }

}

Output:


Combobox or Drop Down in Salesforce lightningSnapin__PreChat Lightning Web Component

Sample Code:
HTML:

<template>
    <lightning-card title="Prechat Form">   
        <template class="slds-m-around_medium" for:each={fields} for:item="field">
            <template if:true={field.dropDown} key={field.name}>
                <div key={field.name}>Priority</div>
                <select class="slds-select" key={field.name} onchange={handlePriorityChange}>
                    <option label="Low" value="Low"></option>
                    <option label="Medium" value="Medium"></option>
                    <option label="High" value="High"></option>
                </select>
            </template>
            <template if:false={field.dropDown} key={field.name}>
                <lightning-input
                    key={field.name}
                    name={field.name}
                    label={field.label}
                    value={field.value}
                    max-length={field.maxLength}
                    required={field.required}>
                </lightning-input>
            </template>
        </template>
    </lightning-card>
    <br/>
    <lightning-button
        label="Start Chat"
        title="Start Chat"
        onclick={handleStartChat}
        class="slds-m-left_x-small"
        variant="brand">
    </lightning-button>
</template>

JavaScript:
import BasePrechat from 'lightningsnapin/basePrechat';
import { api } from 'lwc';

export default class Prechat extends BasePrechat {

    @api prechatFields;
    fields;
    namelist;
    priorityValue = 'Low';

    get priorityOptions() {

        return [
            { label: 'Low', value: 'Low' },
            { label: 'Medium', value: 'Medium' },
            { label: 'High', value: 'High' },
        ];

    }

    handlePriorityChange( event ) {
        
        console.log( 'Updated Value is', JSON.stringify( event.target.value ) );
        this.priorityValue = event.target.value;

    }

    /**
     * Set the button label and prepare the prechat fields to be shown in the form.
     */
    connectedCallback() {
        
        this.fields = this.prechatFields.map( field => {
            console.log( 'Field is ', JSON.stringify( field ) );
            let dropDown = false;
            if ( field.label == 'Priority' ) {
                dropDown = true;
            }
            const { label, name, value, required, maxLength } = field;
            return { label, value, name, required, maxLength, dropDown };
        });
        this.namelist = this.fields.map( field => field.name );

    }

    /**
     * On clicking the 'Start Chatting' button, send a chat request.
     */
    handleStartChat() {

        this.template.querySelectorAll( "lightning-input" ).forEach( input => {
            this.fields[ this.namelist.indexOf( input.name ) ].value = input.value;            
        } );
        this.fields[ this.namelist.indexOf( 'Priority' ) ].value = this.priorityValue;
        console.log( 'Updated Fields values are', JSON.stringify( this.fields ) );
        this.startChat( this.fields );

    }

}

JS-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightningSnapin__PreChat</target>
  </targets>
</LightningComponentBundle>


Output:


How to find Accounts without Contacts using Report in Salesforce?

Classic:
1. Go to Reports Tab.

2. Click New.

3. Select Accounts Report Type and click Create.

 

4. Select Cross Filter.


 
5.  Set Accounts without Contacts.


Lightning:
1. Go to Reports tab.

2. Click New.

3. Select "Accounts" Report Type.


4. In the Filter section, select "Add Cross Filter Salesforce".
 
 
5. Choose Accounts and without in Show Me. Select Contacts in Secondary Object. Click Apply.


How to force users to select right Stage while creating Opportunity record in Salesforce?

Validation Rule can be used to force users to select right Stage while creating Opportunity record in Salesforce.

Sample Validation rule:
AND(
ISNEW(),
NOT( ISPICKVAL( StageName , 'Prospecting' ) )
)

Output:
 
 

How to use Einstein Bot for WhatsApp Messages in Salesforce?

For setting up WhatsApp Channel with all the required configuration, use the following link

1. Go to Bot Overview and add the WhatsApp Channel in Connection.


2. Setup the Dialogs.


Output:
 
 

How to prevent users updating Notes in Salesforce?

To prevent users from updating Notes in Salesforce, develop a trigger on Note object and throw an error when someone tries to update the notes.
 
 
Sample Trigger:
trigger NoteTrigger on Note ( before update ) {
    
    for ( Note objNote : trigger.new ) {
        
        objNote.addError(
            'You cannot update the Note(s). Check with your Salesforce System Admin for assistance'
        );
        
    }

}
 
Output: 
 

How to add Customer Community or Experience Cloud users to Public Group in Salesforce?

Select "Customer Portal Users" in the Search. This will list all the Customer Community or Experience Cloud users to add it to the Public Group


INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: [] Exception in Salesforce

INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: [] Exception in Salesforce occurs due to following reasons

1. If the user doesn't have access to the Lookup or Master detail relationship records when they are updating a record with it.

2. If the user is trying to update the record with the OwnerId and the owner doesn't have access to the record.

3. This also occurs when the Task record is created with blank or null Assigned To(OwnerId) field.

4. If the issue is happening after listening to Platform Event and updating the record, then set "Publish After Commit" as the Publish Behavior.


Salesforce Interview Questions with Answers Part 70

1. How to route Leads/Cases/Chats/Custom Object records based on Agents Availability in Salesforce?
We can use Omni-Channel feature in Salesforce. Based on the Omni-Channel presence status(Online, Offline, Away, etc), the records will be assigned to the agents.

2. Types of routing in Salesforce Omni-Channel
In Omni-Channel, we have two types of routing.
1. Skill Based Routing
https://www.infallibletechie.com/2020/06/route-chats-via-skills-based-routing.html
2. Queue Based Routing
https://www.infallibletechie.com/2021/01/queue-based-chat-routing-in-salesforce.html

3. Where do we configure Skills for agents for Skill Based routing in Salesforce?
1. Create a Service Resource records for the agents.
2. Created related Skills records from the Service Resource related list "Skills".

4. Is it possible to route WhatsApp Messages, Facebook Messages and SMS Messages using Omni-Channel?
Yes. We have to utilize Digital Engagement Messaging feature in Salesforce.
https://www.infallibletechie.com/2020/04/digital-engagement-messaging-in.html

WhatsApp Messages Routing:
https://www.infallibletechie.com/2021/03/how-to-route-whatsapp-messages-to.html

SMS Messages Routing:
https://www.infallibletechie.com/2020/04/sms-channel-setup-in-digital-engagement.html

Facebook Messages Routing:
https://www.infallibletechie.com/2020/04/facebook-channel-setup-in-digital.html

Note:
Digital Engagement Messaging is not a free feature. It requires additional Add-On Licenses.

5. How to change the behavior of Contact that gets created as part of Digital Engagement Messaging in Salesforce?
Channel Object Linking Rules can be used. It is easy to set up by just point and click configuration.
https://www.infallibletechie.com/2020/06/setting-up-channel-object-linking-in.html

6. What objects support Assignment Rules?
1. Lead
2. Case
https://www.infallibletechie.com/2014/02/assignment-rule-in-salesforce.html

7. How to handle SLAs in Salesforce Cases?
Entitlement Management can be used.
https://www.infallibletechie.com/2013/06/entitlement-management-in-salesforce.html

8. What objects support Salesforce Entitlement Management?
1. Case
2. Work Order

9. How to escalate the cases automatically in Salesforce based on some criteria?
Escalation Rules can be used.
https://www.infallibletechie.com/2013/08/escalation-rule-in-salesforce.html

10. How to send an email when a Case Comment is added to the Case in Salesforce?
Case Comment notification can be used.
https://www.infallibletechie.com/2020/10/case-comment-notification-in-salesforce.html

11. How to capture or create cases from the emails in Salesforce?
Email to Case can be utilized.
https://www.infallibletechie.com/2012/10/email-to-case-in-salesforce.html

12. How to capture or create cases in Salesforce from a form in Company's website?
Web to Case feature can be used.
https://www.infallibletechie.com/2012/12/web-to-case-in-salesforce.html

13. How Case Management is handled in Salesforce?
https://www.infallibletechie.com/2014/12/case-management-in-salesforce.html

14. What feature in Salesforce can be used to send or assign agents bases on the Service Appointments and Work Orders?
Field Service Lightning can be used.
https://www.infallibletechie.com/2016/06/field-service-lightning-in-salesforce.html

15. What feature allows agents to automate things like Sending Emails, Post to social networks, Replace field values in a case, Insert Field values into a case, etc in Salesforce?

Macros can be used.
https://www.infallibletechie.com/2015/07/macros-in-salesforce.html

How to find Dashboards that are using a Report in Salesforce?

To find Report references in a Dashboard, use the following SOQL.

Sample SOQL:
 
SELECT Dashboard.Title
FROM DashboardComponent
WHERE CustomReportId = '00O8c000007uh5UEAQ'

Output:
 

How to display related records in Salesforce using Lightning Web Component?

lightning/uiRelatedListApi can be used to fetch the related records and display using Lightning Web Component. Since we use lightning/uiRelatedListApi, apex code is not required to fetch the related records. Check the sample code below:  

Sample Code:
HTML:

<template>
    <lightning-card>
        <div class="slds-m-around_medium">
            No of Contacts is {recordCount}<br/><br/>
            <lightning-datatable
                key-field="Id"
                data={records}
                columns={columns}
                hide-checkbox-column="true"
                show-row-number-column="true">
            </lightning-datatable>  
        </div>
    </lightning-card>
</template>

JavaScript:
import { LightningElement, wire, api } from 'lwc';
import { getRelatedListRecords } from 'lightning/uiRelatedListApi';
 
const COLUMNS = [   
    { label: 'Name', fieldName: 'Name' },
    { label: 'Email', fieldName: 'Email' }
];

export default class RelatedListComponent extends LightningElement {

    @api recordId;
    recordCount;
    records;
    columns = COLUMNS;

    @wire( getRelatedListRecords, {

        parentRecordId: '$recordId',
        relatedListId: 'Contacts',
        fields: [ 'Contact.Id', 'Contact.Name', 'Contact.Email' ]

    } )listInfo( { error, data } ) {

        if ( data ) {

            console.log( 'Data is', JSON.stringify( data ) );
            let tempRecords = [];

            data.records.forEach( obj => {

                console.log( 'obj is', JSON.stringify( obj ) );
                let tempRecord = {};
                tempRecord.Id = obj.fields.Id.value;
                tempRecord.Name = obj.fields.Name.value;
                tempRecord.Email = obj.fields.Email.value;
                tempRecords.push( tempRecord );

            } );

            this.records = tempRecords;
            this.recordCount = data.count;
            console.log( 'Records are ' + JSON.stringify( this.records ) );
            
        } else if (error) {
            
            this.records = undefined;

        }
    }

}

js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
            </objects>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>


Note:
I have configured the Lightning Web Component page in Account Lightning Record page.

Output:


How to sign up Salesforce Financial Services Cloud Developer Edition Org?

1. Open the following link.

2. Enter all the details and click "Sign me up" button.


Organization concurrent user limit exceeded Exception in Salesforce

Organization concurrent user limit exceeded Exception in Salesforce occurs due to "Maximum number of concurrent clients (subscribers) across all channels and for all event types" limit.
Check the limit as it depends on Edition using the following link
https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/limits.htm#free_orgs_limit_note2

Sample Code to check the Limit:
Map < String, System.OrgLimit > limitsMap = OrgLimits.getMap();
System.OrgLimit o = limitsMap.get( 'StreamingApiConcurrentClients' );
System.debug( o.getName() + ' - ' + o.getValue() + ' - ' + o.getLimit() );
o = limitsMap.get( 'DurableStreamingApiConcurrentClients' );
System.debug( o.getName() + ' - ' + o.getValue() + ' - ' + o.getLimit() );



How to find number of related records in Salesforce using Lightning Web Component?

lightning/uiRelatedListApi can be used to find number of related records using Lightning Web Component. Check the sample code below:
 
Sample Code:
HTML:

<template>
    <lightning-card>
        No of Contacts is {recordCount}
    </lightning-card>
</template>

JavaScript:
import { LightningElement, wire, api } from 'lwc';
import { getRelatedListCount } from 'lightning/uiRelatedListApi';

export default class RelatedListComponent extends LightningElement {

    @api recordId;
    recordCount;

    @wire( getRelatedListCount, {

        parentRecordId: '$recordId',
        relatedListId: 'Contacts'

    })listInfo( { error, data } ) {

        if ( data ) {

            console.log( 'Data is ' + JSON.stringify( data ) );
            this.recordCount = data.count;

        } else if ( error ) {
            
            console.log( 'Error occured', JSON.stringify( error ) );

        }

    }

}

js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
            </objects>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>


Output:
 

Salesforce and Xero Integration

Use the following steps for Salesforce and Xero integration.

1. Open the following link.
https://developer.xero.com/app/manage
 
Note:
If you don't have an account, sign up for a free trial.

2. Click New App.

3. Click Create App to create the App.

 
4. Open Configuration on the Left Panel.

 
5. Click Generate Secret.

6. Create Auth. Provider in Salesforce.
Authorize Endpoint URL: https://login.xero.com/identity/connect/authorize
Token Endpoint URL: https://identity.xero.com/connect/token

 
7. Get the Callback URL.

8. Update the Redirect URIs in Xero. Open Configuration on the Left Panel to see it.

9. Create Named Credential in Salesforce using the Auth. Provider.
Scope: offline_access accounting.settings openid profile email accounting.transactions accounting.transactions.read accounting.contacts
URL: https://api.xero.com

 
10. Enter the credentials to login into Xero.

11. Use the following code to test.
HTTPRequest request = new HTTPRequest();
request.setMethod( 'GET' );
request.setEndpoint( 'callout:Xero_Named_Credential/'+'connections' );
request.setHeader( 'Accept', 'application/json' );
request.setHeader( 'xero-tenant-id', '' );
HTTPResponse response = new HTTPResponse();
HTTP objHTTP = new HTTP();
response = objHTTP.send( request );
System.debug( 'Status Code is '+ response.getStatusCode() );
System.debug( 'Response Body is '+ response.getBody() );

Here Xero_Named_Credential is my Named Credential API Name.


Report on Total Views on Knowledge Article in Salesforce by External Users

1. Create a Custom Report Type.

2. Use Knowledge Articles as Primary object and Article View Statistics as the related object. 
 

3. Use the Custom Report Type and create the report. Set Channel to "Customer, Partner" in the Report filer.
 

How to report on Total Views on Knowledge Article in Salesforce?

1. Create a Custom Report Type.

2. Use Knowledge Articles as Primary object and Article View Statistics as the related object. 
 

3. Use the Custom Report Type and create the report. Set Channel to "All Channels" in the Report filer.
 

 

How to populate Account in Chat and Case from Experience Cloud Embedded Service Chat Component in Salesforce?

1. Create a file with the extension ".js" using the following code.

window._snapinsSnippetSettingsFile = ( function() {
    console.log( "Code from Static Resource loaded" );
    let chatAccNm = document.getElementById( "chatAccNm" ).innerHTML;
    console.log( 'Account Name - ' + chatAccNm );
    /* Pre-populating pre-chat form */
    embedded_svc.snippetSettingsFile.extraPrechatFormDetails  = [
        { "label":"Web Company", "value":chatAccNm, "displayToAgent":true }
    ];
    /* Linking Chat to Account to Case */           
    embedded_svc.snippetSettingsFile.extraPrechatInfo = [ {
        "entityName":"Account",
        "showOnCreate":true,
        "linkToEntityName":"Case",
        "linkToEntityField":"AccountId",
        "saveToTranscript":"AccountId",
        "entityFieldMaps": [ {
            "isExactMatch":true,
            "fieldName":"Name",
            "doCreate":false,
            "doFind":true,
            "label":"Web Company"
          } ]
    } ];
}
)();

2. Upload the File in Static Resource. Set Cache Control to Public. Copy the Static Resource Name.


3. Use the Static Resource Name in Snippet Settings File in Experience Cloud Builder's Embedded Service Chat Component Properties.


4. Create the following LWC Component for PreChat.

HTML:
<template>
    <lightning-card title="Prechat Form">   
        <template class="slds-m-around_medium" for:each={fields} for:item="field">
            <template if:true={field.showField} key={field.name}>
                <lightning-input
                    key={field.name}
                    name={field.name}
                    label={field.label}
                    value={field.value}
                    max-length={field.maxLength}
                    required={field.required}>
                </lightning-input>
            </template>
        </template>
    </lightning-card>
    <br/>
    <lightning-button
        label="Start Chat"
        title="Start Chat"
        onclick={handleStartChat}
        class="slds-m-left_x-small"
        variant="brand">
    </lightning-button>
</template>
 
JavaScript:
import BasePrechat from 'lightningsnapin/basePrechat';
import { api } from 'lwc';

export default class Prechat extends BasePrechat {

    @api prechatFields;
    fields;
    namelist;

    /**
     * Set the button label and prepare the prechat fields to be shown in the form.
     */
    connectedCallback() {
        
        this.fields = this.prechatFields.map( field => {
            console.log( 'Field is ', JSON.stringify( field ) );
            let showField = true;
            if ( field.label == 'Web Company' ) {
                showField = false;
            }
            const { label, name, value, required, maxLength } = field;
            return { label, value, name, required, maxLength, showField };
        });
        this.namelist = this.fields.map( field => field.name );

    }

    /**
     * On clicking the 'Start Chatting' button, send a chat request.
     */
    handleStartChat() {

        this.template.querySelectorAll( "lightning-input" ).forEach( input => {
            this.fields[ this.namelist.indexOf( input.name ) ].value = input.value;
        });
        console.log( 'Starting Chat' );
        this.startChat( this.fields );

    }

}
 
JS-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
  <isExposed>true</isExposed>
  <targets>
    <target>lightningSnapin__PreChat</target>
  </targets>
</LightningComponentBundle>


5. Configure the LWC as the Pre-Chat Component in Embedded Service Deployment.


6. Create the following Apex Class and Aura Component.
Apex Class:
public class PreChatValuesController {
    
    @AuraEnabled
    public static user fetchUserDetails() {
        
       User u = [ SELECT Id, FirstName, LastName, Email, Phone, Account.Name
                 FROM User
                 WHERE Id =: userInfo.getUserId() ];
       return u;
        
    }

}

Aura Component:
<aura:component implements="forceCommunity:availableForAllPageTypes" access="global" controller="PreChatValuesController">
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    <aura:attribute name="userInfo" type="user"/>     
    <div id="chatFName" hidden="true">
        {!v.userInfo.FirstName}
    </div>    
    <div id="chatLName" hidden="true">
        {!v.userInfo.LastName}
    </div>    
    <div id="chatEmail" hidden="true">
        {!v.userInfo.Email}
    </div>    
    <div id="chatPhone" hidden="true">
        {!v.userInfo.Phone}
    </div>    
    <div id="chatAccNm" hidden="true">
        {!v.userInfo.Account.Name}
    </div>   
</aura:component>

Aura Component JavaScript:
({
        
    doInit : function(component, event, helper) {
        
        let action = component.get( "c.fetchUserDetails" );
        action.setCallback( this, function( response ) {
            let state = response.getState();
            if ( state === "SUCCESS" ) {
                
                let userResponse = response.getReturnValue();
                console.log( 'userResponse is ', JSON.stringify( userResponse ) );
                if ( !userResponse.hasOwnProperty( 'Account' ) ) {
                    console.log( 'Internal User' );
                    userResponse = Object.assign( userResponse, { 'Account' : { 'Name':'' } } );
                }
                component.set( "v.userInfo", userResponse );
                
            }
        });
        $A.enqueueAction( action );
        
    }
    
})

 
7. Drag and Drop the Aura Component to the Experience Cloud Builder. Just above the Embedded Service Chat component.


8. Add Web Company field in the Embedded Service Deployment.
 
 
9. Publish the Experience Cloud and test it by initiating a Chat.
 
Process:
1. When the Site is loaded, the Aura Component will do the Apex Call and get the User details including Account Name.
 
2. When  the Chat is initiated, the JS file from Static Resource will load. As per the LWC, it will hide the Web Company field.

3. The JS file will get the Account Name from the Aura Component. It will search for account records based on the Account Name passed from the Aura component.

4. Matching Account will be linked to Chat Transcript and Case.

Note:
When an internal user tries to access the Site, the Account Name will be blank. So, the Case and Chat Transcript won't be linked to any Account.

How to avoid closing Parent Case when child(related) cases are still open in Salesforce?

Sample Trigger:

trigger CaseTrigger on Case ( before update ) {
    
    Set < Id > setCaseIds = new Set < Id >();
    Map < Id, Integer > mapOpenCaseCount = new Map < Id, Integer >();
    
    for ( Case objCase : trigger.new ) {
        
        if ( objCase.Status == 'Closed' ) {
        
            setCaseIds.add( objCase.Id );
        
        }
    
    }
    
    for ( Case objCase : [ SELECT ParentId FROM Case WHERE ParentId IN: setCaseIds AND IsClosed = false ] ) {
    
        if ( mapOpenCaseCount.containsKey( objCase.ParentId ) ) {
        
            mapOpenCaseCount.put( objCase.ParentId, mapOpenCaseCount.get( objCase.ParentId ) + 1 );
        
        } else {
        
            mapOpenCaseCount.put( objCase.ParentId, 1 );
        
        }
    
    }    
    
    
    for ( Case objCase : trigger.new ) {
    
        if ( objCase.Status == 'Closed' ) {
        
            if ( mapOpenCaseCount.containsKey( objCase.Id ) ) {
        
                objCase.addError( 'You cannot close this Case. It has ' + mapOpenCaseCount.get( objCase.Id ) + ' open Child Cases.' );
                
            }
        
        }
    
    }

}

Sample Case record with two open Child Cases
 

Trigger Valiation Error: