Sunday, March 29, 2015

Algorithm to Convert 15-Digit ID to 18-Digit ID

Salesforce.com Record ID's exist in 2 forms

  • The 15-Digit case-sensitive form
  • The 18-Digit case-insensitive form

How to get Record ID's?

  • URL (after logging in Salesforce and clicking a particular record)
  • Salesforce Reports
  • API
  • SOQL (Salesforce.com Object Query Language)

Reports and Object ID's

  • Salesforce Report returns 15-Digit ID's
  • The Report framework does not expose ID's for all objects

API and Object ID's

  • The API always returns 18-Digit ID's
  • For updates, the API will accept either the 15-Digit or 18-Digit format

Algorithm to Convert 15-Digit ID to 18-Digit ID


Step 1






Step 2





Step 3





Step 4





Step 5





Step 6






Format for Salesforce.com Record ID's

Salesforce.com Record ID's exist in 2 forms

  • The 15-Digit case-sensitive form
  • The 18-Digit case-insensitive form

How to get Record ID's?

  • URL (after logging in Salesforce and clicking a particular record)
  • Salesforce Reports
  • API
  • SOQL (Salesforce.com Object Query Language)

Reports and Object ID's

  • Salesforce Report returns 15-Digit ID's
  • The Report framework does not expose ID's for all objects

API and Object ID's

  • The API always returns 18-Digit ID's
  • For updates, the API will accept either the 15-Digit or 18-Digit format

Saturday, March 28, 2015

External ID's in Salesforce

What is External ID?

When importing data into Force.com apps, you can use External IDs to prevent duplicate records from being created as a result of the import operation. It allows use of relationships defined in legacy systems when importing data into Force.com apps.

Considerations

  • It is a flag that can be added to a custom field to indicate that it should be indexed and treated as an ID.
  • It is a user-defined cross-referenced field.
  • It can be created for custom field type (Text, Number or Email ONLY).
  • Each object can have up to 7 (seven) external Ids (as of Spring '15).
  • Configure UPSERT action to traverse object relationships defined in your Force.com app, but use External Id's from legacy system to discover Force.com record ID's.

Benefits

  • It helps improve Report and API SOQL performance.
  • It can be used with UPSERT DML operation to seamlessly integrate apps with other systems.
  • No need to know Force.com record Id's to load data.
  • Very convenient for data integrations and migrations.

What is UPSERT?

UPSERT is an API function that combines INSERT and UPDATE into a single call. It uses an indexed custom field or External Id to determine whether to create a new object or update an existing object.
  • If the External Id is not matched, then a new object is created.
  • If the External Id is matched once, then the existing object is updated.
  • If the External Id is matched multiple times, then an error is reported.
  • Use UPSERT when importing data to prevent the creation of duplicates.

Useful Resources

System / Audit Fields in Salesforce

Every system or application has system fields for auditing. In Salesforce these fields are referred as "Created Date, Last Modified Date, Created By, Last Modified By".

Usually System/Audit fields are READ ONLY and automatically populate by Salesforce.com. But there is a time when you need to import data into these fields.


Use Case

A company has a database to store Invoices and now they have decided to use Salesforce and migrate all Invoices into Salesforce objects. They want to migrate system / audit fields (Created Date, Last Modified Date, Created By, Last Modified By) as well along with other data.


What Does it Do?

Allows you to set Created Date, Created By, Last Modified Date, Last Modified By
Useful for migrating data from external systems and preserving history
By default, System / Audit fields are Read Only


How Do you Get it?

By default, this feature is not enabled in Salesforce.com organisations. You need to log a case to Salesforce.com customer support to enable this feature.


Considerations

  • Audit fields can only work on INSERT / CREATE of new records.
  • Generally READ ONLY for existing records. Audit fields do not work on UPDATE / MODIFY of records.
  • Only accessible through API
  • Backward compatible with all SOAP-based API's
Audit fields will only be enabled for following objects (as of Spring ‘15)
  • Lead
  • Account
  • Contact
  • Opportunity
  • Case
  • Tasks and Events
  • All Custom Objects
Other Objects
  • Attachments
  • CampaignMember
  • CaseComment
  • FeedComment
  • FeedItem
  • Idea
  • IdeaComment
  • Vote 
  • Contracts
Additionally, Audit fields from the Lead object related to conversion can also be defined on INSERT / CREATE:
  • ConvertedDate
  • ConvertedAccountId
  • ConvertedContactId
  • ConvertedOpportunityId

Useful Resources

Saturday, March 21, 2015

Activities Tab

Activities Tab

A custom tab to show Activities (Tasks & Events) in Salesforce.com.


Overview

In Salesforce.com we do not have Activities (Tasks & Events) tab like we have for other standard objects (Lead, Account, Contact, Opportunity etc). This piece of code allows end users (Non-Salesforce Expert, Administrators and of course Developers) to create tab for Activities (Tasks & Events) without writing much of code.






Required Components for this functionality:

  • Visualforce Page
  • Visualforce Tab

Visualforce Page Code:

<apex:page>
    <apex:enhancedList type="Activity" height="500"/>
</apex:page>


Steps to Create a Tab for Activities:



Use Custom Setting Efficiently in Apex

Use Custom Setting Efficiently in Apex

What is Custom Setting?

Custom Settings are similar to custom objects and gives ability to create custom sets of data. The data can be associate to an organisation, profile, or specific user. 

Data Types for Custom Setting fields:


  • Checkbox
  • Currency
  • Date
  • DateTime
  • Email
  • Number
  • Percent
  • Phone
  • Text
  • Text Area
  • URL

Note: The data in these fields are cached with the application.

Types of Custom Settings

There are two types of custom settings:

  • List
  • Hierarchy


List

A type of custom setting that provides a reusable set of static data that can be accessed across your organisation.

For example you have a custom setting for Status Code. It has 2 fields:
Name (object Name field same as when you create a custom object)
Code (Text field)

How to access this List type custom setting in Apex:

// Method 1
// Returns a map of the data sets defined for the custom setting.
Map<String, Status_Code__c> mapStatusCodeCustomSetting = Status_Code__c.getAll();
for(Status_Code__c mandatoryRoles : mapStatusCodeCustomSetting.values()){
}

// Method 2
for(Status_Code__c mandatoryRoles : Status_Code__c.getAll().values()){
}

// Method 3    
Status_Code__c statusCodeCS = Status_Code__c.getValues('400');
String statusCode = statusCodeCS.Code__c;

// Method 4
String statusCode = Status_Code__c.getValues('400').Code__c;


Hierarchy

A type of custom setting that uses a built-in hierarchical logic that checks the organisation, profile, and user settings for the current user and returns the most specific, or “lowest,” value. 

How to access this Hierarchy type custom setting in Apex:

// Method 1
// Returns a custom setting data set record for the current user.
Authentication_Token_Setting__c authTokenSetting = Authentication_Token_Setting__c.getInstance();

// Method 2
// Returns the custom setting data set record for the specified User ID or Profile ID. 
Authentication_Token_Setting__c authTokenSetting = Authentication_Token_Setting__c.getInstance(Userinfo.getUserId());

// Method 3
// Returns the custom setting data set record for the organization.
Authentication_Token_Setting__c authTokenSetting = Authentication_Token_Setting__c.getOrgDefaults();

// Method 4
// Returns the custom setting data set record for the specified User ID or Profile ID.
Authentication_Token_Setting__c authTokenSetting = Authentication_Token_Setting__c.getValues(Userinfo.getUserId());

Note:

  • For Apex saved using Salesforce API version 21.0 or earlier, this method returns the custom setting data set  record with fields merged from field values defined at the lowest hierarchy level, starting with the user.  Also, if no custom setting data is defined in the hierarchy, this method returns null.
  • For Apex saved using Salesforce API version 22.0 or later, If no custom setting data is defined in the hierarchy, the returned custom setting has empty fields, except for the SetupOwnerId field which contains the user ID.


Benefits of Using Custom Setting:


  • Custom settings data is exposed in the application cache, which enables efficient access without the cost of repeated queries to the database.
  • Custom settings data can be used by formula fields, Visualforce, Apex, and the Force.com Web Services API.
  • You can make visibility of custom setting public or protected.


DON'T:

Don't query custom settings data using Standard Object Query Language (SOQL). It doesn't make use of the application cache and is similar to querying a custom object. 

Note: You can create up to 2 MB data in custom settings.



Use Static Resources to Create Custom Settings Data

// Publicly exposed Data Factory Class for Test class
@isTest
public class TestDataFactory{
    public static List<Status_Code__c> createStatusCodeCustomSettingByStaticResource(){
        // Create records for a custom setting Status_Code__c
        // using a sample .CSV file "StatusCodes" stored in Static Resource
        List<Status_Code__c> lstStatusCodeSetting = Test.loadData(Status_Code__c.sObjectType, 'StatusCodes');
        return lstStatusCodeSetting;
    }    
}

// Main Test Class to Test the functionality
@isTest
private class StatusCodeTest{
    @isTest
    static void testStatusCode(){
        // Call publicly exposed method of Test class to create data in a custom setting "Status_Code__c"
        // via CSV file stored in a Static Resource 
        List<Status_Code__c> lstStatusCodeSetting = TestDataFactory.createStatusCodeCustomSettingByStaticResource(); 
    }
}

Useful Resources:


Testing in Apex

“one unit test is infinitely better than no unit test”

Testing in Apex

Testing is an important part of the development process. Like other programming languages, Apex also provides a testing framework that allows you to write unit tests, run, check and have code coverage of your test results.
In Salesforce before you deploy Apex to your Salesforce.com Production organisation or package it for the Force.com AppExchange, you must have at least 75% of your Apex code covered by unit tests, and all of those tests must complete successfully. 

The most important point and advantage to create a separate class for Apex Test methods is that it does not count against your organisation limit of 3 MB for all Apex code. 

Apex Test Class Syntax:


// This class contains test methods with different data access levels.
@isTest
private class className{
    
    // Method 1
    static testMethod void methodName1(){
              // your logic here
    }
    
    // Method 2
    @isTest static void methodName2(){
              // your logic here
    }
    
    // Method 3
    @isTest (SeeAllData = true)
    static void methodName3(){
              // your logic here
    }
    
    // Method 4
    @isTest
    static void methodName4(){
              // your logic here
    }

}


// All test methods in this class can access all data of Salesforce organisation.
@isTest (SeeAllData = true)
private class className{
    
    // Method 1
    static testMethod void methodName1(){
              // your logic here
    }
    
    // Method 2
    @isTest
    static void methodName2(){
              // your logic here
    }
    Note: You don't need "@isTest (SeeAllData = true)" here because class has already been defined with the @isTest(SeeAllData=true) annotation.

}


First thing to notice is that we use the @isTest annotation. All classes marked with "@isTest" annotation will make classes to run in Testing context only. Also, you see we use "testMethod" keyword and "@isTest" annotation for defining methods within Test classes. Both are interchangeable the only difference is you can access your organisation's data by using "@isTest (SeeAllData = true)" annotation individually with the method.


Winter '12 Features for Apex Testing

With Winter '12 releaseForce.com platform provided you a capability to create Public test classes that expose common methods for test data creation. These public methods can be called by tests outside the test class for setting up data that the tests need to run against.

Methods of a public test class can only be called from a running test, that is, a test method or code invoked by a test method, and can't be called by a non-test request. 

// In this class you can create and expose records to called by other test classes
@isTest
public class TestDataFactory{

    public static Account createTestAccount(){
              // create test Account records
    }
    public static Contact createTestContact(){
              // create test Contact records
    }

}


Spring '12 Features for Apex Testing

Spring '12 release came with a feature "Isolation of Test Data for Unit Test". It means with Spring 12 release you can now explicitly mark your test class "@isTest (SeeAllData = true)" to access your Salesforce organisation data.

As we know all Salesforce metadata components associate to a particular Salesforce API version and every version has dependency based on features.

Spring '12 release came up with Salesforce API version 24.0 and announced that Apex code saved using Salesforce API version 24.0, test classes and methods don't have access by default to pre-existing data in the organisation. So, for Apex code saved using Salesforce API version 24.0 and later, use explicitly the @isTest(SeeAllData=true) annotation to grant test classes and individual test methods access to all data in the organisationBut Test code saved against Salesforce API version 23.0 or earlier continues to have access to all data in the organisation and its data access is unchanged.


Spring '15 Features for Apex Testing

Finally Spring '15 release has came up with a new annotation "@testSetup" which gives you ability to "Setup Test Data for Entire Class".
With Spring '15 release now you create common test records once and access them in every test method in the test class. All methods that are annotated with @testSetup will be called test setup methods.

Syntax for Test Setup Method (@testSetup annotation)

@isTest
private class className{

           @testSetup static void commonmethodName() {
                               // your logic here
           }

           // Method 1
           static testMethod void methodName1(){
                               // your logic here
           }
    
          // Method 2
          @isTest static void methodName2(){
                               // your logic here
          }

}

For further details of @testSetup method see here


Considerations:

  • Use the @isTest annotation to define classes and methods that only contain code used for testing your application. The @isTest annotation on methods is equivalent to the testMethod keyword.
  • Classes and methods defined as @isTest can be either private or public.
  • Classes defined as @isTest must be top-level classes.
  • Classes defined with the @isTest annotation don't count against your organisation limit of 3 MB for all Apex code. 
  • Classes defined as @isTest can't be interfaces or enums.
  • Methods of a public test class can only be called from a running test, that is, a test method or code invoked by a test method, and can't be called by a non-test request.
  • You must have at least 75% of the Apex code coverage in your organisation to be able to deploy the code to your Salesforce production organisation.

Useful Resources:

Enums in Apex (Salesforce)


Enums in Apex


Apex is probably the first on-demand programming language by Salesforce.com that provides easy, fast and robust ways to design, develop, test and deploy apps on Force.com platform. Apex is more similar to Java but it has some differences which makes it very unique programming language.

Apex also has Enums like we have in Java and other programming languages with some unique differences. 

Let's take an example: We need to send data FROM different objects of Salesforce TO some External 3rd party system.

Below is the code which gives you an idea that how we can use Enums here instead of using variables (e.g. to check the object type).



public class IntegrationImplementation{
    // Declare Enums
    public Enum serviceType {ACCOUNT, CONTACT}
    
    // a method to send Notification based on Object Type
    public static String sendNotification(IntegrationImplementation.serviceType objectType, Set<Id> objectIds){
        String resultCallOutNotification = '';
        // For Account
        if(objectType == serviceType.ACCOUNT){
            // logic here
        }
        // ... logic here for other object types
        return resultCallOutNotification;
    }
}

public class callOutExternalSystem{
    public static void sendAccountToExternalSystem(){
        Set<Id> setAccountIds = new Set<Id>();
        // For Account
        String resultNotification = IntegrationImplementation.sendNotification(IntegrationImplementation.serviceType.ACCOUNT, setAccountIds); 
    }
}

For further details:

Sunday, March 15, 2015

@testSetup - Create Common Test Data Efficiently

With Spring '15 release now you create common test records once and access them in every test method in the test class. All methods that are annotated with @testSetup will be called test setup methods.

Syntax for Test Setup Method (@testSetup annotation)
@testSetup static void methodName() {}

Let's take an example. You need to create an Account and a Contact record in Apex test classes (@isTest).


// Test Data Factory class
@isTest
public class TestDataFactory{
    public static Account createAccount(String accountName, String accountIndustry){
        Account acct = new Account();
            acct.Name = accountName;
            acct.Industry = accountIndustry;
        return acct;
    }     

    public static Contact createContact(String contactFirstName, String contactLastName, Account acct){
        Contact cont = new Contact();
            cont.FirstName = contactFirstName;
            cont.LastName = contactLastName;
            cont.AccountId = acct.Id;
        return cont;
    }
}


// Main Test class to create Account and Contact
@isTest
private class AccountContactTest{
    @testSetup static void setupCommonData(){
        Account acct = TestDataFactory.createAccount('Salesforce.com', 'Technology');
        insert acct;
        Contact cont = TestDataFactory.createContact('Marc', 'Benioff', acct);
        insert cont;
    }
    
    @isTest static void testMethodOne(){
        Account queryAccount = [SELECT Id, Name, Industry FROM Account WHERE Name = 'Salesforce.com' LIMIT 1];
        System.assertNotEquals(null, queryAccount);
        System.assertEquals('Salesforce.com', queryAccount.Name);
        System.assertEquals('Technology', queryAccount.Industry);
        
        queryAccount.Name = 'Facebook';
        update queryAccount;
        System.assertEquals('Facebook', queryAccount.Name);

        Contact queryContact = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'Benioff' LIMIT 1];
        System.assertNotEquals(null, queryContact);
        System.assertEquals('Marc', queryContact.FirstName);
        System.assertEquals('Benioff', queryContact.LastName); 
        
        queryContact.FirstName = 'Mark';
        queryContact.LastName = 'Zuckerberg';
        update queryContact;
        System.assertEquals('Mark', queryContact.FirstName);
        System.assertEquals('Zuckerberg', queryContact.LastName);        
    }

    @isTest static void testMethodTwo(){
        Account queryAccount = [SELECT Id, Name, Industry FROM Account WHERE Name = 'Salesforce.com' LIMIT 1];
        System.assertNotEquals(null, queryAccount);
        System.assertEquals('Salesforce.com', queryAccount.Name);
        System.assertEquals('Technology', queryAccount.Industry);
        
        queryAccount.Name = 'Google';
        update queryAccount;
        System.assertEquals('Google', queryAccount.Name);

        Contact queryContact = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'Benioff' LIMIT 1];
        System.assertNotEquals(null, queryContact);
        System.assertEquals('Marc', queryContact.FirstName);
        System.assertEquals('Benioff', queryContact.LastName); 
        
        queryContact.FirstName = 'Larry';
        queryContact.LastName = 'Page';
        update queryContact;
        System.assertEquals('Larry', queryContact.FirstName);
        System.assertEquals('Page', queryContact.LastName); 
    }    
} 

Note: All changes will be Rollback to the common setup data before starting a specific test method.

Benefits:


  • Create common test data easily and efficiently.
  • Reduce the number of lines of code.
  • Reduce test execution time.
  • It can be time-saving when you need to create a common set of records that all test methods depends on.
  • Use system resources more efficiently (Because now system would just need to roll back data from a single test method instead of roll back for each test method).

Considerations:


  • If a test class contains a test setup method, the test setup method executes first, before any test method in the class.
  • Records that are created in a test setup method are available to all test methods in the test class and are rolled back at the end of test class execution.
  • If a test method changes those records, such as record field updates or record deletions, those changes are rolled back after each test method finishes execution. The next executing test method gets access to the original unmodified state of those records.
  • It takes no arguments, and return no value. @testSetup static void methodName(){}
  • @testSetup method only works with the default data isolation mode "@isTest(SeeAllData=true)" for a test class.
  • It does not work with "@isTest(​SeeAllData=​true)". Because data isolation for tests is available for API versions 24.0 and later, test setup methods are also available for those versions only. Otherwise you will get an error: Test class containing a test setup method cannot be annotated with @isTest(​SeeAllData=​true)
  • Multiple @testSetup methods are allowed in a test class, but the order in which they’re executed by the testing framework isn’t guaranteed.
  • If a fatal error occurs during the execution of a @testSetup method, such as an exception that’s caused by a DML operation or an assertion failure, the entire test class fails, and no further tests in the class are executed.
  • If a @testSetup method calls a non-test method of another class, no code coverage is calculated for the non-test method. 

See further details for @testSetup method

Data.com Duplicate Management

Preventing users to create duplicate records is definitely important and takes vital role in every organisation's data. Salesforce introduced a new feature "Data.com Duplicate Management" with its Winter '15 release as a Beta program and with Spring '15 release Salesforce has made this feature GA (Globally Available) due to its high demand by customers.

It gives Users ability to:
  • Block users to create duplicate records.
  • Ignore duplicates and create duplicate records.
  • Create Reports of those duplicates which are ignored.
Note:
  • It only available in Professional and higher Salesforce editions (e.g. Enterprise, Performance, Unlimited, and Developer editions).
  • It uses Data.com technology, but does not require a Data.com license.

Let's take an example: We usually have a requirement where we need to enforce users to NOT create multiple Contact records with the same Email address.

Let's use this Data.com Duplicate Management feature to achieve this.


Step 1: Create a Matching Rule


What are Matching Rules?
Matching Rules compare field values to determine whether a record is similar to existing records to be considered a duplicate record.

For example, a matching rule can specify that if the Email and Phone values of two records match exactly, the records might be duplicates.

You can follow steps mentioned here to create a Matching Rule to check Email field on Contact object.

Your configuration should look like as below:















Step 2: Create a Duplicate Rule


What are Duplicate Rules?
Duplicate rules tell Salesforce what action to take when duplicates are identified.

