You need to sign in to do that
Don't have an account?
Formula to calculate the number of working days between 2 dates
IF(AND((5 - (CASE(MOD( Start_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 5, 2, 5, 3, 4, 4, 3, 5, 2, 6, 1, 0)) < (CASE(MOD( End_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 0)) ),
((( End_Date__c - Start_Date__c ) + 1) < 7)),
((CASE(MOD( End_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 0)) - (5 - (CASE(MOD( Start_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 5, 2, 5, 3, 4, 4, 3, 5, 2, 6, 1, 0)))),
(((FLOOR((( End_Date__c - Start_Date__c ) - (CASE(MOD( Start_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 6, 2, 5, 3, 4, 4, 3, 5, 2, 6, 1, 0))) / 7)) * 5) +
(CASE(MOD( Start_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 5, 2, 5, 3, 4, 4, 3, 5, 2, 6, 1, 0)) +
(CASE(MOD( End_Date__c - DATE(1900, 1, 6), 7), 0, 0, 1, 0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 0))))
The Start Date and End Date fields are custom in the above example and can be replaced as required. If use of a DateTime field is required then the DATEVALUE function will be required.
I also recommend a simple field validation rule is added to check that the End Date is after the Start Date.
Accounts plotted on Google Map with Lightning Component
I describe the codes below and hope anyone can help with the test code part. Thank you!
Component (MapNearbyAccount.cmp)
<aura:component controller="MapNearbyAccountController" implements="flexipage:availableForAllPageTypes,force:hasRecordId"> <aura:attribute name="mapMarkers" type="Object"/> <aura:attribute name="selectedMarkerValue" type="String" /> <aura:handler name="init" value="{! this }" action="{! c.init }"/> <div class="slds-box slds-theme--default"> <lightning:map mapMarkers="{! v.mapMarkers }" selectedMarkerValue="{!v.selectedMarkerValue}" markersTitle="accounts nearby" listView="auto" showFooter="false" onmarkerselect="{!c.handlerMarkerSelect}" /> </div> </aura:component>Controller (MapNearbyAccount.js)
({ init: function (cmp, event, helper) { var recordId = cmp.get("v.recordId"); var action = cmp.get("c.getAccounts"); action.setParams({recordId :recordId}); cmp.set('v.mapMarkers', [{location: {}}]); action.setCallback(this, function(response){ var accounts = response.getReturnValue(); var markers = []; for(var i = 0; i < accounts.length; i++){ var acc = accounts[i]; markers.push({ location: { Country : acc.BillingCountry, State : acc.BillingState, City: acc.BillingCity, Street: acc.BillingStreet }, icon : "standard:account", value: acc.Id, title: acc.Name, description:acc.Description }); } if(markers.length != 0){ cmp.set('v.mapMarkers', markers); } }); $A.enqueueAction(action); }, handlerMarkerSelect: function (cmp, event, helper) { console.log(event.getParam("selectedMarkerValue")); } });ApexClass (MapNearbyAccountController)
public class MapNearbyAccountController { @AuraEnabled public static List<Account> getAccounts(String BillingCity, String BillingState, String recordId){ Account acct = [SELECT Id, Name, BillingCountry, BillingState, BillingCity, BillingStreet, Industry FROM Account WHERE Id =:recordId]; return [SELECT Id, Name, BillingCountry, BillingState, BillingCity, BillingStreet,Description FROM Account WHERE BillingState = :acct.BillingState AND BillingCity LIKE :('%' + acct.BillingCity + '%') AND Industry = :acct.Industry LIMIT 10]; } }TestClass
@isTest public class MapNearbyAccountControllerTest { @isTest static void testMapNearbyAccountController() { Account acc1 = new Account(); acc1.Name='acc1'; acc1.BillingCity='Shibuya'; acc1.BillingState='Tokyo'; insert acc1; MapNearbyAccountController ctrl = new MapNearbyAccountController(); Test.startTest(); List<Account> getAccounts = ctrl.getAccounts(); System.assertEquals(false,getAccounts.isEmpty()); Test.stopTest(); } }

Please use the below test class:
@isTest public class MapNearbyAccountControllerTest { @isTest static void testMapNearbyAccountController() { Account acc1 = new Account(); acc1.Name='acc1'; acc1.BillingCity='Shibuya'; acc1.BillingState='Tokyo'; insert acc1; Test.startTest(); List<Account> getAccounts = MapNearbyAccountController.getAccounts('Shibuya','Tokyo',acc1.Id); System.assertEquals(false,getAccounts.isEmpty()); Test.stopTest(); } }
Thanks,
Maharajan.C

Dynamically add/remove rows for a table in LWC
I am facing issue with save & delete records. How I can solve this? Can anyone give me some guidence to solve.
dynamicAddRow.html <template> <div class="slds-m-around--xx-large"> <div class="slds-float_right slds-p-bottom_small"> <h1 class="slds-page-header__title">Add Row <lightning-button-icon icon-name="utility:add" size="large" variant="bare" alternative-text="Add" onclick={addRow}> </lightning-button-icon> </h1> </div> <div class="container-fluid"> <table class="slds-table slds-table_bordered slds-table_cell-buffer"> <thead> <tr class="slds-text-title_caps"> <th scope="col"> <div class="slds-truncate">#</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Name">Account Name</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Number">Account Number</div> </th> <th scope="col"> <div class="slds-truncate" title="Phone">Phone</div> </th> <th scope="col"> <div class="slds-truncate" title="Action">Action</div> </th> </tr> </thead> <tbody> <template for:each={accountList} for:item="acc" for:index="index"> <tr key={acc.Id}> <td>{index}</td> <td> <lightning-input label="Name" value={acc.Name} onchange={handleNameChange}></lightning-input> </td> <td> <lightning-input label="Account Number" value={acc.AccountNumber} onchange={handleAccountNumberChange}></lightning-input> </td> <td> <lightning-input label="Phone" value={acc.Phone} onchange={handlePhoneChange}></lightning-input> </td> <td> <a onclick={removeRow}> <lightning-icon icon-name="utility:delete" size="small" style="margin-top: -4px; margin-right: 0px;" ></lightning-icon> <span class="slds-assistive-text">Delete</span> </a> </td> </tr> </template> </tbody> </table> <div class="slds-align_absolute-center slds-p-top_small"> <lightning-button name="Save" label="Save" onclick={saveRecord} ></lightning-button> </div> </div> </div> </template>
dynamicAddRow.js import { LightningElement, track,api } from 'lwc'; import ACCOUNT_OBJECT from '@salesforce/schema/Account'; import NAME_FIELD from '@salesforce/schema/Account.Name'; import ACCOUNTNUMBER_FIELD from '@salesforce/schema/Account.AccountNumber'; import PHONE_FIELD from '@salesforce/schema/Account.Phone'; import saveAccounts from '@salesforce/apex/AccountController.saveAccounts'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; export default class CreateDynamicRecord extends LightningElement { @track accountList = []; @track index = 0; @api recordId; @track name = NAME_FIELD; @track industry = ACCOUNTNUMBER_FIELD; @track phone = PHONE_FIELD; @api record = { firstName : '', lastName : '', Email : '', Phone : '', Title : '' } addRow(){ this.index++; this.accountList.push ({ sobjectType: 'Account', Name: '', AccountNumber : '', Phone: '' }); console.log('Enter ',this.accountList); // this.accountList.push(this.record); //console.log(' After adding Record List ', this.accountList); } removeRow(){ var index = this.index; if(this.accountList.length>1) this.accountList.splice(index, 1); //this.dispatchEvent(new CustomEvent('deleterow', {detail: this.index})); //console.log(' After adding Record List ', this.dispatchEvent); } acc = { Name : this.name, AccountNumber : this.accNumber, Phone : this.phone } handleNameChange(event) { this.acc.Name = event.target.value; console.log("name", this.acc.Name); } handleAccountNumberChange(event) { this.acc.AccountNumber = event.target.value; console.log("AccountNumber", this.acc.AccountNumber); } handlePhoneChange(event) { this.acc.Phone = event.target.value; console.log("Phone", this.acc.Phone); } saveRecord(){ saveAccounts(this.acc.accountList) .then(result => { this.message = result; this.error = undefined; if(this.message !== undefined) { this.acc.Name = ''; this.acc.AccountNumber = ''; this.acc.Phone = ''; this.dispatchEvent( new ShowToastEvent({ title: 'Success', message: 'Account created successfully', variant: 'success', }), ); } console.log(JSON.stringify(result)); console.log("result", this.message); /*console.log(' After adding Record List ', result); this.accountList = result; console.log(' After adding Record List ', this.accountList);*/ }) .catch(error => { this.message = undefined; this.error = error; this.dispatchEvent( new ShowToastEvent({ title: 'Error creating record', message: error.body.message, variant: 'error', }), ); console.log("error", JSON.stringify(this.error)); }); } }
AccountController.apex public with sharing class AccountController { @AuraEnabled( cacheable = true ) public static List< Account > getAccounts() { return [ SELECT Id, Name, Industry FROM Account LIMIT 10 ]; } @AuraEnabled( cacheable = true ) public static void saveAccounts(List<Account> accList){ Insert accList; /*if(accList.size()>0 && accList != null){ insert accList; }*/ } }Thanks
Siva

Please refer below code:
html: <template> <div if:true={isLoaded} class="cstm-spinner"> <lightning-spinner alternative-text="Loading..."></lightning-spinner> </div> <div class="slds-m-around--xx-large container-fluid"> <div class="slds-float_right slds-p-bottom_small"> <h1 class="slds-page-header__title">Add Row <lightning-button-icon icon-name="utility:add" size="large" variant="bare" alternative-text="Add" onclick={addRow}> </lightning-button-icon> </h1> </div> <div class="container-fluid"> <table class="slds-table slds-table_bordered slds-table_cell-buffer"> <thead> <tr class="slds-text-title_caps"> <th scope="col"> <div class="slds-truncate">#</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Name">Account Name</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Number">Account Number</div> </th> <th scope="col"> <div class="slds-truncate" title="Phone">Phone</div> </th> <th scope="col"> <div class="slds-truncate" title="Action">Action</div> </th> </tr> </thead> <tbody> <template for:each={accountList} for:item="acc" for:index="indx"> <tr key={acc.key} id={acc.key}> <td>{indx}</td> <td> <lightning-input data-id={indx} label="Name" value={acc.Name} onchange={handleNameChange}></lightning-input> </td> <td> <lightning-input data-id={indx} label="Account Number" value={acc.AccountNumber} onchange={handleAccountNumberChange}></lightning-input> </td> <td> <lightning-input data-id={indx} label="Phone" value={acc.Phone} onchange={handlePhoneChange}></lightning-input> </td> <td> <lightning-button-icon icon-name="utility:delete" data-id={indx} alternative-text="Delete" class="slds-m-left_xx-small" onclick={removeRow} title="Delete"></lightning-button-icon> </td> </tr> </template> </tbody> </table> <div class="slds-align_absolute-center slds-p-top_small"> <lightning-button name="Save" label="Save" onclick={saveRecord} ></lightning-button> </div> </div> </div> </template>
js : import { LightningElement, track,api } from 'lwc'; import ACCOUNT_OBJECT from '@salesforce/schema/Account'; import NAME_FIELD from '@salesforce/schema/Account.Name'; import ACCOUNTNUMBER_FIELD from '@salesforce/schema/Account.AccountNumber'; import PHONE_FIELD from '@salesforce/schema/Account.Phone'; import saveAccounts from '@salesforce/apex/AccountController.saveAccounts'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; export default class CreateDynamicRecord extends LightningElement { @track accountList = []; @track index = 0; @api recordId; @track name = NAME_FIELD; @track accNumber = ACCOUNTNUMBER_FIELD; @track phone = PHONE_FIELD; isLoaded = false; @api record = { firstName : '', lastName : '', Email : '', Phone : '', Title : '' } acc = { Name : this.name, AccountNumber : this.accNumber, Phone : this.phone ? this.phone : "", key : '' } addRow(){ this.index++; //var i = JSON.parse(JSON.stringify(this.index)); var i = this.index; /*this.accountList.push ({ sobjectType: 'Account', Name: '', AccountNumber : '', Phone: '', key : i });*/ this.acc.key = i; this.accountList.push(JSON.parse(JSON.stringify(this.acc))); console.log('Enter ',this.accountList); // this.accountList.push(this.record); //console.log(' After adding Record List ', this.accountList); } removeRow(event){ this.isLoaded = true; var selectedRow = event.currentTarget; var key = selectedRow.dataset.id; if(this.accountList.length>1){ this.accountList.splice(key, 1); this.index--; this.isLoaded = false; }else if(this.accountList.length == 1){ this.accountList = []; this.index = 0; this.isLoaded = false; } //this.dispatchEvent(new CustomEvent('deleterow', {detail: this.index})); //console.log(' After adding Record List ', this.dispatchEvent); } handleNameChange(event) { var selectedRow = event.currentTarget; var key = selectedRow.dataset.id; var accountVar = this.accountList[key]; this.accountList[key].Name = event.target.value; //this.acc.Name = event.target.value; //console.log("name", this.acc.Name); } handleAccountNumberChange(event) { /*this.acc.AccountNumber = event.target.value; console.log("AccountNumber", this.acc.AccountNumber);*/ var selectedRow = event.currentTarget; var key = selectedRow.dataset.id; var accountVar = this.accountList[key]; this.accountList[key].AccountNumber = event.target.value; } handlePhoneChange(event) { /*this.acc.Phone = event.target.value; console.log("Phone", this.acc.Phone);*/ var selectedRow = event.currentTarget; var key = selectedRow.dataset.id; var accountVar = this.accountList[key]; this.accountList[key].Phone = event.target.value; } saveRecord(){ saveAccounts({accList : this.accountList}) .then(result => { this.message = result; this.error = undefined; if(this.message !== undefined) { this.acc.Name = ''; this.acc.AccountNumber = ''; this.acc.Phone = ''; this.dispatchEvent( new ShowToastEvent({ title: 'Success', message: 'Account created successfully', variant: 'success', }), ); } console.log(JSON.stringify(result)); console.log("result", this.message); /*console.log(' After adding Record List ', result); this.accountList = result; console.log(' After adding Record List ', this.accountList);*/ }) .catch(error => { this.message = undefined; this.error = error; this.dispatchEvent( new ShowToastEvent({ title: 'Error creating record', message: error.body.message, variant: 'error', }), ); console.log("error", JSON.stringify(this.error)); }); } }
AccountController.apex public with sharing class AccountController { @AuraEnabled( cacheable = true ) public static List< Account > getAccounts() { return [ SELECT Id, Name, Industry FROM Account LIMIT 10 ]; } //( cacheable = true ) doesn't support DML operations @AuraEnabled public static void saveAccounts(List<Account> accList){ Insert accList; /*if(accList.size()>0 && accList != null){ insert accList; }*/ } }

How Batch process works during the Error.
1. Assume a batch process has 3 iterations processing 200 records each. The batch process is doing an insert and I am using Database.Insert with AllorNone parameter set to False. Assume there was an error during the second iteration while processing 101 record.I understand that all the records in the first iteration will be committed and also the 100 records in the second iteration. My question is will the batch process continue to process other records in the second iteration and also the third iteration.
2. Assume all the 3 iterations (execute method) completed without any error but some error occured in the Finish method. Finish method just sends an email. How does this work, considering that I am using Database.Insert and AllorNone parameter set to False. My understanding is that all the records will be committed to the database but user will not be receiving email that the batch was successfull or not. I am confused how this scenario will work in the real time.

1. OK. The first execute method successfully processed records, and this records committed to the database.
The second execute method successfully processed too, because of the "Database.Insert" method without the AllOrNone parameter is not throwing an exception. This method returns the list of SaveResults records. It means that successfully inserted only 199 records(1 fail #101).
But if you use the insert method or the Database.insert with AllOrNone parameter the second execute method failed, and all inserted/updated records in the second "execute" method will be rollback. And exceptions did not stop process "execute" method; this means that after an exception in the second batch execute method; the third batch "execute" method will process.
2. You are right. The start, execute and finish methods process in an asynchronous mode, and if the finish method failed, no an email message received. After each successfully processed "execute" methods, all records will have to be committed to the database.
Thanks,
Alex

Launch flow from account list view
The Flow is to create account and related contact records and it needs to happen only through a flow, as the customer wants point and click customization.
So far, I have only been able to launch the flow from within a record- by adding the action on the account page layout. However, my requirement is to launch the flow from the Account List View itself and not requiring the user to first have to select any other record. I have also tried creating a VF page to launch the flow from.
The issue that I am running into is
1- I do NOT see 'List View' as an option when I navigate to 'Search Layouts' on the Account Object and the 'Default Layout' does not have the custom button that I created
Default Layout- supports only buttons that create or update a record
2- I do see 'List View' listed when I navigate TO 'Search Layouts for Salesforce Classic' on the Account Object, however, the button to launch flow still does not show up under custom buttons and the only buttons that show up are related to either creating/updating a record. Also, I am sure if seeing the button to launch a flow under Search Layouts for Salesforce Classic would do me any good as I am working in Lightning
Direction on how to proceed ahead is greatly appreciated. Thank you in advance!


My colleague @Maruthy Jakkam helped me solve this as follows-
There are 2 ways to go about it-
1- Using 'List Button' with content source as URL from 'Buttons, Links, and Actions' on Account object and add it to the custom button section for 'List View' layout under the 'Search Layouts for Salesforce Classic' as follows-
Fetch Flow URL:
Create Custom List Button:
Add it to List View layout:
2- Second approach is to call embed the flow in a visualforce page and call it using a List Button as follows:
<apex:page standardController="Account" recordSetVar="sobjects">
<flow:interview name="Account_and_Contact_Creation_77946">
</flow:interview>
</apex:page>
Note: it is imperative to set the standardController and recordSetVar, otherwise, the vf page would not show up for list buttons.
@Shirisha- I had already exhausted all the resouces before posting it to the community and that video was one of those. It unfortunately does not solve the problem, but thank you for your help!
Replace Embedded Service Chat Text with Image
I'm setting up Embedded Services Chat. Is there a way to override the
embedded.svc.settings
parameters so that instead of text being displayed, an icon is displayed instead? For example, instead of
embedded.svc.settings.defaultMinimizedText
we would have
embedded.svc.settings.defaultMinimizedImage
. I've looked in the documentation and don't see any parameters like this, so would we have to build a LWC to override the default
.embeddedServiceHelpButton
?

Thanks, @Abhishek. It turns out that I was able to do this via styling. For anyone who has a similar issue, here is the styling that worked for me:
<style type='text/css'> .embeddedServiceHelpButton .helpButton .uiButton { background-color: #FFA400; border-radius: 50%; min-width: 5em; margin: 0 15px 15px 0; } .embeddedServiceHelpButton .helpButton .uiButton:focus { outline: 1px solid #FFA400; border-radius: 50%; min-width: 5em; } .embeddedServiceHelpButton .helpButton { margin: 0 15px 25px 0; } .embeddedServiceHelpButton .helpButton .uiButton .embeddedServiceIcon { margin: auto; } .embeddedServiceHelpButton .embeddedServiceIcon::before { font-size: 2.5em; } .embeddedServiceHelpButton .helpButton .uiButton .helpButtonLabel { display: none; } .embeddedServiceLiveAgentStateChatAvatar.isLightningOutContext .agentIconColor0 { background-color: #84bd00; } </style>Image attached for reference.
How to create a "Related to" picklist lookup field
Step1: Picklist with the Objects
Step2: On select of any one object, need to display all related records
Give me quick suggestion.
Thakns Niraj

Create a picklist fields with available object names in related to and create custom lookup as mentioned in Jeff's blog (http://blog.jeffdouglas.com/2011/08/12/roll-your-own-salesforce-lookup-popup-window/).
In the javascript function: baseURL(refer blog post page: MyCustomLookup), add a parameter to dynamically load the pass the object name to the new page.
// Following is the url of Custom Lookup page. You need to change that accordingly baseURL = "/apex/CustomAccountLookup?txt=" + txtId + '&objectName=' + objectApiName;
Then read objectApiName in CustomAccountLookupController to dynamically fetch the records using dynamic SOQL and List<sObject>.
Hope it helps!

How to calculate the Average using a Formula Field
Formula:
(IF(ISNULL(Base_Q1__c),Null,Base_Q1__c) + IF(ISNULL(Base_Q2__c),Null,Base_Q2__c)+IF(ISNULL(Base_Q3__c),Null,Base_Q3__c) +IF(ISNULL(Base_Q4__c),Null,Base_Q4__c)) / (IF(ISNULL(Base_Q1__c),Null,1) + IF(ISNULL(Base_Q2__c),Null,1)+IF(ISNULL(Base_Q3__c),Null,1) + IF(ISNULL(Base_Q4__c),Null,1)The problem is that I'm trying to establish a “running average” but it only calculates the average if all 4 custom fields (Base_Q1__c...) contain a value. If one of the 4 fields are blank, then the formula field will not calcuate anything. I need it to calculate the average no matter how value are displayed or blank.
WITH ALL 4 VALUES - AVG Calculates:
WITHOUT ALL 4 VALUES - No AVG Calculation:
Please help!!!

(IF(ISNULL(Base_Q1__c),0,Base_Q1__c) + IF(ISNULL(Base_Q2__c),0,Base_Q2__c)+IF(ISNULL(Base_Q3__c),0,Base_Q3__c) +IF(ISNULL(Base_Q4__c),0,Base_Q4__c)) / (IF(ISNULL(Base_Q1__c),0,1) + IF(ISNULL(Base_Q2__c),0,1)+IF(ISNULL(Base_Q3__c),0,1) + IF(ISNULL(Base_Q4__c),0,1)

Does deploying profile through autorabbit deploy apex class and vf page access, other object access in salesforce?
2. Is there a way to assign apex classes to a profile through data loader?




You may have to add those apex classes and Vf pages in additional to the Profiles because the profile metadata only get the basic details of the profiles. If you need any additional access like field-level permissions or Object permissions or Apex Class Access you have to add those as well in the deployment.
Regarding the second question Did you try data loading on SetUpEntityAccess object?
Let me know if you face any issues.
If this solution helps, Please mark it as best answer.
Thanks,

How do i find aconnected app by connected_app_id?


This formula seems to work when calculating bt 2 different days. What about taking into account for same day and returns result shoud be a "0"? My result shows a "5" when I entered 9/10/09 and 9/10/09 for both start and end dates. Is there one formula that can include this possiblity?
TY!!
Teacup13