Wednesday, December 16, 2020

Access Custom Metadata Type data without Using the SOQL in Salesforce

From Spring'21 onwards we can get the custom metadata record information without using the SOQL.

Demo:

For the demo, I created the Country and Amount(Country_And_Amount__mdt) Custom Metadata type object and records.

Country_And_Amount__mdt object.


Sample Code:

// Getting all metadata values 
Map<String, Country_And_Amount__mdt> mapValues = Country_And_Amount__mdt.getAll();

for(Country_And_Amount__mdt mdt : mapValues.values()) {
    System.debug('Name => '+mdt.Label);
    System.debug('DeveloperName => '+mdt.DeveloperName);
    System.debug('Amount__c => '+mdt.Amount__c);
}


// Getting metadata record based on value
Country_And_Amount__mdt objMdt = Country_And_Amount__mdt.getInstance('United_States');
System.debug('objMdt => '+objMdt);


Output:



Tuesday, December 15, 2020

Inline Editing in lightning-datatable in Salesforce Lightning Web Component(lwc)

 This post explains, inline editing in lightning-datatable in salesforce lightning web components(lwc).


HTML Code:

<template>
    <lightning-card title="Inline Edit With Lightning Datatable in LWC">
        <template if:true={contacts.data}>
            <lightning-datatable key-field="Id" 
                                 data={contacts.data} 
                                 columns={columns} 
                                 onsave={handleSave}
                                 draft-values={saveDraftValues} 
                                 hide-checkbox-column 
                                 show-row-number-column>
            </lightning-datatable>
        </template>
    </lightning-card>
</template>


Javascript Code:

import { LightningElement, wire, track } from 'lwc';
import getContacts from '@salesforce/apex/LWCExampleController.getContacts';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';
// datatable columns
const columns = [
    {
        label: 'Name',
        fieldName: 'Name',
        type: 'text',
    }, {
        label: 'FirstName',
        fieldName: 'FirstName',
        type: 'text',
        editable: true,
    }, {
        label: 'LastName',
        fieldName: 'LastName',
        type: 'text',
        editable: true,
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone',
        editable: true
    }
];

export default class InlineEditTable extends LightningElement {

    columns = columns;
    @track contacts;
    saveDraftValues = [];

    @wire(getContacts)
    cons(result) {
        this.contacts = result;
        if (result.error) {
            this.contacts = undefined;
        }
    };

    handleSave(event) {
        this.saveDraftValues = event.detail.draftValues;
        const recordInputs = this.saveDraftValues.slice().map(draft => {
            const fields = Object.assign({}, draft);
            return { fields };
        });

        // Updateing the records using the UiRecordAPi
        const promises = recordInputs.map(recordInput => updateRecord(recordInput));
        Promise.all(promises).then(res => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                    message: 'Records Updated Successfully!!',
                    variant: 'success'
                })
            );
            this.saveDraftValues = [];
            return this.refresh();
        }).catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error',
                    message: 'An Error Occured!!',
                    variant: 'error'
                })
            );
        }).finally(() => {
            this.saveDraftValues = [];
        });
    }

    // This function is used to refresh the table once data updated
    async refresh() {
        await refreshApex(this.contacts);
    }
}

Apex Code:

public inherited sharing class LWCExampleController {

    @AuraEnabled(Cacheable = true)
    public static List<Contact> getContacts() {
        return [SELECT Id, Name, FirstName, LastName, Phone, Email 
                FROM Contact 
                WHERE Email != null 
                AND Phone != null 
                ORDER BY CreatedDate DESC NULLS LAST limit 10];
    }
}


Output:



Tuesday, December 8, 2020

How to get object key prefix using apex in salesforce

This post explains how to get the object key prefix using apex in salesforce.

Below the code is to get the Account Key prefix.

Sample Code:

String strObjKeyPrefix  = Account.sobjecttype.getDescribe().getKeyPrefix();
system.debug('Key Prefix =>' +strObjKeyPrefix);
Output:



Monday, December 7, 2020

Hyperlink a Record in lightning-datatable in Lightning Web Components(lwc)

 This post explains how to add the Hyperlink to name in the lightning data table using Lightning web components(lwc).

Example:

HTML Code:

<template>
    <lightning-card title="Hyperlink to The Name in Lightning Datatable"><br/>
         <div if:true={consData}>
            <lightning-datatable data={consData} 
                                 columns={columns} 
                                 key-field="Id"
                                 hide-checkbox-column="true"></lightning-datatable>
        </div>
    </lightning-card>
</template>

Javascript Code:

import { LightningElement, wire, track } from 'lwc';
import getContacts from '@salesforce/apex/LWCExampleController.getContacts';


// datatable columns
const columns = [
    {
        label: 'Name',
        fieldName: 'ConName',
        type: 'url',
        typeAttributes: {label: { fieldName: 'Name' }, target: '_blank'}
    }, {
        label: 'FirstName',
        fieldName: 'FirstName',
        type: 'text',
    }, {
        label: 'LastName',
        fieldName: 'LastName',
        type: 'text',
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone'
    }
];

export default class HyperlinkNameInDatatable extends LightningElement {
    consData = [];
    columns = columns;

    @wire(getContacts)
    contacts({ error, data }) {

        if (data) {
            let tempConList = []; 
            
            data.forEach((record) => {
                let tempConRec = Object.assign({}, record);  
                tempConRec.ConName = '/' + tempConRec.Id;
                tempConList.push(tempConRec);
                
            });
            
            this.consData = tempConList;
            this.error = undefined;

            console.table(this.consData);

        } else if (error) {
            this.error = result.error;
        }
    }
}

Apex Code:

public inherited sharing class LWCExampleController {

    @AuraEnabled(Cacheable = true)
    public static List<Contact> getContacts() {
        return [SELECT Id, Name, FirstName, LastName, Phone, Email 
                FROM Contact 
                WHERE Email != null 
                AND Phone != null 
                ORDER BY CreatedDate DESC NULLS LAST limit 10];
    }
}

Result:



Sunday, December 6, 2020

Address Lookup in Lightning Web Components(LWC) using Google Maps Places API

To Enable the address lookup in lightning-input-address first we need to enable the permission for Maps and Location Settings in our salesforce org.

Note: 

Maps and Location Settings feature only available in Professional, Enterprise, Performance, and Unlimited editions.

Path:

From Setup, enter Maps in the Quick Find box, and then select Maps and Location Settings


Once the permission is enabled, we need to provide the show-address-lookup attribute to display the Address Lookup field.

Example:

<template>
   <lightning-card title="Address Lookup using Google Maps Places API">
      <lightning-input-address  address-label="Shipping Address"
         street-label="Street"
         city-label="City"
         country-label="Country"
         province-label="Province"
         postal-code-label="PostalCode"
         street="Default Street Line"
         city=""
         country=""
         province=""
         postal-code=""
         required
         field-level-help="Select Shipping Address"
         show-address-lookup>
      </lightning-input-address>
   </lightning-card>
</template>

Output:




Tuesday, December 1, 2020

Safe Navigation Operator – Avoid Null Pointer Exceptions

Safe Navigation Operator (?.) first evaluates the Left-Hand-Side of the chain expression. If it is NULL, the Right-Hand-Side is evaluated and returns NULL. We can use this operator in variable, method, and property chaining.

To use the Safe Navigation Operator, we just need to replace the dot (.) with “?.“.

For Example,  Account?.Type.

Example: 1

// Creating a NULL reference.
Account objAcc; 

// it throws Null Pointer Exception.
System.debug(objAcc.Type); 

// it prints the NULL because we used the safe operator
System.debug(objAcc?.Type); 

Example: 2


Without Safe Navigation Operator:

String str = 'Salesforce Code Crack';
if(!String.isEmpty(str)){
    System.debug(str.capitalize());
}

With Safe Navigation Operator:

String str = 'Salesforce Code Crack';
System.debug(str?.capitalize());

Example: 3


Without Safe Navigation Operator:

list<Account> lstAccs = [SELECT Type FROM Account WHERE Id='0013z00002TAEwaAAH'];
if(lstAccs != null && !lstAccs.isEmpty()){
    System.debug(lstAccs[0].Type);
}

