Validation Rule Requiring Lead Fields Prior to Conversion

In this post I am writing a validation rule that requires all of these fields prior to Lead conversion.

Need is a checkbox, Languages and propsepct role are picklists, Notes and SDR are text…

Below is the successful Formula that works for the above criteria:

Also, If the  Notes__c a Rich Text area field, then you need to use this:

 

If the above don’t work either, then check the following:
This Lead Settings should be checked in order for the Validation Rule to Fire.
Hope this information helps you!
– Chandra V [01/12/2019]

 

EINSTEIN ANALYTICS

In this Post, I would like to get the most important points on the Einstein Analytics to this Blog, through which one can understand it’s significance in improving the Business.

  1. Work with a platform you can trust
  2. Save on expenses
  3. Get set up quickly
  4. Cut out the fluff
  5. Customize your solution
  6. Enjoy built-in support
  7. Integrate your data
  8. Integrate with the entire Salesforce ecosystem
  9. Easily explore customer data from every source
  10. Bring your people together
  11. Unify your goals
  12. Collaborate from the dashboard
  13. Generate presentation-worthy visuals
  14. Be a part of the conversation
  15. Put it all into context
  16. Never be out of reach
  17. See team performance
  18. Access relevant KPIs
  19. Track call-center efficiency
  20. Chart changes
  21. Become a better coach
  22. Empower your teams to analyze themselves
  23. Eliminate the holes in your campaigns
  24. See the big picture
  25. Eliminate borders
  26. Find the devil in the details
  27. Predict the future
  28. Reduce churn
  29. Focus on the right leads
  30. Evaluate your lead sources
  31. Recognize your biggest wins
  32. Optimize the customer experience
  33. Dive deeper
  34. Present the right message
  35. Be your own data analyst
  36. Take instant action
  37. Make B2B marketing your speciality
  38. Understand the brand experience
  39. Set your priorities
  40. Evaluate your accounts
  41. Connect with your agents
  42. Review your service backlog
  43. Integrate with third-party applications
  44. Go mobile
  45. Optimize your pipelines
  46. Automate your analysis efforts
  47. Enjoy the highest level of data security
  48. Push the limits
  49. Gain deeper visibility into your business
  50. Keep up the pace                                                                                                                                                                                         – Sumanth A[01/04/19]

Field History Tracking on Custom Components

There is a limitation on the Field Tracking on the Quote Standard object in Salesforce.

This functionality is used when a custom application is built and want to track the history of the fields that are created
on the component.

In this scenario, I am tracking the Field History based on these criteria:

Date / Field / Original value / New Value / Type / Modified By

In the below scenario, Tracking the Custom Component Fields Based on two objects – Quote and Quote Line Item.

Lightning Component for Field History Tracking:

<aura:component controller=”QuoteAndQuoteLineItemHistory” implements=”force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction” access=”global” >
<!– HANDLERS –>
<aura:handler name=”init” action=”{!c.doInit}” value=”{!this}” />
<!– ATTRIBUTES –>
<aura:attribute name=”componentHistory” type=”List” />
<aura:attribute name=”componentHistoryFinalList” type=”List” />
<aura:attribute name=”searchText” type=”String”/>
<aura:attribute name=”headers” type=”List”/>
<aura:attribute type=”Boolean” name=”sortType” />

<aura:attribute name=”recordId” type=”Id” />
<aura:attribute name=”sortedBy” type=”String” default=”Name”/>
<aura:attribute name=”sortedDirection” type=”String” default=”asc”/>
<div class=”slds”>
<div class=”slds-grid slds-gutters”>
<div class=”slds-col slds-size_9-of-12″></div>
<div class=”slds-col slds-size_3-of-12″>
<lightning:input type=”text” name=”searchInput” onkeyup=”{!c.filterSelection}” value=”{!v.searchText}” aura:id=”searchInput” label=”Type here to search” />
<br/>
</div>
</div>

<lightning:datatable data=”{!v.componentHistory}”
columns=”{!v.headers}”
keyField=”Id”
hideCheckboxColumn=”true”
onsort=”{!c.updateColumnSorting}”
sortedBy=”{!v.sortedBy}”
sortedDirection=”{!v.sortedDirection}”/>
</div>
</aura:component>

This component also has the functionality of Sorting and Search feature.

Please comment and reach out for the Apex Class and related java scripts.

Chandra V [11/3/2018]

How to use Named credentials for Callouts (Integrations)

In the call outs or Integrations that we do from Salesforce to External Systems, we should pass the Endpoint URL and Password in the Header to hit the External System.

Using the Named Credentials we can Put these Endpoint URL and Password in a Label and can expose that label in the code.

Below are the Steps for Navigating to Named credentials:

Setup -> Type Named Credentials -> Setup the Named Credentials with all the details

 

This is considered as one of the best practices (Not exposing the URL and Password in the code)

Sumanth A [10/25/18]

Check for Empty strings in Java Script

Below is the code for checking the Empty Strings present in the Java Script

string str;

if(str != ‘undefined’ && str != null && str != ” && str != undefined && str != ‘null’ && str != ‘ ‘ && str.trim() != ”)
{
// if string is not empty do your logic

}
else // if string is empty
{
do your logic
}

Using this we can check the empty strings in JavaScript.

Sumanth A [10/25/18]

Notes and Attachments in Salesforce Lightning

Users may have noticed that Files under the Notes & Attachments related list don’t show up on the Account record when a user switches to Lightning Experience, however the same files are available when you switch back to Salesforce Classic.

Similarly, the same behavior can be observed when converting leads with attachments:

1. Create a Lead
2. Add a attachment to the lead [Newly added attachment shows up under the Notes & Attachments related list in Salesforce Classic]
3. Now convert the lead by creating a new account ‘or’ Add to an existing account
4. Open the newly created account in Salesforce Classic and you will see the attachment record created in Step 2
5. Switch over to Lightning Experience and navigate to the account, you will not see the attachment under the Notes & Attachment related list.

Note: Upload a File under the Notes & Attachments for a Lead record in Lightning Experience. When a lead is converted, the file will not get transferred to contact/account. The attachment in lightning experience is an action to upload a “File”. At the moment, Files don’t support the roll-up during lead conversion. Thus, the “Files” are not visible in contact/account.

 Apex Class :

public class AccountAttachmentsController {

@AuraEnabled
public static map<string,list<sObject>> getAllRelatedAttachments(string accountID){
set<id> parentIDs=new set<id>();
map<string,list<sObject>> mpAttachment=new map<string,list<sObject>>();
try{

Account objAccount=[select id,(select id from contacts),(select id from Orders),(select id from Cases),(select id from ActivityHistories ORDER BY ActivityDate DESC , LastModifiedDate DESC LIMIT 500),(select id from OpenActivities ORDER BY ActivityDate ASC , LastModifiedDate DESC LIMIT 500),(select id from Opportunities)
,(select id from Deliveries__r),(select id from Invoices__r)
from Account where id=:accountID];

if(objAccount!=null){
parentIDs.add(objAccount.id);

for(contact objContact: objAccount.contacts){
parentIDs.add(objContact.Id);
}

for(Case objCase: objAccount.Cases){
parentIDs.add(objCase.Id);
}

for(Order objOrder: objAccount.Orders){
parentIDs.add(objOrder.Id);
}

for(Opportunity objOpportunity: objAccount.Opportunities){
parentIDs.add(objOpportunity.Id);
}

for(ActivityHistory objTask: objAccount.ActivityHistories){

parentIDs.add(objTask.Id);
}

for(OpenActivity objTask: objAccount.OpenActivities){

parentIDs.add(objTask.Id);
}

for(Deliveries__c objDelivery: objAccount.Deliveries__r){
parentIDs.add(objDelivery.Id);
}

for(Invoice__c objInvoice: objAccount.Invoices__r){
parentIDs.add(objInvoice.Id);
}

}

if(parentIDs.size()>0){
system.debug(‘ParentIDS’+parentIDs);

mpAttachment.put(‘Attachment’,new list<attachment>([select id,Name,Body,BodyLength,ContentType,Description,
ParentId,Parent.Name,CreatedDate,LastModifiedDate,
LastModifiedById,LastModifiedBy.Name,CreatedById,CreatedBy.Name from attachment where ParentId in:parentIDs ORDER BY LastModifiedDate DESC]));
mpAttachment.put(‘File’,new list<ContentDocumentLink>([SELECT ContentDocumentId,LinkedEntityId,LinkedEntity.Name,ContentDocument.ContentAssetId,
ContentDocument.Title,ContentDocument.Description,
ContentDocument.FileType,
ContentDocument.CreatedDate,
ContentDocument.LastModifiedDate,
ContentDocument.LastModifiedBy.Name,
ContentDocument.LastModifiedById,ContentDocument.CreatedById,ContentDocument.CreatedBy.Name FROM ContentDocumentLink WHERE LinkedEntityId in :parentIDs ORDER BY ContentDocument.LastModifiedDate DESC]));

}

}catch(Exception ex){
throw new AuraHandledException(‘Error occurred: ‘ + ex.getMessage());
}
system.debug(mpAttachment.size());
return mpAttachment;
}

In my case, we have attachments that are related to child objects(Contacts, Cases, Orders, Opportunities, Activity History, Open Activities, Invoices, Deliveries). If you just want attachments that are related to any specific child object you can just query the same.

Helper Class :

({
getAllAttachments : function(component,event,helper) {
this.showSpinner(component);
var action = component.get(“c.getAllRelatedAttachments”);
action.setParams({
“accountID” : component.get(“v.recordId”)
});
action.setCallback(this, function(response) {
var state = response.getState();
if(state === “SUCCESS”){
let returnList=[];
console.log(response.getReturnValue());
let allAttachmentes=response.getReturnValue();
if(allAttachmentes!=undefined && allAttachmentes.length!=0){
if(allAttachmentes[‘Attachment’]!==undefined){
for(let i=0;i<allAttachmentes[‘Attachment’].length;i++){
returnList.push({“Id”:allAttachmentes[‘Attachment’][i][“Id”],
“name”:allAttachmentes[‘Attachment’][i][“Name”],
“relatedToName”:allAttachmentes[‘Attachment’][i].hasOwnProperty(“Parent”)?allAttachmentes[‘Attachment’][i][“Parent”].Name:’Task’,
“relatedToId”:allAttachmentes[‘Attachment’][i][“ParentId”],
“lastModifiedByName”:allAttachmentes[‘Attachment’][i][“LastModifiedBy”].Name,
“lastModifiedById”:allAttachmentes[‘Attachment’][i][“LastModifiedById”],
“LastModifiedDate”:allAttachmentes[‘Attachment’][i][“LastModifiedDate”],
“CreatedByName”:allAttachmentes[‘Attachment’][i][“CreatedBy”].Name,
“CreatedById”:allAttachmentes[‘Attachment’][i][“CreatedBy”].Id,
“Type”:”Attachment”,
“formatedDate”:this.formatDate(new Date(allAttachmentes[‘Attachment’][i][“LastModifiedDate”].substring(0,10)))
});
}
}
if(allAttachmentes[‘File’]!=undefined && allAttachmentes[‘File’].length!=0){
for(let i=0;i<allAttachmentes[‘File’].length;i++){
returnList.push({“Id”:allAttachmentes[‘File’][i][“ContentDocumentId”],
“name”:allAttachmentes[‘File’][i][“ContentDocument”].Title+(allAttachmentes[‘File’][i][“ContentDocument”].FileType!=’UNKNOWN’?’.’+allAttachmentes[‘File’][i][“ContentDocument”].FileType:”),
“relatedToName”:allAttachmentes[‘File’][i][“LinkedEntity”].Name,
“relatedToId”:allAttachmentes[‘File’][i][“LinkedEntityId”],
“lastModifiedByName”:allAttachmentes[‘File’][i][“ContentDocument”].LastModifiedBy.Name,
“lastModifiedById”:allAttachmentes[‘File’][i][“ContentDocument”].LastModifiedById,
“LastModifiedDate”:allAttachmentes[‘File’][i][“ContentDocument”].LastModifiedDate,
“CreatedByName”:allAttachmentes[‘File’][i][“ContentDocument”].CreatedBy.Name,
“CreatedById”:allAttachmentes[‘File’][i][“ContentDocument”].CreatedBy.Id,
“Type”:”File”,
“formatedDate”:this.formatDate(new Date(allAttachmentes[‘File’][i][“ContentDocument”].LastModifiedDate.substring(0,10)))
});
}
}
console.log(returnList);
component.set(“v.relatedAttachments”,returnList);
component.set(“v.relatedAttachmentsFinalList”,returnList);
component.set(“v.start”,0);
this.createMapFromList(component,event,helper);
}
this.hideSpinner(component);
}else if (state === “ERROR”) {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
$A.get(“e.force:showToast”).setParams({
“title”: “ERROR”,
“message”: “Error message: ” + errors[0].message,
“type”: “error”
}).fire();
}
} else {

$A.get(“e.force:showToast”).setParams({
“title”: “ERROR”,
“message”: “Unknown error”,
“type”: “error”
}).fire();
}
}
});
$A.enqueueAction(action);
},

Note : Hope this should really solve the issue. If not, please get in touch with me:  Yeshas@salesforcefactory.com

–  Yeshas Konduru [10/11/18]