September 30, 2021

Salesforce System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, There's a problem with this state, even though it may appear correct. Please select a state from the list of valid states.:

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, There's a problem with this state, even though it may appear correct. Please select a state from the list of valid states.:

Code which causes the error:
Account objAcc = new Account();
objAcc.Name = 'Testing Account';
objAcc.BillingCountry = 'United States';
objAcc.BillingState = 'WA';
objAcc.BillingPostalCode = '54321';
insert objAcc;


State should not have abbreviation. Use Washington to resolve the issue.


Salesforce Interview Questions with Answers Part 68

1. Advantages of Queueable interface over Future method
a. It supports Non-Primitive Data types.
b. Chaining jobs: You can chain one job to another job by starting a second job from a running job. Chaining jobs is useful if you need to do some sequential processing.

2.'You have uncommitted work pending. Please commit or rollback before calling out' error 
Callouts are not allowed when there is an uncommitted transaction pending. For example, if a save point is set before a DML operation, a callout cannot be made based on the results of that operation to commit or roll back the save point.
You cannot perform a DML operation prior to a callout. All the DML operations should be invoked only after you are done with callouts. So, make a webservice callout first and then save the request.

3. What is the use of Crypto class in Salesorce?
Crypto Class provides methods for creating digests, message authentication codes, and signatures, as well as encrypting and decrypting information.

4. How to view LWC code unminified in Salesforce?
Go to Debug Mode in Setup and enable Debug Mode for the user..

5. Custom Formatters in Browser tool for LWC Inspection
Lightning web components use JavaScript proxies to enforce that certain types of data are read-only, primarily data that's provisioned via decorators (@api, @track, @wire). In Debug Mode, custom formatters manipulate the proxies into readable parts. Then in Chrome DevTools, you see the real value instead of the proxy. Let’s enable the custom formatters.

In DevTools, click Settings (settings icon). The Preferences page opens.
Under Console, select Enable custom formatters.

6. In outbound message, if endpoint is not available, message will be in queue for how many hour before it dropped?
If the endpoint is unavailable, messages stay in the queue until sent successfully or until they are 24 hours old. After 24 hours, messages are dropped from the queue. 

7.  What Is Process Mapping?  
Process mapping creates visual representations of business processes. It includes any activity that defines what a business does, who is responsible for what, how standard business processes are completed, and how success is measured. The main purpose of business process mapping is to show the relationship between the steps and the inputs of a business to establish a clear, consistent, and concise result. It takes a specific objective and compares that objective to the organization’s overall objectives to make sure their processes are aligned with the company’s values and capabilities.