With Safe Navigation Operator:

System.debug([SELECT Type FROM Account WHERE Id='0013z00002TAEwaAAH' LIMIT 1]?.Type);

References:

Tuesday, November 17, 2020

Salesforce Lightning button menu in Lightning Web component(lwc)

 Below is the sample button menu example to get the selected button menu value.

Example:

<template>
   <lightning-card title="Button Menu Example">
      <div class="slds-p-around_medium lgc-bg">
         <lightning-button-menu alternative-text="Show menu" icon-name="utility:settings" onselect={handleMenuItem}>
            <lightning-menu-item label="New" icon-name="utility:new" value="New"></lightning-menu-item>
            <lightning-menu-item label="Edit" icon-name="utility:edit" value="Edit"></lightning-menu-item>
            <lightning-menu-item label="Delete" icon-name="utility:delete" value="Delete"></lightning-menu-item>
         </lightning-button-menu>
      </div>
   </lightning-card>
</template>

JS Code:

import { LightningElement } from "lwc";

export default class App extends LightningElement {
  handleMenuItem(event) {
    console.log("selected menu => " + event.detail.value);
    switch (event.detail.value) {
      case "New":
        // do logic
        break;
      case "Edit":
        //do logic
        break;
      case "Delete":
        //do logic
        break;
    }
  }
}

Output:



Monday, November 16, 2020

WhatsApp Business + Salesforce + Chat on go

The need for customer interaction and management has been realized by businesses for a long time. The game has really changed with the advent of technology. Customers want to connect with businesses on readily available platforms that they are familiar with. And what easier way to fulfill this demand other than WhatsApp. With more than 1.5 billion users across 180 countries, WhatsApp is the leading messenger app in the world. So, it is no surprise that they launched WhatsApp Business to take advantage of the wide user base that they have. Another giant in the tech industry is the Salesforce CRM platform. It is a dominator in CRM with more than 150,000 users and 83% of market share among Fortune 500 companies. It is but natural to wonder how these two can be combined to create even more business value with better CRM.

In this blog, I will share my experience and findings for the implementation of WhatsApp business with Salesforce. 


Client Use Case


My client was a car dealership owner based in Italy. His company was selling cars of various brands from different store locations. They have a lot of inbound leads generated through WhatsApp from the website and we're looking for a solution to manage these contacts for their sales team. The issue was that the team was mostly in the stores busy with customer engagement and had limited accessibility to Salesforce on PC. The need was for a better way to connect with their customers through their mobile phones and simultaneously sync their chats with Salesforce.

My research  


After spending a lot of time in an attempt to find a solution like an application or API development services. I ended up reviewing lots of apps and attending 8 demos from different service providers like Screen Magic, SMS360, ValueText, and others. Here it would be good to state that the client was looking for a ready to use service. As a result, API integration service providers like Twilio and Nexmo were out of the question. This is because API integration has to be built from a scratch and takes a lot of time and investment which the client wasn’t ready for.

The Solutions and Findings


What is WhatsApp Business API


We are all familiar with WhatsApp personal and WhatsApp for Small Businesses. These are easily available on iOS and Android app stores. But they cannot be integrated with other business systems like Salesforce and other platforms.

Only WhatsApp business API is capable of integrating with the systems like Salesforce and any other platforms. The limitation of using WhatsApp Business API is that you can only configure one number with one WhatsApp service. This means that if you are already a WhatsApp Personal user, you cannot use the same number for WhatsApp Business.   

The Findings

After much effort, I narrowed down the ready-to-use application by ValueText.

ValueText has a functionality where you can chat from the phone and all chats can sync with Salesforce. This option helps sales teams to serve from their phones and sync chats with Salesforce. ValueText application is available on Android and iOS. Their ready-to-use application integrates WhatsApp with Salesforce, to allow business on the go! This lets you send WhatsApp messages to your customers directly from your phone.

ValueText was the clear winner in this case and here is some more information to prove that their application goes beyond mere integration. 

The ValueText Advantage

ValueText application brings a lot to the table in terms of features and functionality to provide a single platform for global messaging. 

1.       Easy to use

The app is extremely user friendly and easy to use. It has only two tabs that give all the functionality you need. One tab is for chats and the other one is for accessing Salesforce features. The chatting interface is similar to WhatsApp so it needs little time for the sales team to get familiar with it.

Find their website - https://valuetext.io/

Find them at AppExchange: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000EFoedUAD

Figure 2 – ValueText’s Simple User Interface

2       Accessibility

The chat window seamlessly connects with the Salesforce tab giving easy access to existing object data like contacts, leads, case, and other objects. This helps in searching Salesforce records and initiating chat on the go. 

3.    Multi-language support and International Messaging

With technology, the world has become a smaller place. Realizing the global needs of businesses, ValueText offers Multi-language support for messaging. It also lets you integrate with the messaging service of any country at local prices.

4.    Dynamic  Templates

ValueText offers mobile apps having dynamic templates. This allows users to access real-time data from Salesforce and helps them to create custom message templates to communicate with their customers. These templates can be easily accessed to initiate sessions.

5.     Powerful Salesforce app

The ValueText app has many features for Salesforce like one conversation on detailed record, WhatsApp web-like chat console, automation texting (workflow/process builder/flow/apex), texting from reports, appointment reminders, bots, inbound leads capture and creation, case management with WA, omnichannel support & drip campaigns. This ensures successful integration and robust functionality.

Conclusion

Needless to say, I successfully implemented the ValueText solution for my client across their different stores. ValueText enabled the use of its advanced features for quick and easy communication with customers. It is a single platform automated solution that leverages the advantages of messaging with the power of Salesforce to give you the best of both worlds.

Wednesday, November 4, 2020

Opportunity must have products to close the opportunity validation rule in salesforce

 Below validation rules fires when you are trying to close the opportunity without opportunity products.

Validation Rule:


AND (
CASE( StageName,
"Closed Won", 1,
0) = 1,
NOT(HasOpportunityLineItem)
)

Output:
Try to close the opportunity without products it will show an error message.





Wednesday, October 28, 2020

How to set CreatedDate field value for Test Class Records in Salesforce

We can now set the Created date field value for the test records in Salesforce test classes using setCreatedDate(Id recordId, Datetime createdDatetime) method. 

Note: Both recordId and DateTime parameters are required.

Example:

@isTest 
private class SetCreatedDateTest {
    static testMethod void testSetCreatedDate() {
        Account a = new Account(name='myAccount');
        insert a;
        Test.setCreatedDate(a.Id, DateTime.newInstance(2020,12,12));
        Test.startTest();
        Account myAccount = [SELECT Id, Name, CreatedDate FROM Account 
                             WHERE Name ='myAccount' limit 1];
        System.assertEquals(myAccount.CreatedDate, DateTime.newInstance(2020,12,12));
        Test.stopTest();
    }
}


Thursday, October 22, 2020

Auto Add Fields to Custom Report Types in salesforce

 From Winter 21 onwards we can auto-add, custom fields that you add to a Salesforce object are added automatically to all the custom report types based on that object. When you create a report from the custom report type, all the custom fields are right there for you to add to your report.

How to Enable:

Path:

From Setup, enter Reports & Dashboard Settings in the Quick Find box, and then Reports & Dashboard Settings

Enable the Auto add new custom fields to custom report type layouts



Monday, October 19, 2020

How to extract specific tags information from String using Apex in Salesforce

we can use the regular expression and utilize the Apex Pattern and Matcher classes.

Below is the generic regular expression to get the specific tags information from the HTML string.

Replace your tag and use it for your requirement.

(?i)<test([^>]+)>(.+?)</test>
Ex: 
(?i)<div([^>]+)>(.+?)</div>
Demo:
from the below string, I am extracting the a (anchor) tag information.

Sample Html String:

"We at <a href="https://www.linkedin.com/company/etg/" rel="noopener noreferrer" target="_blank">ETS, Inc.</a> are eager to share with you that we are a Strategic Solution Partner for the <a href="https://www.linkedin.com/company/commercecloud-demandware/" rel="noopener noreferrer" target="_blank">Salesforce Commerce Cloud</a>.<br>If you need any assistance with your <a href="https://www.linkedin.com/feed/hashtag/?keywords=ecommerce&amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6721841224095014912" rel="noopener noreferrer" target="_blank">#eCommerce</a> systems, let us know how we can help!"

