Sunday, July 26, 2020

Compare CRUD (Object Level Access) Permission for a Profile from 2 different Org

Through this blog, I am going to share a script through which you can compare object level permission for a profile in 2 different SFDC orgs. This script is very helpful when you want to compare CRUD level permission for a profile in 2 different sandbox or permission in sandbox and production.

When you run below script, you will receive email with csv file with CRUD permission comparison.
You need to specify the target org domain url and sessionid or access_token of target org and need to run below script in source org in execute anonymous window in developer console.

Below is script:

Below is snapshot of csv file:



Note:

This is just a prototype and it may work for small organization. You need to consider heap size and apex CPU time limit exceeded errors. You can refractor this code for your use based on number of objects that you have in your org.

Hope this will help!!



Friday, June 26, 2020

Creating Package.xml from Changeset and Retrieving zip file containing Metadata using Workbench

We can utilize workbench to retrieve the package.xml and complete metadata in zip file for a changeset.

Navigate to "migration" and then click retrieve.


Enter changeset name. If you want to download package.xml for different changeset, then enter names seperated by comma.


Click on "next" button and then retrieve button.

Download zip file and after extracting the files, you will get complete metadata and package.xml.



Benefit of generating package.xml

Before deploying changeset to target org, you can extract package.xml from changeset. Now you can utilize this package.xml to extract metadta from target org before deployment which will work as backup for target org metadata. 
Suppose you have to rollback after actual deployment, then you can utilize backup taken using package.xml to redeploy the old metadata in production.


Hope this will help!!



Monday, April 27, 2020

Javascript Promise.all : Way to perform action when Multiple Parallel enqueued Actions are Completed in Lightning Components

As we all know that all actions from Lightning components are sent to server in asynchronous manner and we can not predict the sequence about response from server.

If we have requirement to wait for all operations to complete and then perform some action on lightning components like hiding the spinner or displaying all data at once.

We can either queue the first server call and when we get response then we perform second server call. For this you can use Javascript Promise pattern to sequence the server call. Please refer below URL for complete understanding of sequencing of server call using javascript promise.

JavaScript Promises vs Callback Functions in Lightning Components

Now if we need to fire server calls in parallel and want to wait for all response, then you can utilize promise.all methods to achieve this. This will execute many promises in parallel and wait until all of them are ready. Below is syntax to use promise.all:
 
//create array of promise and pass it to promise.all 
var promiseArray =[promise1, promise2];
var combinedPromise = Promise.all(promiseArray);
//this return single promise. Now handle it with then and catch
combinedPromise
.then($A.getCallback(function(results){
 //handle success
 var promise1Results = results[0]; //Results from Promise 1
 var promise2Results = results[1]; //Results from Promise 2
})) 
.catch($A.getCallback(function () { 
 //Handle errors on any promise here
 console.log('Some error has occured'); 
}));

Note:
  • Promise.all takes an array of promises and returns a new promise.
  • The new promise resolves when all listed promises are settled, and the array of their results becomes its result.
  • Order of the resulting array members is the same as in its source promises. Even though the first promise takes the longest time to resolve, it’s still first in the array of results.
  • If any of the promises is rejected, the promise returned by Promise.all immediately rejects with that error.
  • For example, if there are multiple fetch calls and one fails, the others will still continue to execute, but Promise.all won’t watch them anymore. They will probably settle, but their results will be ignored. Promise.all does nothing to cancel them, as there’s no concept of “cancellation” in promises.
  • This will help to improve the performance of lightning components as server operations are not performed in sequential order. Due to parallel call to server, lightning components will perform better.
I have created a sample lightning component which fetch Account and Task records from server and displays it in UI only when both operations are completed and response is returned to lightning components. below is gif image displaying the lightning component functionality:


Below is complete snippet for your reference:

Hope this will help!!

Friday, April 17, 2020

Get the Content (Blob) of File from Box and Store/Manipulate it in Salesforce

Through this blog, I am going to share sample apex script through which you can get content of file from box as blob and then store or manipulate it within salesforce.

I have already written a blog to explain how to get box access token (needed for handshake with Box) and to display file content in salesforce in VF page without storing it in salesforce. You can cosider it as Mashup inSalesforce. Please refer below URL to that:

Box and Salesforce Integration

In order to get box file content, we need to have box file Id and box access token.

Box does not provide direct API to get file content. First you need to do callout to get download URL and then you perform another API callout to get file content. Also you perform another API call to get file details like filename in order to store it in salesforce.

I am going to store box file in salesforce library for demo purpose. You can store it as attachments or read the content on the fly to perform some logic instead of saving it.

Add below URLs in remote site settings before performing the callouts:
  • https://api.box.com
  • https://dl.boxcloud.com 

Below is required code and it is self explainatory as comments are mentioned for each methods:

Now run below script in developer console:

string boxFileId='6542xxx28604';
string access_token='0xxxxxxxxxxxxxxxxxxxxxxxxxxxredx0P';
string sfdcLibraryName='Box_File_Library';
string boxFilename= SK_BoxAPIUtilityClass.findFileNameFromBox(boxFileId,access_token);
system.debug('****boxFilename:'+boxFilename);
SK_BoxAPIUtilityClass.readFileContentFromBox(boxFileId,boxFilename,sfdcLibraryName,access_token);



Use Case

During sandbox refresh, all custom settings data gets refreshed from production values. So before refresh, you have to take back up each custom settings data and after refresh, you need to update the custom setting records. In order to automate this, you can write script through which you can push all custom setting data to box folder. Code to upload the files from Salesforce to box is already shared in blog  Box and Salesforce Integration.

Now we need to get the content of all csv files stored in box and update the custom setting in salesforce. Once you get the content of file, you can parse csv file and update custom settings.

Hope this helps!!!


Saturday, April 11, 2020

JavaScript Promises vs Callback Functions in Lightning Components

As we all know that all server calls from lightning components are asynchronous in nature. If we call 2 different apex methods from lightning components, then there is no surety that which will return response first. In order to provide sequencing between these 2 calls, we have to write second method call in callback function of first apex call as mentioned below:

findDataUsingNormalCall : function(component, event, helper) {
  var actionName1= component.get("c.findMyAccounts");
  var params1={"numberOfRecords":2};
  actionName1.setParams(params1);
  actionName1.setCallback(this, function(response) {
    var state = response.getState();
    if (state === "SUCCESS") {
        var apexResponse1=response.getReturnValue();
        component.set("v.ltngAccList",apexResponse1);
       //Now perform second Call
        var actionName2= component.get("c.findMyPendingTasks");
        var params2={"numberOfRecords":2};
        actionName2.setParams(params2);
        actionName2.setCallback(this, function(response) {
           state = response.getState();
           if (state === "SUCCESS") {
              var apexResponse2=response.getReturnValue();
              component.set("v.ltngTaskList",apexResponse2);
           }else if(state === "ERROR"){
              var errors2 = response.getError();
              console.error(errors2);
           }
        });
        $A.enqueueAction(actionName2);
     }else if(state === "ERROR"){
        var errors1 = response.getError();
        console.error(errors1);
     }
  });
  $A.enqueueAction(actionName1);

Now if you have to perform multiple server side apex calls from lightning components in sequential order, code becomes very difficult to understand and read and difficult to maintain this kind of code.

Javascript Promises

Promise pattern is very common in javascript to handle asynchronous operations.  Prior to promises events and callback functions were used but they had limited functionalities and created unmanageable code.

Promise can have 3 states:
  • Pending
  • Fulfilled
  • Rejected
Use below syntax to create promise:

var promise1 = new Promise($A.getCallback(function(resolve, reject){
     //perform logic like server call
     if (/* success */) {  
        resolve("result");
     }else {
        reject("error");
     }
}));
  • Constructor takes only one argument as a function. 
  • Callback function takes two arguments, resolve and reject
  • Perform operations inside the callback function and if everything went well then call resolve.
  • If desired operations do not go well then call reject.
In order to consume promise, use .then or .catch methods as shown below:

promise1 . 
    .then($A.getCallback(function(result){
             //handle success
 }), 
 $A.getCallback(function(error){
            //handle error
        })
     ) 
    .catch($A.getCallback(function () { 
        console.log('Some error has occured'); 
    }));

Remember:
  1. then() method automatically invoked when promise is either resolved (fulfilled) or reject.
  2. then() method takes 2 functions as parameters:
    • If promise is resolved and a result is received, First function is executed.
    • If promise is rejected and an error is received, Second function is executed(optional).
  3. catch() method is invoked when a promise is either rejected or some error has occurred in execution. catch take 1 function as parameter. If you are using the second parameters for then function then use catch for error handling.
Calling multiple asynchronous functions and Chaining them using Promises

You can use below pattern in order to perform different asynchronous operation in synchronous manner.

new Promise($A.getCallback(function(resolve, reject){}))
    .then(
        // resolve handler
        $A.getCallback(function(result) {
   //when first call is successfull, then create new 
   //instance of promise to make another call
          return new Promise($A.getCallback(function(resolve,reject){}));
        }),
 // reject handler
        $A.getCallback(function(error) {
            console.log("Promise was rejected: ", error);
    //you can create another promise for error handling
        })
    )
    .then(
        // resolve handler
        $A.getCallback(function() {
            //perform logic when second call is successfull
        })
    );
I have created a sample lightning component which explain the functionality of callback function and promise pattern. Below are details about this component functionality:
  • Component contains 2 button which invoke 2 different apex methods by using callback pattern and promise pattern.
  • When user clicks on "Fetch 2 records using callback pattern" button, system fires 2 server calls to get account and task records in asynchronous manner. So records will get displayed on UI based on response from server. There will be no sequencing of these 2 method invocation.
  • When user clicks on "Fetch 3 records using promise pattern", system first fire an asynchronous call to get account records and once account data is recieved, then it will fire another asynchronous call to get task records. This functionality uses promise pattern to fire 2 asynchronous call in synchronous manner. 


Below is code snippet:

Best Practices:
  • Always use catch or reject handler.
  • Always use $A.getCallback() when using promise pattern in lightning components. Even if you do not use this, then sometimes it will work but it will be very difficult to debug if something went wrong. Sometimes if you don't use it, then results may get delayed on UI and can cause performance issues. 
Hope this will help!!

Thursday, January 30, 2020

Fetch All Workflow Email Alert Details Related to Object Using Tooling API

Through this blog, I will sharing script which can help to get complete information about all the email alerts configured in Salesforce using workflow rules for any sObject.

Imagine a scenario in which you need to extract all email alert configured or created for different workflow rules for specific object so that it can be reviewed or analyzed. If you do this activity manually then you have to open each workflow email alert and note down details like recipient, ccEmails, senderAddress, email template etc. This will be very hectic if you have lots of email configured.

In order to solve this scenario, I am using Tooling API through which we can get complete details about workflow email alert. Through apex script, we can generate these details and send email (with csv file as attachment) to user with all details.

First of all, inorder to parser JSON response, we need to create apex class (SK_EmailAlertJSONParser) which will act as parser for JSON. After this we can run the script in developer console and user will get email with all information regarding email alert.


Below is snapshot of csv file that we will receive after running above script in developer console.
I have specified objectId as "Contact". For custom object, specify 15 digit or 18 digit id.


This script can be used to fetch information from other salesforce org also. Suppose you don't want to deploy this script in production, then save SK_EmailAlertJSOnParser class in sandbox and in developer console (using execute anonymous window)  just specify the domainUrl for production and sessiond id production for admin user.

Don't forget to add domainUrl in remote site settings before running this script in execute anonymous window in developer console.

Hope this will help!!1

Thursday, January 9, 2020

How to Delete all Files from Library using Apex

If you have to delete any library, then first you have to delete all the files present in that library. For this purpose you can run below mentioned simple apex script to delete all files from library.

string LibraryName='Demo Library';
ContentWorkspace ws = [SELECT Id, RootContentFolderId FROM ContentWorkspace WHERE Name = :LibraryName LIMIT 1];
List<ContentDocument> contentDocumentIds = new List<ContentDocument>();
for(ContentDocumentLink con:[select id,LinkedEntityId,ContentDocumentId   from ContentDocumentLink  where LinkedEntityId=:ws.Id]){
    contentDocumentIds.add(new ContentDocument(id=con.ContentDocumentId));
}
system.debug('********contentDocumentIds:'+contentDocumentIds);
system.debug('********contentDocumentIds.size:'+contentDocumentIds.size());
database.delete(contentDocumentIds,false);


Hope this will help!!

Wednesday, January 8, 2020

Download Multiple Files from Libraries

Consider a scenario in which we are suppose to download all files from libraries. Below are different approach which can be utilized:

Approach 1: Salesforce UI Download Button

If the file size is around 60 or less in library then you can use Salesforce UI to download all files at one time.

Open any library, click on show all button, then click on display options and select "Show 60 results per page". By doing this, you will be able to see 60 files at once in library. Now you can click on select all checkbox and click download button. This will help you to download files at once.
If you have more than 60 files, then click on next page and then again download all files. This process will become hectic if you have more than 1000 files in library.

Approch 2:URL hack

I performed some search on google and found out that there is another way to download all files as zip by specifying the contentversion Ids of file in URL. I can call it as URL hack and everyone mentioned that it is not recommended way. Below is URL format that you need to use:

https://xxxxxx.salesforce.com/sfc/servlet.shepherd/version/download/068xxxxxxxxxxxxxxx/068yyyyyyyyyyyyyyy/068wwwwwwwwwwwwwww/068zzzzzzzzzzzzz?

Just paste this URL and files will be downloaded as zip file.

If you have more than 1000 files in library, then you have to build different URL by specifying 10 or 15 record id in one URL. I was able to download zip file with size around 400Mb using one URL.

Approach 3: Using Apex Script & Tab Save Chrome Extension

One of my friend told me about Tab Save  chrome extension. You just need to paste all files download url and click on download.



This will download all files in your downloads folder or folder that you have specified in chrome download settings.

Now we wrote simple apex script which will send email with all URLs(file download URL) in csv file. Suppose you want to get download URLs for all files present in library "Demo Download Library", then refer below script:

Run above script in developer console by specifying your library name. You will receive email with all file download URLs. Now you just copy and paste these URLs in Tab Save edit window and click on download.

I have used Tab Save extension to download around 1500 files and it was working fine.

Now you have all 3 approaches and you can decide what to chose based on your requirements.

Hope this will help!!