8. What annotation is used when Flow calls Apex?
@InvocableMethod(

9. Salesforce Inbound API Limit
To maintain optimum performance and ensure that the Lightning Platform API is available to all our customers, Salesforce balances transaction loads by imposing two types of limits:
1. Concurrent API Request Limits
2. Total API Request Allocations

Concurrent API Request Limit is a request with running duration of 20 seconds or longer.

https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm

10. Use case for @track
There is still one use case for @track. When a field contains an object or an array, there’s a limit to the depth of changes that are tracked. To tell the framework to observe changes to the properties of an object or to the elements of an array, decorate the field with @track.

So, it is required for array and object.

11. How to Salesforce supported certificates?
To review a current list of supported certificates you can append /cacerts.jsp to any instance URL (Only Winter '19 Instances will work with this endpoint) - https://INSTANCE.salesforce.com/cacerts.jsp (replace 'INSTANCE' with any Winter'19 upgraded instance, e.g. https://cs32.salesforce.com/cacerts.jsp )

Reference Article - https://help.salesforce.com/s/articleView?id=000326722&type=1

12. Record Type assigned via Permission Set not working in Salesforce 
Default Record Types: 
A user’s default record type is specified in the user’s profile. Users can view their default record type and edit record type selection in personal settings. You can’t specify a default record type in permission sets.
 
Master Record Types:
In Profiles: You can assign the master record type in profiles, but you can’t include custom record types in the profile.
In Permission Sets:You can assign only custom record types in permission sets, not master record types.
 

13. UX design 
UX designis the practice of examining people’s needs and motivations to inform the design of the overall experience with a product or service.

14. ORDER BY Clause not returning consistent result in SOQL
Even if you use ORDER BY, the order of results can vary if there are duplicate values for the fields you’re using in the ORDER BY clause. Reference Article - https://developer.salesforce.com/docs/atlas.en-us.234.0.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_orderby.htm

15. Your query request was running for too long
[sf: QUERY_TIMEOUT]. Reason [QUERY_TIMEOUT: Your query request was running for too long.]

If the query runs more than 2 mins(120 seconds), the query times out and throw the exception.

Maximum SOQL query run time before Salesforce cancels the transaction is 120 seconds(2 minutes). Check the following reference article.
https://developer.salesforce.com/docs/atlas.en-us.232.0.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_apexgov.htm

Use "SOQL_EXECUTE_BEGIN" in the Debug Logs. Find the start time and the time of the exception. If it is 120 seconds, then optimize the query.

September 29, 2021

Muliple Account Ownership in Private Sharing Model in Salesforce

Account Teams can be used for Muliple Account Ownership in Private Sharing Model in Salesforce.

OWD Settings:

Enable Account Teams:

User from Line of Business 1:
a. Owner of Account.
b. Owner of One opportunity.


User from Line of Business 2:
a. Account Manager using Account Team. So, gets access to the Account.
b. Since Opportunity OWD is private, cannot see opportunities from other Line of Businesses.


September 27, 2021

Query(SOQL) Process Builder Salesforce

Use Tooling API to query. Get the Process Builder Name.


Sample SOQL:
SELECT Id, MasterLabel, Description, ProcessType, Status, CreatedDate, LastModifiedDate FROM Flow WHERE MasterLabel = 'Test Event Subscribing' 
 

403:denied_by_security_policy:create_denied Exception from Salesforce

You may receive the "403:denied_by_security_policy:create_denied" for the following reasons.

1. The Event or the channel you are trying to subscribe doesn't exist in the org. Check the username and check whether the Event or channel exists in the org.

2. Use the correct api name of the event.
Syntax:
/event/API_Name_Of_The_Event

Example:
/event/Test_Event__e

3. Check the Profile of the integration user. The profile should have Read and Create access to the Event or Channel.

September 26, 2021

How to detect URL Query Parameters Change in Salesforce Lightning Web Component(LWC)?

1. Create a simple Quick Action component.

HTML:
<template>
    
</template>

JavaScript:
import { LightningElement, api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class SampleQuickAction extends NavigationMixin( LightningElement ) {
    
    @api recordId;

    @api invoke() {

        this[NavigationMixin.Navigate]( {
            type: 'standard__navItemPage',
            attributes: {
                apiName: 'Sample_Tab'
            },
            state: {
                c__recId: this.recordId
            }
        } );

    }

}

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__RecordAction</target>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordAction">
            <actionType>Action</actionType>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>


2. Create a Quick Action using the above component.


3. Add the above Quick Action to the page layout.

4. Create a Lightning Web Component(LWC) for a Tab.

HTML:
<template>
    <lightning-card>
        <template if:true={recordBool}>
            {recId}
        </template>
        <template if:false={recordBool}>
            Record Id is not passed
        </template>
    </lightning-card>
</template>

JavaScript:
import { LightningElement, wire } from 'lwc';
import { CurrentPageReference } from 'lightning/navigation';

export default class SampleTab extends LightningElement {

    recordBool = false;
    recId;
    currentPageReference;
    
    @wire( CurrentPageReference )
    setCurrentPageReference( currentPageReference ) {

        this.currentPageReference = currentPageReference;
        let tempRecId = this.currentPageReference.state.c__recId;
        console.log( 'Rec Id is ' + tempRecId );

        if ( tempRecId ) {

            this.recordBool = true;
            this.recId = tempRecId;

        } else {

            this.recordBool = false;
            this.recId = undefined;

        }

    }
    
}

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__Tab</target>
    </targets>
</LightningComponentBundle> 
 
5. Create a tab for the above component.
 

 6. Add the above Tab to your App Navigation Items.
 
Output:
 

 Navigated from Account:
 

Clicking Sample Tab after navigating from Account(This removes the query parameter):
 

September 23, 2021

Queue and Public Group Assignments using Lightning Web Component (LWC) in Salesforce


Sample Code:

Apex:

public class QueueAssignmentController {

    @AuraEnabled( cacheable=true )
    public static QueuePublicGroupWrapper fetchQueueAssignments( String strUserId ) {
    
        QueuePublicGroupWrapper objQW = new QueuePublicGroupWrapper();
        Set < String > setAssignedQueueIds = new Set < String >();
        List < OptionWrapper > allQueues = new List < OptionWrapper >();
        Set < String > setAssignedPublicGroupIds = new Set < String >();
        List < OptionWrapper > allPublicGroups = new List < OptionWrapper >();
        Set < String > groupTypes = new Set < String > { 'Queue', 'Regular' };
        Set < Id > setGroupIds = new Set < Id >();
        
        for ( GroupMember objGM : [ SELECT Id, Group.Name, GroupId, Group.Type FROM GroupMember WHERE UserOrGroupId =: strUserId AND Group.Type IN: groupTypes ] ) {
            
            if ( objGM.Group.Type == 'Queue' ) {

                setAssignedQueueIds.add( objGM.GroupId );
                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGM.Group.Name;
                objOW.value = objGM.GroupId;
                allQueues.add( objOW );

            } else {

                setAssignedPublicGroupIds.add( objGM.GroupId );
                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGM.Group.Name;
                objOW.value = objGM.GroupId;
                allPublicGroups.add( objOW );

            }

            setGroupIds.add( objGM.GroupId );
        
        }
        
        for ( Group objGroup : [ SELECT Id, Name, Type FROM Group WHERE Id NOT IN:setGroupIds AND Type IN: groupTypes ] ) {
            
            if ( objGroup.Type == 'Queue' ) {

                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGroup.Name;
                objOW.value = objGroup.Id;
                allQueues.add( objOW );

            } else {

                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGroup.Name;
                objOW.value = objGroup.Id;
                allPublicGroups.add( objOW );

            }
        
        }
        
        objQW.availableQueues = allQueues;
        objQW.availablePublicGroups = allPublicGroups;
        objQW.selectedQueues = new List < String >();
        objQW.selectedPublicGroups = new List < String >();
        
        if ( setAssignedQueueIds.size() > 0 ) {

            objQW.selectedQueues.addAll( setAssignedQueueIds );

        }
        
        if ( setAssignedPublicGroupIds.size() > 0 ) {
            
            objQW.selectedPublicGroups.addAll( setAssignedPublicGroupIds );

        }
        
        return objQW;
    
    }
    
    @AuraEnabled
    public static String addRemoveQueues( String strUserId, List < String > selectedQueues, List < String > updatedQueues,
        List < String > selectedPublicGroups, List < String > updatedPublicGroups,
        Boolean queuesUpdatedBool, Boolean publicGroupsUpdatedBool
    ) {
    
        List < GroupMember > listGroupMembersForInsert = new List < GroupMember >();
        Set < String > setGroupIds = new Set < String >();
    
        try {
        
            Set < String > setSelectedQueues = new Set < String >();
            Set < String > setUpdatedQueues = new Set < String >();
            Set < String > setSelectedPublicGroups = new Set < String >();
            Set < String > setUpdatedPublicGroups = new Set < String >();
            setSelectedQueues.addAll( selectedQueues );
            setUpdatedQueues.addAll( updatedQueues );
            setSelectedPublicGroups.addAll( selectedPublicGroups );
            setUpdatedPublicGroups.addAll( updatedPublicGroups );
            
            if ( queuesUpdatedBool ) {
                for ( String strQueue : setUpdatedQueues ) {
                
                    if ( !setSelectedQueues.contains( strQueue ) ) {
                        
                        GroupMember objGM = new GroupMember();
                        objGM.UserOrGroupId = strUserId;
                        objGM.GroupId = strqueue;
                        listGroupMembersForInsert.add( objGM );
                        
                    }
                
                }
                
                for ( String strQueue : setSelectedQueues ) {
                
                    if ( !setUpdatedQueues.contains( strQueue ) ) {
                        
                        setGroupIds.add( strQueue );
                        
                    }
                
                }
        
            }

            if ( publicGroupsUpdatedBool ) {

                for ( String strPublicGroup : setUpdatedPublicGroups ) {
                
                    if ( !setSelectedPublicGroups.contains( strPublicGroup ) ) {
                        
                        GroupMember objGM = new GroupMember();
                        objGM.UserOrGroupId = strUserId;
                        objGM.GroupId = strPublicGroup;
                        listGroupMembersForInsert.add( objGM );
                        
                    }
                
                }

            }
            
            for ( String strPublicGroup : setSelectedPublicGroups ) {
            
                if ( !setUpdatedPublicGroups.contains( strPublicGroup ) ) {
                    
                    setGroupIds.add( strPublicGroup );
                    
                }
            
            }
            
            if ( setGroupIds.size() > 0 ) {
                
                delete [ SELECT Id FROM GroupMember WHERE UserOrGroupId =: strUserId AND GroupId IN: setGroupIds ];

            }
            
            if ( listGroupMembersForInsert.size() > 0 ) {
            
                insert listGroupMembersForInsert;
                
            }

            return 'Successful';
            
        
        } catch ( Exception e ) {
        
            throw new AuraHandledException( e.getMessage() );
            
        }
    
    }
    
    public class QueuePublicGroupWrapper {

        @AuraEnabled
        public List < OptionWrapper > availableQueues;
        @AuraEnabled
        public List < String > selectedQueues;
        @AuraEnabled
        public List < OptionWrapper > availablePublicGroups;
        @AuraEnabled
        public List < String > selectedPublicGroups;

    }

    public class OptionWrapper {

        @AuraEnabled
        public String value;
        @AuraEnabled
        public String label;

    }

}

HTML:
<template>
    <div class="slds-box slds-theme--default">
        <lightning-record-edit-form object-api-name="Account">
            <lightning-input-field field-name="User__c" onchange={handleUserChange}></lightning-input-field>
        </lightning-record-edit-form>
        <template if:true={showBool}>
            <lightning-card>
                <lightning-dual-listbox
                    label="Select/Remove Queues"
                    source-label="Available Queues"
                    selected-label="Selected Queues"
                    options={availableQueues}
                    value={selectedQueues}
                    onchange={handleQueuesChange}
                    class="slds-m-around_medium">
                </lightning-dual-listbox><br/><br/>
                <lightning-dual-listbox
                    label="Select/Remove Public Groups"
                    source-label="Available Public Groups"
                    selected-label="Selected Public Groups"
                    options={availablePublicGroups}
                    value={selectedPublicGroups}
                    onchange={handlePublicGroupsChange}
                    class="slds-m-around_medium">
                </lightning-dual-listbox>
                <p slot="footer">
                    <lightning-button
                        variant="brand"
                        label="Save"
                        onclick={saveChanges}
                        disabled={buttonBool}>
                    </lightning-button>
                </p>
            </lightning-card>    
        </template>
    </div>
</template>

JavaScript:
import { LightningElement } from 'lwc';
import fetchQueueAssignments from '@salesforce/apex/QueueAssignmentController.fetchQueueAssignments';
import addRemoveQueues from '@salesforce/apex/QueueAssignmentController.addRemoveQueues';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class QueueAssignment extends LightningElement {

    availableQueues;
    selectedQueues;
    updatedQueues;
    availablePublicGroups;
    selectedPublicGroups;
    updatedPublicGroups;
    showBool = false;
    buttonBool = false;
    userId;

    handleUserChange( event ) {

        let selectedUserId = event.target.value;
        console.log( 'Selected User Id is ' + selectedUserId );

        if ( selectedUserId ) {

            this.userId = selectedUserId;
            this.showBool = true;
            
        } else {

            this.showBool = false;

        }

        fetchQueueAssignments( { strUserId : this.userId } )
        .then( data => {

            console.log( 'Data ===> ' + data );
            console.log( 'Records are ' + JSON.stringify( data ) );
            this.availableQueues = data.availableQueues;
            this.selectedQueues = data.selectedQueues;
            this.updatedQueues = data.selectedQueues;
            this.availablePublicGroups = data.availablePublicGroups;
            this.selectedPublicGroups = data.selectedPublicGroups;
            this.updatedPublicGroups = data.selectedPublicGroups;

        })
        .catch( error => {

            this.dispatchEvent(
                new ShowToastEvent( {
                    title: 'Error!!',
                    message: 'Some error occured. Please reach out to your Salesforce Admin for help!',
                    variant: 'error',
                    mode: 'sticky'
                } ),
            );     

        } )

    }

    handleQueuesChange( event ) {

        const selectedOptionsList = event.detail.value;
        console.log( 'Selected Options are ' + JSON.stringify( selectedOptionsList ) );
        this.updatedQueues = selectedOptionsList;
        console.log( 'Updated Selected Queues are ' + JSON.stringify( this.selectedQueues ) );

    }

    handlePublicGroupsChange( event ) {

        const selectedOptionsList = event.detail.value;
        console.log( 'Selected Options are ' + JSON.stringify( selectedOptionsList ) );
        this.updatedPublicGroups = selectedOptionsList;
        console.log( 'Updated Selected Public Groups are ' + JSON.stringify( this.selectedPublicGroups ) );

    }

    saveChanges() {

        let queuesUpdatedBool = false;
        let publicGroupsUpdatedBool = false;

        console.log( 'selectedQueues is ' + JSON.stringify( this.selectedQueues ) );
        console.log( 'updatedQueues is ' + JSON.stringify( this.updatedQueues ) );
        console.log( 'selectedPublicGroups is ' + JSON.stringify( this.selectedPublicGroups ) );
        console.log( 'updatedPublicGroups is ' + JSON.stringify( this.updatedPublicGroups ) );

        if ( JSON.stringify( this.selectedQueues ) != JSON.stringify( this.updatedQueues ) ) {

            queuesUpdatedBool = true;

        }

        if ( JSON.stringify( this.selectedPublicGroups ) != JSON.stringify( this.updatedPublicGroups ) ) {

            publicGroupsUpdatedBool = true;

        }

        console.log( 'queuesUpdatedBool is ' + queuesUpdatedBool );
        console.log( 'queuesUpdatedBool is ' + publicGroupsUpdatedBool );

        if ( queuesUpdatedBool || publicGroupsUpdatedBool ) {
            
            addRemoveQueues( { strUserId : this.userId,
                selectedQueues : this.selectedQueues, updatedQueues : this.updatedQueues,
                selectedPublicGroups : this.selectedPublicGroups, updatedPublicGroups : this.updatedPublicGroups,
                queuesUpdatedBool : queuesUpdatedBool, publicGroupsUpdatedBool : publicGroupsUpdatedBool } )
            .then( result => {

                console.log( 'Result ' + JSON.stringify( result ) );
                let message;
                let variant;

                if ( result === 'Successful' ) {

                    message = 'Successfully Processed!';
                    variant = 'success';

                } else {

                    message = 'Some error occured. Please reach out to your Salesforce Admin for help!';
                    variant = 'error';
                    
                }

                const toastEvent = new ShowToastEvent( {

                    title: 'Queue(s) and Public Group(s) Assignment',
                    message: message,
                    variant: variant

                } );
                this.dispatchEvent( toastEvent );

            } )
            .catch( error => {

                console.log( 'Error ' + JSON.stringify( error ) );
                
            } );
            this.buttonBool = true;

        } else {

            alert( "No changes made!!!" );

        }
            
    }

}

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__Tab</target>
    </targets>
</LightningComponentBundle>


Output:



September 22, 2021

Queue Assignment using Lightning Web Component in Salesforce with lightning-dual-listbox or multipicklist

Sample code:
Apex Class:
public class QueueAssignmentController {

    @AuraEnabled( cacheable=true )
    public static QueueWrapper fetchQueueAssignments() {
    
        QueueWrapper objQW = new QueueWrapper();
        Set < String > setAssignedQueueIds = new Set < String >();
        List < QueueOptionWrapper > allGroups = new List < QueueOptionWrapper >();
        
        for ( GroupMember objGM : [ SELECT Id, Group.Name, GroupId FROM GroupMember WHERE UserOrGroupId =: UserInfo.getUserId() AND Group.Type = 'Queue' ] ) {
        
            setAssignedQueueIds.add( objGM.GroupId );
            QueueOptionWrapper objQOW = new QueueOptionWrapper();
            objQOW.label = objGM.Group.Name;
            objQOW.value = objGM.GroupId;
            allGroups.add( objQOW );
        
        }
        
        for ( Group objGroup : [ SELECT Id, Name FROM Group WHERE Type = 'Queue' AND Id NOT IN:setAssignedQueueIds  ] ) {
        
            QueueOptionWrapper objQOW = new QueueOptionWrapper();
            objQOW.label = objGroup.Name;
            objQOW.value = objGroup.Id;
            allGroups.add( objQOW );
        
        }
        
        objQW.availableQueues = allGroups;
        objQW.selectedQueues = new List < String >();
        
        if ( setAssignedQueueIds.size() > 0 )
            objQW.selectedQueues.addAll( setAssignedQueueIds );
        
        return objQW;
    
    }
    
    @AuraEnabled
    public static String addRemoveQueues( List < String > selectedQueues, List < String > updatedQueues ) {
    
        String strUserId = UserInfo.getUserId();
        List < GroupMember > listGroupMembersForInsert = new List < GroupMember >();
        Set < String > setGroupIds = new Set < String >();
    
        try {
        
            Set < String > setSelectedQueues = new Set < String >();
            Set < String > setUpdatedQueues = new Set < String >();
            setSelectedQueues.addAll( selectedQueues );
            setUpdatedQueues.addAll( updatedQueues );
            
            for ( String strQueue : setUpdatedQueues ) {
            
                if ( !setSelectedQueues.contains( strQueue ) ) {
                    
                    GroupMember objGM = new GroupMember();
                    objGM.UserOrGroupId = strUserId;
                    objGM.GroupId = strqueue;
                    listGroupMembersForInsert.add( objGM );
                    
                }
            
            }
            
            for ( String strQueue : setSelectedQueues ) {
            
                if ( !setUpdatedQueues.contains( strQueue ) ) {
                    
                    setGroupIds.add( strQueue );
                    
                }
            
            }
            
            if ( setGroupIds.size() > 0 ) {
                
                delete [ SELECT Id FROM GroupMember WHERE UserOrGroupId =: strUserId AND GroupId IN: setGroupIds ];
            }
            
            if ( listGroupMembersForInsert.size() > 0 ) {
            
                insert listGroupMembersForInsert;
                
            }

            return 'Successful';
            
        
        } catch ( Exception e ) {
        
            throw new AuraHandledException( e.getMessage() );
            
        }
    
    }
    
    public class QueueWrapper {

        @AuraEnabled
        public List < QueueOptionWrapper > availableQueues;
        @AuraEnabled
        public List < String > selectedQueues;

    }

    public class QueueOptionWrapper {

        @AuraEnabled
        public String value;
        @AuraEnabled
        public String label;

    }

}

HTML:
<template>
    <lightning-card>
        <lightning-dual-listbox
            label="Select/Remove Queues"
            source-label="Available Queues(s)"
            selected-label="Selected Queues(s)"
            options={availableQueues}
            value={selectedQueues}
            onchange={handleChange}
            class="slds-m-around_medium">
        </lightning-dual-listbox>
        <p slot="footer">
            <lightning-button
                variant="brand"
                label="Save"
                onclick={saveChanges}>
            </lightning-button>
        </p>
    </lightning-card>    
</template>

JavaScript:
import { LightningElement, wire } from 'lwc';
import fetchQueueAssignments from '@salesforce/apex/QueueAssignmentController.fetchQueueAssignments';
import addRemoveQueues from '@salesforce/apex/QueueAssignmentController.addRemoveQueues';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class QueueAssignment extends LightningElement {

    availableQueues;
    selectedQueues;
    updatedQueues;

    @wire( fetchQueueAssignments )  
    wiredRecs( { error, data } ) {

        if ( data ) {

            console.log( 'Records are ' + JSON.stringify( data ) );
            this.availableQueues = data.availableQueues;
            this.selectedQueues = data.selectedQueues;

        } else if ( error ) {

            console.log( 'Error ' + JSON.stringify( error ) );

        }
        
    }

    handleChange( event ) {

        const selectedOptionsList = event.detail.value;
        console.log( 'Selected Options are ' + JSON.stringify( selectedOptionsList ) );
        this.updatedQueues = selectedOptionsList;

    }

    saveChanges() {

        addRemoveQueues( { selectedQueues : this.selectedQueues, updatedQueues : this.updatedQueues } )
        .then( result => {

            console.log( 'Result ' + JSON.stringify( result ) );
            let message;
            let variant;

            if ( result === 'Successful' ) {

                message = 'Successfully Processed!';
                variant = 'success';

            } else {

                message = 'Some error occured. Please reach out to your Admin';
                variant = 'error';
                
            }

            const toastEvent = new ShowToastEvent( {

                title: 'Queue(s) Assignment',
                message: message,
                variant: variant

            } );
            this.dispatchEvent( toastEvent );

        } )
        .catch( error => {

            console.log( 'Error ' + JSON.stringify( error ) );
            
        } );
        this.selectedQueues = this.updatedQueues;
            
    }

}

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__Tab</target>
    </targets>
</LightningComponentBundle>
 
Output:
 

 
Note:
This works only for user assigned to queue. This is not work users assigned via Public Groups.

How to allow external users to be able to export reports in Salesforce?

To export report data, external users need "Export Reports" permission.


These permissions aren’t available to high-volume user licenses, such as Customer Community, High Volume Customer Portal, Service Cloud Portal, and Authenticated Website. Check the following link for addtiional Information.

September 21, 2021

How to reset lightning:recordEditForm and get also get record id in Salesforce?

Sample Code:
Component:
<aura:component implements="force:appHostable" >
    <lightning:card>
        <lightning:recordEditForm aura:id="recordEditForm" objectApiName="Lead" onsubmit="{!c.handleSubmit}" onsuccess="{!c.handleSuccess}">
            <lightning:messages />
            <lightning:inputField aura:id="field" fieldName="FirstName" />
            <lightning:inputField aura:id="field" fieldName="LastName" />
            <lightning:inputField aura:id="field" fieldName="Email" />
            <lightning:inputField aura:id="field" fieldName="Phone" />
            <lightning:inputField aura:id="field" fieldName="Company" />
            <lightning:button aura:id="myButton" variant="brand" label="Create Lead" type="submit"/>
            <lightning:button aura:id="myButton" variant="brand" label="Reset" onclick="{!c.handleReset}"/>
        </lightning:recordEditForm>
    </lightning:card>
</aura:component>

JavaScript Controller:
({
    
    handleSubmit: function ( component, event, helper ) {
        
        console.log( 'Inside Submit' );
        event.preventDefault();
        const fields = event.getParam( 'fields' );
        console.log( 'Fields are ' + JSON.stringify( fields ) );
        component.find( 'recordEditForm' ).submit( fields );
        
    }, 
    
    handleReset: function ( component, event, helper ) {
        
        component.find( 'field' ).forEach( function( f ) {
            f.reset();
        });
        
    }, 
    
    handleSuccess: function ( component, event, helper ) {
        
        let record = event.getParams();
        console.log( 'Created Lead is ' + JSON.stringify( record ) );
        console.log( 'Record Id is : ', record.response.id );
        let showToast = $A.get( "e.force:showToast" );
        showToast.setParams( {
            title : 'Lead Creation',
            message : 'Lead Submitted Sucessfully.' ,
            type : 'success',
            mode : 'sticky'
        } );
        showToast.fire();
    }
    
})

Output:


"Your org has too many waiting flow interviews" Exception in Salesforce

Exception:
Your org has too many waiting flow interviews, including processes that are waiting to execute groups of scheduled actions. Wait for some interviews to complete, or delete unneeded interviews.

https://help.salesforce.com/s/articleView?id=sf.process_limits_scheduled_processing.htm&type=5
An org can have up to 50,000 pending schedules and paused flow interviews at one time.

SELECT count() FROM FlowInterview WHERE InterviewStatus = 'Paused'
It should be less than 50000 to schedule another.

Also, check the following link for additional troubleshooting

September 20, 2021

How to pass parameter from Flow to Lightning Web Component(LWC) in Salesforce?

Sample Code:
HTML:
<template>
    <lightning-card>
        <lightning-record-view-form object-api-name="Account" record-id={accountId}>
            <lightning-output-field field-name="Name"></lightning-output-field>
            <lightning-output-field field-name="AccountNumber"></lightning-output-field>
            <lightning-output-field field-name="Type"></lightning-output-field>
            <lightning-output-field field-name="Industry"></lightning-output-field>
            <lightning-output-field field-name="Website"></lightning-output-field>
    </lightning-record-view-form>
    </lightning-card>
</template>

JS:
import { api, LightningElement } from 'lwc';

export default class FlowComponent extends LightningElement {
    
    @api accountId;

}

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__FlowScreen</target>
    </targets>
  <targetConfigs>
         <targetConfig targets="lightning__FlowScreen">
             <property name="accountId" label="Account Id" type="String" role="inputOnly"/>
         </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

Sample Flow:




Output:



September 19, 2021

How to get current logged user information using Lightning Web Component LWC in Salesforce?

Sample Code:

HTML:  
<template>
    <lightning-card title="User Details">
        <lightning-record-view-form object-api-name="User" record-id={userId}>
            <lightning-layout multiple-rows>
                <lightning-layout-item size="6" padding="around-small">
                    <lightning-output-field field-name="Name"></lightning-output-field>
                </lightning-layout-item>
                <lightning-layout-item size="6" padding="around-small">
                    <lightning-output-field field-name="CompanyName"></lightning-output-field>
                </lightning-layout-item>
                <lightning-layout-item size="6" padding="around-small">
                    <lightning-output-field field-name="IsActive"></lightning-output-field>
                </lightning-layout-item>
                <lightning-layout-item size="6" padding="around-small">
                    <lightning-output-field field-name="Alias"></lightning-output-field>
                </lightning-layout-item>
                <lightning-layout-item size="6" padding="around-small">
                    <lightning-output-field field-name="Title"></lightning-output-field>
                </lightning-layout-item>
            </lightning-layout>
        </lightning-record-view-form>
    </lightning-card>        
</template>

JavaScript:  
import { LightningElement } from 'lwc';
import USER_ID from '@salesforce/user/Id';

export default class UserDetails extends LightningElement {

    userId = USER_ID;

}

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__Tab</target>
    </targets>
</LightningComponentBundle>

Output: