Showing posts with label Other Blogs. Show all posts
Showing posts with label Other Blogs. Show all posts

Tuesday, August 22, 2017

Salesforce Communities

Initially Salesforce introduces many types of portals like partner portal, customer portal etc. Now these features are not available for new customers and Salesforce suggest to migrate to communities from existing portals because it is easy to implement and having more features.

Also all data access can be configured by Admin and even you can create different communities for your organization as per requirement as we normally do with WhatsApp groups or Facebook groups.

I have created presentation on Salesforce Communities and presented it in one of the Salesforce Meet up held in Pune, India.



Hope this will help in basic understanding of Salesforce Communities!!


More Blogs>>: 
INHERITANCE IN LIGHTNING    
FIRING EVENT FROM LIGHTNING COMPONENT AND PASSING IT TO VF PAGE    
CHANGES TO LIGHTNING DATA SERVICE IN SUMMER'17    
LIGHTNING DATA SERVICES    
PASSING LIGHTNING COMPONENT ATTRIBUTE VALUE FROM VF PAGE    
FIRE LIGHTNING EVENTS FROM VF PAGE    
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
PASSING LIGHTNING COMPONENT ATTRIBUTE VALUE FROM VF PAGE    
PASSING INNER WRAPPER CLASS TO LIGHTNING COMPONENT    
LIGHTNING COMPONENT FOR RECORDTYPE SELECTION FOR ANY SOBJECT    
CUSTOM COMPONENT TO SHOW/HIDE SPINNER IMAGE    

Wednesday, August 16, 2017

Creating Apex Rest Services and Testing it with POSTMAN

In this post, I am going to explain how to validate Apex Rest Service created in SFDC using POSTMAN (google chrome plugin).

First we will create a very basic Apex Rest Service.


After creating this class, now we can access this API by using below endpoint URL:

https://xxxx.salesforce.com/services/apexrest/RestAPIDemo
where xxxx is your domain URL or say instance URL like na15, cs30 etc.

Here we have created Rest API which accepts GET & POST request.Whenever we will perform GET request, API will return Account records based on search string passed as parameter in endpoint URL.

Now I will explain how to test this API Service by using POSTMAN.

In order to invoke Apex REST API, we need to have access token. So first we will use Oauth 2.0 to get access token from SFDC in order to perform API calls.

Steps to get access token from SFDC:

  • Create a connected App in SFDC.
  • Perform POST request from POSTMAN to below mentioned endPoint URL:

https://login.salesforce.com/services/oauth2/token?grant_type=password&client_id=CLIENTID&client_secret=CLIENTSECRET&
username=SFDCUSERNAME&password=SFDCPASSWORD_SECURITY_TOKEN

Where 
       CLIENTID = consumer key from created connected app
       CLIENTSECRET= consumer secret from created connected app
       SFDCUSERNAME = SFDC username
       SFDCPASSWORD_SECURITY_TOKEN = password + security_token

While performing POST request, specify header in which key will be "Content-Type" and value will be "application/x-www-form-urlencoded"



You will recieve JSON response in which access_token will be specified. Copy and save it.

Note:
If you have enabled my domain then you can use domain URL as base URL in endpoint URL. If you are not using domain, then in JSON response you will get instance_URL which you can use base URL whenever you call APEX REST API's.


How to perform GET request from POSTMAN to fetch data from SFDC
  • First create Endpoint URL(GET request).
          https:// BASE_URL/services/apexrest/RestAPIDemo?searchString=test
          where 
          BASE_URL is instance URL returned in JSON while requesting Access token.
          RestAPIDemo is REST Resource we specify while creating class.
          searchString : parameter passed to REST API which will return matched accounts
  • Specify Below headers
          [{"key":"Content-Type","value":"application/json"}]
          [{"key":"Authorization","value":"Authorization: Bearer Access_token"}]
  • Perform Get Request from POSTMAN


How to perform POST request from POSTMAN to create new record

  • Create a JSON through which you send account information.
       {
  "accName":"SKtest By POSTMAN",
   "aType":"New Customer",
   "aIndustry":"IT"
        }   
  • Specify endpoint URL
       https://xxxx.salesforce.com/services/apexrest/RestAPIDemo
       where xxxx is domain of your org
  • Specify headers
          [{"key":"Content-Type","value":"application/json"}]
          [{"key":"Authorization","value":"Authorization: Bearer Access_token"}]
  • Send POST request through POSTMAN.