From the above string, I am getting the anchor tag information.

Sample Code:
String strMessage = 'We at <a href="https://www.linkedin.com/company/etg/" rel="noopener noreferrer" target="_blank">ETS, Inc.</a> are eager to share with you that we are a Strategic Solution Partner for the <a href="https://www.linkedin.com/company/commercecloud-demandware/" rel="noopener noreferrer" target="_blank">Salesforce Commerce Cloud</a>.<br>If you need any assistance with your <a href="https://www.linkedin.com/feed/hashtag/?keywords=ecommerce&amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6721841224095014912" rel="noopener noreferrer" target="_blank">#eCommerce</a> systems, let us know how we can help!';

Pattern objPattren = Pattern.compile('(?i)<a([^>]+)>(.+?)</a>');
Matcher objMatcher = objPattren.matcher(strMessage);

while (objMatcher.find()) {
    String groupValue = objMatcher.group();
    System.debug('groupValue => '+groupValue);
}
Output:



Thursday, October 8, 2020

How to Query the Lookup Filter Information Using SOQL in Salesforce

 To Query the lookup filter information we can use the LookupFilter object.

Note: Select the Tooling API option when you querying the data

Example:

Select id, Active, IsOptional, DeveloperName, SourceObject, TargetEntityDefinition.DeveloperName, SourceFieldDefinitionId, SourceFieldDefinition.DeveloperName From lookupFilter
Result:


Sunday, October 4, 2020

How to check current user has a Custom Permission in Salesforce Using Apex?

To check the custom permission using Apex we can use the FeatureManagement class.

Demo:

Crate the custom permission


Sample Code:

Boolean bHasPermission = FeatureManagement.checkPermission('Test_Custom_Permission');
System.debug('has permission => '+bHasPermission);

Result:


Monday, September 7, 2020

How to get First day of the month using apex in salesforce

 Sample Code

System.debug('First Day ==> '+Date.today().toStartOfMonth());

Output

Thursday, September 3, 2020

Remove spaces from a string using apex in Salesforce

Use the deleteWhitespace() to remove spaces from a string in Salesforce.

Ex:

String str = 'Salesforce Code Crack';
system.debug(str.deleteWhitespace());
Output


Wednesday, August 26, 2020

Send Custom Notifications Using Apex in Salesforce

From Winter'21 onwards we can use the Messaging.CustomNotification class to create, configure, and send custom notifications directly from Apex code, such as a trigger.

Using Messaging.CustomNotification class to create and send custom notifications from Apex is easy. Create a new instance of CustomNotification, configure a few notification details, and call the send() method.

Example:

Before Customizing the Custom Notification you need to define custom notification type in notification types.
Path:
From Setup, enter Notification builder in the Quick Find box, and then Select Notification types


After creating the Notification type get the Id of the notification type Using SOQL

Use below SOQL Query to get the notification type Id.
SELECT Id, CustomNotifTypeName, DeveloperName from CustomNotificationType WHERE DeveloperName = '<Dev_Name>'

Note: Use Tooling API to Query


Apex Class

public inherited sharing class SendCustomNotification {
    
    
    public static void sendNotifications(String strBody, String strSenderId, String strTargetId, String strTitle, String strNotificationId, set<String> setUserIds) {
       
        Messaging.CustomNotification obj = new Messaging.CustomNotification();
        
        // Custom notification type Id
        obj.setNotificationTypeId(strNotificationId);
        
        // when we click on the notification it will redirect to the specified targetId
        obj.setTargetId(strTargetId);
        
        // Notification Title
        obj.setTitle(strTitle);
        
        // Notification Body
        obj.setBody(strBody);
        
        // send used to send the notification, pass the set of user ids , Group or Queue member
        obj.send(setUserIds);
    }
}

Sample test 

SendCustomNotification.sendNotifications('This is Test Body', '', userinfo.getUserId(), 'This is Test Message', '0MLB00000004CrSOAU', new set<String>{UserInfo.getUserId()});

Result