Thursday, May 25, 2017

Finding custom fields Ids in order to pre-populate fields while creating new record

Sometimes it is required to pre-populate the custom fields while creating new record in salesforce. This can be achieved by passing all fields values which you want to populate in URL. But in order to relate url parameter value with custom field, you need know custom field Id. Instead of hard-coding custom fields Ids, you can dynamically find custom fields Ids by using Tooling API.

This will also help when you move code from one instance to another instance as you don't have change hard-coded value in URL.

Now imagine the scenario where you need to pre-populate the contact fields when user clicks on some button or link. For this you have to create URL to redirect user to new contact page. URL format will be as mentioned below:

https://{baseURL}/{object key prefix}/e?{field Id}={field value}&CF{lookup field Id}_lkid={parent recordId}&CF{lookup field Id}={parent record name}&retURL=/{retURL}

Where
  • baseURL : Your org domain URL. Use  "URL.getSalesforceBaseUrl().toExternalForm();" to find domain URL.
  • object key prefix : First 3 digit of object record ID. For example, for Account -001, Contact-003, Opportunity-006 etc. Use "Schema.getGlobalDescribe().get(ObjName).getDescribe().getKeyPrefix();" where ObjName is object API name.
  • field Id : If you need to populate custom field, then specify 15 digit custom field Id. You can use above utility class to find custom field Id.
  • field value : specify the value which you want to pre-populate for custom field.
  • lookup field Id : For custom lookup field, you need to specify field id appended by "_lkid" and corresponding 15 digit record of parent record. Remember Lookup field id should be prefix by "CF". Check URL format.
  • lookup field value: In order to populate the parent record name, specify this parameter as field Id and corresponding parent record name in {parent record name}.
  • retURL : URL where you want to redirect user after clicking on cancel button.
Note: In order to pre-populate standard fields, just right click on field in new record page and click inspect and find " <label for" xxx"> attribute as mentioned below:



Here we want to pre-populate contact last name, so after inspecting the element, we got label value as "name_lastcon2". So in order to populate last name, in URL pass parameters as

https://xxxx.my.salesforce.com/003/e?name_lastcon2=sunil&retURL=%2F003%2Fo

Now consider a scenario where we want to pre-populate below contact fields:
  • LastName
  • Email
  • Birthdate
  • Level__c (custom field)
  • Category__c(custom lookup field)

I have created a Utility class "ToolingAPIUtility"  which will return all custom field Ids of object. Just pass object API name to its static method "findCustomFieldsid". This method will return Map (Key--> field API name, Value-->custom field Id) and this can be used to create URL to pre-populate the fields while record creation.
Below is complete code to generate URL for populating above mentioned field values and required utility class.

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   

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    

Sunday, May 7, 2017

Finding RecordType access to different profiles by using Metadata API

Consider a scenario in which you have an object which is having more than 10 recordtypes. Now you need to find out which all profiles have access to which recordtype. In order to achieve this, admin has to go to each profile and check the recordtype access. Imagine if you have more than 10 profiles which have access to different recordtype of this object.

In order to avoid this manual effort, I have created a VF page where user can select object and particular profile or all profiles and can see the result on a report. I am using metadata API to achieve this.

Please find below unmanaged pakage installation URL:

https://login.salesforce.com/packaging/installPackage.apexp?p0=04t90000000NPA0

Or you can download the code from Git by using below URL:

https://github.com/Sunil02kumar/RecordType-Access-For-Profiles

After installation,  open tab "RecordType Access Finder". You may get "Unauthorized endpoint URL".


Add endpoint URL to remote site setting.

After opening the tab, select the object and profile for which you want to get report for recordtype access to different profiles. You can also specify "All" for profiles.




If you are getting some error by selection all profiles and clicking on "Retrieve and generate report" button, then it means you profile metadata file size is more so in this case, select one profile at one time and click on "Retrieve and generate report" button.
After this operation is finished, then select another profile and again click on "Retrieve and generate report" button. Repeat same process for all profiles you want to check.

Now click on report link and you will be redirected to SFDC standard report where you can see different recordtypes assigned to different profiles.



Looking forward for everyone's comment and feedback!!!

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