Note:

If your POST method contains parameter, then you have to pass JSON in different ways. For example POST method is:

@HttpPost   
    global static String createNewAccount(accountWrapper accDetails) {
        string returnString='';
        try{
            Account acc=new Account();
            acc.Name= accDetails.accName;
            acc.Type = accDetails.aType;
            acc.Industry =accDetails.aIndustry;
            insert acc;
            returnString = 'Account created successfully with record Id:'+acc.id; 
        }catch(exception ex){
            returnString = 'Request got failed: Error details-'+ex.getmessage();
        }
         return returnString;
    }

In this scenario, JSON which needs to sent should be in below format:

{
"accDetails":{
"accName":"SKtest By POSTMAN2",
"aType":"New Customer",
"aIndustry":"IT"
}
}

Hope this will help!!!!

More Blogs>>: 
USING DATABASE.UPSERT WITH EXTERNAL ID   
DYNAMIC APEX IN SALESFORCE   
SOQL INJECTION IN SOQL   
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS   
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE   
REST API TUTORIAL FOR SALESFORCE   
VISUALFORCE COMPONENT FOR RECORD STATUS BAR   
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
PASSING INNER WRAPPER CLASS TO LIGHTNING COMPONENT    
LIGHTNING COMPONENT FOR RECORDTYPE SELECTION FOR ANY SOBJECT    
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE   

Friday, July 28, 2017

Language Translation in VisualForce Page

Salesforce provide functionality through which you can create single VF page and that can be translated in different languages based on language or locale preference of current logged in user.

You need to upload the translation of all custom fields which you are going to use in VF page and can utilize custom labels to display warning, error information on VF page.

In order to render the VF page in particular language, use Language attribute on <apex:page> tag. You can also bind this values with controller variable so that you can render VF page in different language.

<apex:page controller="SK_LocalizationTestController" language="{!selectedLang}">

I have created a very simple VF page to illustrate this functionality by displaying account information. I have dropdown on VF page through which user will select language and VF page will re render to display page in selected language.





Note:
  • If you are displaying page message using <apex:pageMessages>, then use custom label on apex class to display message. Upload all translation for custom label in salesforce.
  • For custom fields also you need to upload language translation. Please refer Translation Workbench under Set Up.
  • The language attribute does accept ISO country codes plus an optional locale like en,en_US,de,de_DE etc.
  • For displaying header or pageblock section title, use custom labels.

More Blogs>>: 
USING DATABASE.UPSERT WITH EXTERNAL ID   
DYNAMIC APEX IN SALESFORCE   
SOQL INJECTION IN SOQL   
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS   
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE   
REST API TUTORIAL FOR SALESFORCE   
VISUALFORCE COMPONENT FOR RECORD STATUS BAR   
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
PASSING INNER WRAPPER CLASS TO LIGHTNING COMPONENT    
LIGHTNING COMPONENT FOR RECORDTYPE SELECTION FOR ANY SOBJECT    
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE   

Saturday, July 1, 2017

Firing Event from Lightning Component and Passing Parameter to VF Page

In this blog, I am going to explain the way through which you can pass parameter from Lightning component by firing event from it and handling it in VF page and display the passed parameter in VF page.

If you want to understand how you can fire event from VF page and handle it in Lightning component, then refer below blog:

How to Fire Lightning Events from VF Page in Lightning

I have created a VF page which contains input text which will display Account Id which will be passed from Lightning component. This VF page also contains div container which will display lightning app which contains our lightning component.



Below is complete code for above example:

Note:
  • If you don't have namespace in your org then on VF page use "c:" instead of "skforce:" like c:SK_AccListViewApp
Hope this will help!!!

Looking forward for your comments and suggestions...

More Blogs>>: 
PASSING LIGHTNING COMPONENT ATTRIBUTE VALUE FROM VF PAGE    
FIRE LIGHTNING EVENTS FROM VF PAGE    
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
PASSING LIGHTNING COMPONENT ATTRIBUTE VALUE FROM VF PAGE    
PASSING INNER WRAPPER CLASS TO LIGHTNING COMPONENT    
LIGHTNING COMPONENT FOR RECORDTYPE SELECTION FOR ANY SOBJECT    
CUSTOM COMPONENT TO SHOW/HIDE SPINNER IMAGE    

Wednesday, June 28, 2017

How to find Salesforce API version of your Org in Apex

Sometimes it is required to find out current API version of your Org (Sandbox/Dev Org/Production) in order to perform some operations like making HTTP request to SFDC URI which contains api version.

As of now, I was not able to find any method in apex through which I can get my org current api version So I have created utility class which uses Tooling API to get all version related to org and returning latest/current api version like 39.0,40.0 etc.

Below is complete code for this.


You can run below scripts in developer console to get current API version after saving above class in your org.

Decimal currentAPIVersion = UtilityClassForSFDC.findAPIVersionOfOrg();
system.debug('***************currentAPIVersion:'+currentAPIVersion);

After running you may get "Unauthorized endpoint url". Just add your SFDC base URL in remote site setting to avoid this exception.

Hope this will help!!!
Looking forward for your comments and suggestions..


More Blogs>>: 
USING DATABASE.UPSERT WITH EXTERNAL ID  
DYNAMIC APEX IN SALESFORCE  
SOQL INJECTION IN SOQL  
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS  
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE  
REST API TUTORIAL FOR SALESFORCE  
VISUALFORCE COMPONENT FOR RECORD STATUS BAR  
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE  

Sunday, May 14, 2017

Important Things to Consider for Record Access while Designing Large Scale Applications

As we already know through Organization wide default, record access to different users in system can be controlled. Apart from OWD, user can get record access through role, being a part of public group with which record is shared, territories etc. In order to control access of records, Salesforce maintain record sharing data and recalculate the sharing when any changes happen to role, territory, public group etc. For end user, changing user's role is simple operation but at the back end, Salesforce has to perform all record sharing recalculation based on user's new role.

Lets discuss all this in details. First we will start with Database Architecture. Salesforce maintains 3 types of tables as mentioned below:

  • Object Record Table
These are the tables which stores records of specific object and indicate which user or queue owns each record.
  • Object Sharing Table
If OWD of any object is public read only or private, the Salesforce create share table for that object.This table store information about record access for all users which is shared by explicit grant (shared with user or group) or implicit grant (built in sharing like access to child opportunity, cases if you have access to account record).
  • Group Maintenance Tables
This table stores list of users or groups that belong to each group indicating group membership. Suppose a record is shared with group, then Salesforce check group maintenance table to identify which all users inherit access to that record (either through role hierarchy, group membership or through territories).

So when Salesforce has to find out that if user has access to record, then it perform join between three tables to identify record access for user. If user is owner of record, then it will display that record. If not it will check object sharing table and group maintenance table to find users access to record.

Salesforce Role hierarchy, public groups and territories are closely connected with sharing rules and security features. Suppose an user owns more than 10,000 records and now admin just changed this role. Now salesforce need to remove access to all these records for all user which are having higher role than user's previous role and need to provide access to all user's in higher role than new user's new role. So Salesforce has to recalculate the record access and sometimes it may take more time.

In order to handle these scenarios, Salesforce provide few tools which can be used to avoid these issues caused by user realignment either through roles, territory or public groups:

  • Parallel Sharing Rule Calculation
Whenever admin changes user's role or change group membership or create, edit or delete sharing rules, then recalculation for record access happens synchronously. So when any of these changes affects access right to large number of records, the recalculation job take longer time. If any Salesforce perform any activity at this time like patch release or upgrade, then recalculation jobs get killed. In this scenrio, consider parallel Sharing Rule calculation. This will split the job in multiple threads which will run asynchronously and if Salesforce perform any activity, these jobs will resume after salesforce activity.

Contact Salesforce in order to enable this feature.
  • Deferred Sharing Maintenance
Suppose you have rebuild the role hierarchy and group membership, the sharing recalculation may take significant time. In this kind of scenarios, you can enable deferred sharing which will allow admins to switch off of sharing recalculation and perform all role and group membership changes and then switch on sharing calculation. After switching on sharing calculation, admin has to start recalculation of all sharing rules for accurate user access rights.

Remenber deferred sharing doesnot stop sharing recalculation due to implicit sharing.
Contact Salesforce in order to enable this feature.
  • Granular locking
Whenever any change is performed to roles or group, Salesforce locks entire Group membership table to protect data integrity. This will make impossible to perform group membership changes. Consider a scenario in which your users are facing frequent record locking error and restrict their ability to manage manual and automatic update at same time or degrade the group maintenance updates, then enable Granular Locking feature.

If Granular locking feature is enabled then system will lock portion of records instead of locking entire Group maintenance table. This allow multiple update simultaneously if there is no hierarchical or other relationship between the roles and groups involved in the update.

You need to contact Salesforce to enable Granular locking feature.


More Blogs>>: 
DYNAMIC APEX IN SALESFORCE
SOQL INJECTION IN SOQL
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE
REST API TUTORIAL FOR SALESFORCE
VISUALFORCE COMPONENT FOR RECORD STATUS BAR
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
PASSING INNER WRAPPER CLASS TO LIGHTNING COMPONENT    
LIGHTNING COMPONENT FOR RECORDTYPE SELECTION FOR ANY SOBJECT    

Thursday, April 20, 2017

Using Database.upsert with external ID field

External Id plays very important role if you want to update records without knowing the record Ids or want to relate the child record with parent record without knowing the parent record Id.

As a best practice, you should always make External Id unique. If you are performing upsert with External Id, then following situations will occur:

  1. If no record is found in table with provided External Id, then it will create record in table.
  2. If 1 record is found in table with provided External Id, then it will update record in table.
  3. If more than 1 records is found in table with provided External Id, then system will throw an error.

I am going to cover 2 different aspect of using external Id in apex.

  • Updating a record with External Id

Create a External Id field on Account as Account_Unique_Number__c and mark it as External Id and unique while creating it.Now we will create a new record using upsert.

Execute below command in developer console

List<Account> acclist=new list<Account>();
acc.name='Demo test1';
acc.Account_Unique_Number__c='00001';
acclist.add(acc);
Schema.SObjectField ftoken = Account.Fields.Account_Unique_Number__c;
Database.UpsertResult[] srList = Database.upsert(acclist,ftoken,false);
for (Database.UpsertResult sr : srList) {
    if (sr.isSuccess()) {
        // Operation was successful
    }
    else {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('error has occurred.' + err.getStatusCode() + ': ' + err.getMessage());                    
            System.debug('fields that affected this error: ' + err.getFields());
            
        }
    }
}

As there is no record in Account with Account_Unique_Number__c as 00001, system will create a new record.

Now again we will run same script in developer console and will specify some more field values:

List<Account> acclist=new list<Account>();
Account acc=new Account();
acc.name='Demo test1';
acc.Account_Unique_Number__c='00001';
acc.type='Other';
acc.Industry='Banking';
acclist.add(acc);
Schema.SObjectField ftoken = Account.Fields.Account_Unique_Number__c;
Database.UpsertResult[] srList = Database.upsert(acclist,ftoken,false);
for (Database.UpsertResult sr : srList) {
    if (sr.isSuccess()) {
        // Operation was successful
    }
    else {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('error has occurred.' + err.getStatusCode() + ': ' + err.getMessage());                    
            System.debug('fields that affected this error: ' + err.getFields());
            
        }
    }

Now you will see that system will update the record as it was able to find a Account record with Account_Unique_Number__c as 00001

  • Relating a child record with parent record by using parent record Id

In order to understand this, we will create contact record and will relate to account using Account_Unique_Number__c. Execute below code in developer console:

List<Contact> conlist=new list<Contact>();
Contact con=new Contact();
con.lastname='Kumar';
con.Firstname='Kumar';
con.email='sunil02kumar@gmail.com';
Account acc=new Account(Account_Unique_Number__c='00001');
con.Account=acc;
conlist.add(con);
Database.UpsertResult[] srList = Database.upsert(conlist,false);
for (Database.UpsertResult sr : srList) {
    if (sr.isSuccess()) {
        // Operation was successful
    }
    else {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('error has occurred.' + err.getStatusCode() + ': ' + err.getMessage());                    
            System.debug('fields that affected this error: ' + err.getFields());
        }
    }
}

This will create a new contact for Account which have Account_Unique_Number__c as 00001.

In above code snippet, you can see that in order to relate contact with account, we are not specifying the account 15 or 18 digit record id. We are just specifying the external Id of account and system will maintain the relationship.

If you refer custom object as parent object then refer it with __r. For example in above scenario, if i have to relate contact with custom object say Parent_Obj__c, then I will use below code:

Parent_Obj__c  obj = new Parent_Obj__c(Unique_Number__c='00001');
con.Parent_Obj__r = obj;

Why it is recommended to mark External Id as unique?

Imagine you are creating a contact and specified External Id of parent. Suppose there are 2 records in account table with same value, then system will not able to identify with whom it needs to relate the contact and will throw error saying more than 1 match found.

Same is applicable when you update the record with External Id.



More Blogs>>: 
DYNAMIC APEX IN SALESFORCE
SOQL INJECTION IN SOQL
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE
REST API TUTORIAL FOR SALESFORCE
VISUALFORCE COMPONENT FOR RECORD STATUS BAR
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE

Thursday, April 6, 2017

Login Flows to Display Important Messages to User After Login

Sometimes it is required to display some message to SFDC users when some maintenance or migration activity is getting performed in production. For example, during some major project release which may take many hours or many days for metadata and data migration, you want to display message to SFDC user saying "Maintenance is in progress and you may experience intermittent issues".

You might have seen these kind of intermediate screen informing about Salesforce maintenance window after logging into salesforce.

Login Flows allow administrators to display intermediate screen (Flow) once user is authenticated and after that user will be redirected to home page of salesforce.

You can create a flow using flow designer and associate it with Login flow. As you already know that flow can be used to collect some information from users or to display some message to end users. Using flow you can specify set of screen to capture data from user or navigate the user's to set of instructions.

Important points regarding Login Flows:
  • The login flow screens are embedded within the standard Salesforce login page for uniform user experience.
  • You need to associate Login flows to different profiles. So all user related to that profile will see flow screen after authentication.
  • Login Flows can be applied to SFDC Orgs, communities and portals. 
  • Login flow comes into picture whenever user login through UI either using username and password, delegated authentication, SAML single sign-on, and social sign-on through a third-party authentication provider

Now we will create a sample flow to display maintenance message to end users during some major project release. Below are steps which we need to follow:


Create a flow

  • Navigate to Set Up--> Create-->Flow. Click on New Flow button. This will open Flow designer screen. Drag Screen Palette from left side and name it as "Maintenance Window Message".

  • Now Click on "Add a Field" tab and double click on display text.

  • Now click on "Field Settings" tab and click on display text. Give unique name as "MessageToDisplay". Specify the message which you want to display to end User and then click Ok.

  • Mark screen as start element for you flow by clicking on green down arrow as shown below.

  • Now Save flow by clicking on Save button and name flow as "Maintenance Window Flow".

  • Now Close the Flow and Activate it. Click on Activate link. Remember only active flow will be available for login Flows.

Assign Login Flow to Profile

  • Navigate to Set Up-->Security Controls-->Login Flows. Click on New Button. Specify name as "Maintenance Window Message" and select license and profile. Profile list depends on license selected by user.

  • In this way you can create multiple entries for different profiles.

Now you login into Salesforce to test this. Once you specify your username and password, you will see below message screen.



Points to remember:
  • You can just delete the login Flows records after maintenance window so that users will not see this message after login.
  • You can not create more than 1 login flow record for a given profile. Suppose you want to assign different flow to same profile in login flow then you will get below error:



Hope this will help!!!

For more details on Login flow, please refer below URL:
Login Flows


Other Blogs>>: 
DYNAMIC APEX IN SALESFORCE
SOQL INJECTION IN SOQL
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS
REST API TUTORIAL FOR SALESFORCE
VISUALFORCE COMPONENT FOR RECORD STATUS BAR
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE

Tuesday, March 28, 2017

Different ways of testing HTTP callout in apex

As we all know that test methods do not support HTTP callout, so all test method performing callout will fail.


In order to avoid the test class failure, we mainly use Test.IsRunningTest method in apex class. By using this method, we make sure that particular block of code performing HTTP callout should not run when called by test class methods.

if(!Test.isRunningTest()){
// apex code for HTTP callout
}
but this approach will reduce your code coverage. As per salesforce, you need to have atleast 75% coverage for all your apex code.

We will now go through different options through which we can test HTTP callout and increase our code coverage.

  • Using static resource
You can store the response of your HTTP callout in text file and upload it static resource. Now you can use built in apex class StaticResourceCalloutMock or MultiStaticResourceCalloutMock to build mock response and get response from static resource.

First create an instance of StaticResourceCalloutMock:

StaticResourceCalloutMock mockCallout = new StaticResourceCalloutMock();
mockCallout.setStaticResource('StaticResourceForCallout');
mockCallout.setStatusCode(200);
mockCallout.setHeader('Content-Type', 'application/json');

Now set mock callout mode in test method by using below method:

Test.setMock(HttpCalloutMock.class, mockCallout );

After this call method which perform callout. As we have set mock test callout, apex will not perform callout and will return response from static resource.

Note: MultiStaticResourceCalloutMock helps you test different HTTP callout with different endpoint URL. you can create instance of this class and specify callout response in different static resource for different endpoints and then set this as mock callout in test method.

  • Generating mock response in test by implementing the HttpCalloutMock Interface 
Create a apex class which implements HttpCalloutMock interface. In this interface, you can specify response which will be returned if test method perform callout.

@isTest
global class HTTPMockCallout implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest req) {
        // specify the response here
        // return response.
    }

Note:
       1. Class should be public or global which implements HttpCalloutMock
       2. You can use @IsTest on this class as this will be used only through test class. In this way it                   will not count against organization code size limit.

Now you can set mock response in test method before calling method which perform HTTP callout.

Test.setMock(HttpCalloutMock.class, new HTTPMockCallout());

Below is sample code to provide code coverage to "CalloutUtility" apex class using both approaches mentioned above


Hope this will help!!!!


More Blogs>>: 
DYNAMIC APEX IN SALESFORCE
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE
SOQL INJECTION IN SOQL
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE
VISUALFORCE COMPONENT FOR RECORD STATUS BAR

Friday, March 10, 2017

Generating random number between two numbers and finding string value from list of values randomly

As we know in apex, math.random() function gives random number greater than or equal to zero and less than 1. This function can be used to generate random number in apex.

I have created a apex class which can be used to find a random between 2 numbers and this can be extended later to find random string from list of strings values or to select random picklist value for picklist field while creating test data in test class.

Below is apex class code:


In order to find random picklist value, use apex describe to store all picklist values in List and then pass that list to "findRandomStringFromList" method in RandomUtility apex class.


Hope this will help!!!


More Blogs>>: 
DYNAMIC APEX IN SALESFORCE
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IN SALESFORCE
SOQL INJECTION IN SOQL
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE
VISUALFORCE COMPONENT FOR RECORD STATUS BAR

Saturday, February 25, 2017

Fetching file from external/public URL and storing it into Salesforce

If you have file URL for file stored outside the salesforce, then you can fetch file information from external URL by performing a call out to external system and store the file in salesforce.

For Demo purpose, I have uploaded a pdf file in Google drive and shared it with link with people. Now I will fetch this file and will store it as attachment in salesforce under account record.

File URL-  https://drive.google.com/file/d/0ByXILxflqQ2jWGpNVmI1WW9uYTQ/view?usp=sharing


Below is apex class which will help us to perform this activity:



Now you can run below code in developer console to test this:

//you can specify any record Id where you want to store file as attachment
String RecordId='0019000000ld4kN'; 
String fileContentType='pdf';
String extFileURL='https://drive.google.com/file/d/0ByXILxflqQ2jWGpNVmI1WW9uYTQ/view?usp=sharing';
blob fileBlob=FileDownLoadUtility.fetchFileFromExternalUrl(extFileURL);
Id attachmentId = FileDownLoadUtility.createAttachment(fileBlob, RecordId , fileContentType);
system.debug('*****attachmentId:'+attachmentId);

Note: 

  • If you are trying to fetch file from external source which is authenticated, then pass authorization parameters in HTTP Request headers
  • You should specify the file content type before creating attachment in order to properly view file.
  • You can add additional parameter as fileName in "createAttachment" method, if you you want specify the attachment name while creating attachment.

While trying above code you may get below error:

For this you need to add external URL in Remote Site Settings. For this example, I have added "https://drive.google.com/" in remote site settings.




More Blogs>>: BOX AND SALESFORCE INTEGRATION    
INTEGRATING BOX FILE PICKER WITH SALESFORCE
REST API TUTORIAL FOR SALESFORCE




Friday, January 27, 2017

Ways to resolve "Collection size xxxx exceeds maximum size of 1000" on VF page

Visualforce pages are not designed to display more than 1000 records in UI. So if you have controller method which returns more than 1000 records and you are displaying the records on UI, then you will receive error "Collection size xxxx exceeds maximum size of 1000"  where xxxx is number of records returned by your controller method.



So now if you have to display more than 1000 records on UI, then you can use below options:

  • Use @ReadOnly annotation on method or on page attribute.

As per Salesforce Documetation:

Normally, queries for a single Visualforce page request may not retrieve more than 50,000 rows. In read-only mode, this limit is relaxed to allow querying up to 1 million rows.

In addition to querying many more rows, the readOnly attribute also increases the maximum number of items in a collection that can be iterated over using components such as <apex:dataTable>, <apex:dataList>, and <apex:repeat>. This limit increased from 1,000 items to 10,000.

  • You can restrict the number of records returned by method and provide pagination option using controller method.

For this you have to write the logic in controller and every time you will send request to server in order to render the page.


You can also jquery datatables and pass the JSON data to it to create table for you and you will get pagination, sorting or filtering of records on client side itself which will be very quick.

So we will pass more than 1000 records as a JSON to VF page and by using jQuery, we can build table.

Below is sample apex class and VF page code:


VF page Output (Displaying more than 50000 records)



If you have to dispaly hyperlink on account name, then modify the account name value before adding it to fieldvalues list at line number 19 in apex class as shown below:
sb.name= '<a href=\'/' + sb.id + '\'  target=\'_blank\'>' + sb.name+ '</a>';



This will display hyper link to account record. In my example code, I am adding new records to list so id are not present. If you are using query to add records in account list, then you can use above code snippet to show hyperlink.



Sunday, January 15, 2017

Customizable Visualforce Component to display Hierarchy Relationship between records for any Object (Account Hierarchy, Case Hierarchy etc.)

It is very common use case to display hierarchy relation between records in tabular form (for example account hierarchy, case hierarchy etc.) In order to achieve this, I have created a reusable visualforce component for this purpose which can be customize as per requirement to display hierarchy in table tree grid.



Below are inputs required for component:
  1. Specify the object name for which you want to display hierarchy.
  2. Specify the parent field API name (used for self relationship).
  3. Specify the API names of fields separated by comma which you want to display in table tree grid.
  4. Specify the columns labels separated by comma (make sure sequence is same as that of API fields name )for table tree grid.
  5. Specify the field API name which will display as hyperlink for record detail page.

You can create new VF page and include this component and specify above inputs and component will display the hierarchy of record starting from top most parent. 

Below is visualforce component and apex class code:


For example to generate the account hierarchy, create a VF page with code :
<apex:page controller="hierarchyComponentController">
<c:hierarchyComponent sObjectAPIName="Account" sParentfieldAPIName="ParentId" ColumnsToDispaly="Name, Type, Industry" RecordLinkfieldAPIName="Name" ColumnsLabels="Account Name, Type, Industry"/>
</apex:page>

Note: Don't forget to append record Id on visualforce page url for which you want to display hierarchy. Below is sample URL:
https://xxxxxxxxx.visual.force.com/apex/accHierarchy?id=0019000001NqoXZ

Hope this will help...

This can be used as base code and can be customize as per your requirements.

Looking forward for everyone's comment and feedback.




Refer Below Links for Salesforce Interview Questions

Saturday, January 7, 2017

Custom Metadata Types and Custom Settings Implementation Tricks

Custom Settings

  • Custom settings helps to create custom data set  and associate the data set to particular user, profile or for all users (org-wide). 
  • There are 2 types of custom setting, List and Hierarchy
  • Same set of data is available to all user if we define List custom setting.
  • In Hierarchy custom setting, you can control data visibility based on logged in user, profile or org-wide. 
  • In Hierarchy custom setting for logged in user, system first check user then profile and then org wide setting in order to return data from hierarchy custom setting.
  • You can control the visibility of custom setting by specifying it as public or protected.
  • If custom setting is marked as protected, the subscriber organization will not be able to access the custom setting. If it is marked as public, then subscriber org can also access it.
  • Once you create custom setting, then you cannot change the type (List to hierarchy or vice versa).
  • Custom setting data is available in application cache which increase performance. 
  • You can access custom setting data using instance methods and can avoid SOQL queries to database.
  • While migrating custom setting to another org, you need to migrate data for custom setting separately.
  • Custom settings do not support relationship fields.
  • Custom setting can be used by formula fields, validation rules, flows, Apex, and the SOAP API.
  • You cannot access List custom setting in Validation rule. Only Hierarchy custom setting can be used.
  • In order to use value from list custom setting in validation rule, create a field in object and populate list custom setting value in custom field through triggers and then refer it in validation rule. Validation rule fires after trigger execution.
  • You can perform CUD (Create, Update, Delete) operation on custom setting in apex.
  • Custom settings are not visible in test class without "SeeAllData" annotation.

Custom Metadata Types
  • Custom metadata are like custom setting but records in custom metadata type considered as metadata
  • You can migrate data present in custom metadata type to different org easily. 
  • This helps to create app configuration data and include it in package. 
  • Custom metadata types support Metadata Relationship. It is still in Beta.
  • Metadata Relationship provides the ability to add relationships from your custom metadata to other things in your app, such as other custom metadata, custom or standard objects and fields, and static resources.
  • You can't perform CUD (Create, Update, Delete) operation on custom metadata type in apex.
  • You can also control the visibility of custom metadata type while adding it in package.
  • Custom metadata type are visible in test class without "SeeAllData" annotation.
Custom metadata types are still in development phase and many new features will come in coming future.


Refer Below Links for Salesforce Interview Questions


Tuesday, December 13, 2016

Best way to deal with user supplied inputs in dynamic SOQL query -SOQL Injection

Through SOQL Injection, end user can play with the data present in your organization. End users can specify input which can alter your dynamic SOQL query and return sensitive data to user on UI.

Consider a scenario where user search account present in your org by specifying account name as a search text. Below is sample VF and apex code which explain SOQL injection.

Suppose you enter "test" and click on search, system will return all account name as test. Below is SOQL query which will be executed:

SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry FROM Account WHERE Name like '%test%' 


Now if you enter " test%' OR Name LIKE '% " and click on search account button, then system will return all account in system. 

Actually after entering above text, SOQL query will become like this:

SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry FROM Account WHERE Name like '%test%' OR Name LIKE '%%' 



SOQL injection allow end users to reconstruct your SOQL and fetch sensitive data from your org.

Resolution:

  • Try to use static SOQL and bind user input variable in that.
  • If you have to use dynamic SOQL for your requirement, then user use the escapeSingleQuotes method for all user input strings. This add escape character (\) to all single quotation marks in string that is specified by end user. 

Below is modified apex code to avoid SOQL injection:

public PageReference query() {
        if(name !=null && name !=''){
            name = String.escapeSingleQuotes(name);
            accList = new List<Account>();
            queryString= 'SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry   FROM Account WHERE ' + ' Name like \'%' + name + '%\'';
            accList = Database.query(queryString);
        }else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'Please enter search text value'));
        }
        return null;
    }

Now if user enter " test%' OR Name LIKE '% "  and click on search account button, the dynamic SOQL query will become as mentioned below and system will not display anything on UI.

SELECT Id, name, industry, BillingStreet, BillingState, BillingCity, BillingCountry FROM Account WHERE Name like '%test%\' OR Name LIKE \'%%'