For example:
  • A duplicate rule can block users from saving records that have been identified as possible duplicates
  • A duplicate rule can alert users that they may be creating a duplicate, but allow them to save the record anyway.
You can follow steps mentioned here to create a Duplicate Rule for Email field on Contact object.

Your configuration should look like as below:




























Note: Do not forget to Activate both a Matching Rule and a Duplicate Rule.

Step 3: Let's Test these Rules

  • Create a new Contact record with the Email Address populated.
  • Create another Contact record with the Email Address you used earlier.
  • You should be blocked to create a new Contact record with the Email address which already exists.
















Here now User is unable to create duplicate Contact record. That's good but now User will not be able to do any further action for this Contact.

Sometimes you actually want to alert Users and but also allow them to create duplicate records so they can perform further actions to won the deal.

Let's make some changes in "Duplicate Rule" configuration. Your configuration now should look like as below:




















Step 4: Let's Try this updated Duplicate Rule

  • Create a new Contact record with the Email Address populated.
  • Create another Contact record with the Email Address you used earlier.
















See the difference previously you did not have option to Ignore duplicate Alerts. But now you should be blocked BUT you have options to create a new Contact record with the Email address which already exists.

Limitations:
1) It is available for Leads, Accounts, Contacts, and Custom objects.
2) It does not work with Person Accounts, Opportunities and all other objects.
3) Duplicate rules don’t run when records are created in following ways.

  • When records are created using Quick Create.
  • When leads are converted to accounts or contacts and your organisation doesn’t have the “Use Apex Lead Convert” permission.
  • When a record is restored with the Undelete button.
  • When records are added using Exchange Sync.
  • When records are manually merged.

4) In some cases, if duplicate rules are set for an alert to show when potential duplicates are found, users will always be blocked from saving records and will not see a list of possible duplicates. Examples of this include the following.

  • When records are added using the data import tools.
  • When a person account is converted to a business account (and the newly created business account matches existing business accounts).
  • When records are added or edited using Salesforce APIs.

See further details for Duplicate Management Limitations