Thursday, October 29, 2015

Salesforce: Getting Started with Autolaunched Flow

Do not confuse Flow with all time favorite Workflow (by Salesforce admin). But, workflow have it limitations, example: cannot update field by reference. Therefore you need developer to write apex trigger in the past.

Process Builder which recently announced, able to cover this without the need to hire developer. It is also simple and considered as configuration, therefore you do not need apex test class coverage.

Process Builder alone is pretty powerful, but with ability to launch Flow, it become even more powerful. In some scenario, Process Builder alone cannot handle complex business process, such as: to query an object to get the Id and use that Id for new record creation.

As of now, actions supported by Process Builder:
  • Create a record (not possible using workflow, standard and custom object available)
  • Email Alerts (exist in workflow)
  • Post to Chatter (not applicable with workflow)
  • Quick actions (not applicable with workflow)
  • Submit for Approval (not applicable with workflow)
  • Update records (limited functionality with workflow, standard and custom object available)
Calling Flow and Apex class is additional actions available in Process Builder.

With addition using Flow, we can do:
  • Record Create
  • Record Delete
  • Record Lookup (for query)
  • Record Update

Use Case: auto share record of a private object to user defined in a custom field.

Solution: Process Builder + Autolaunched Flow

Autolaunched Flow
Why it called autolaunched flow? Similar with workflow, this type of flow don’t require any user interaction to start . It can be launched from Apex class or Process Builder as an action. They can’t contain steps, screens, choices, or dynamic choices in the flow. Use autolaunched flow to automate complex business processes without writing code. In order to launch a flow from a process, you must activate the flow.

For this scenario, We just need 1 process only, which is Record Create. Technically, to share a record, we need to create a record for the object with end with __Share. For this case, the object called Insurance__c, so the sharing object called Insurance__Share.

Screenshot below show 2 fields value to populate on record creation will come from the record, which stored as variables: RecordIdFromScreen and UserIdFromScreen.

Process Builder

The only action for our use case in the Process Builder is calling an autolaunched flow created earlier. We need have 2 variables in that flow, make sure the variable type is Input only, because we are going to use them to receive values from the record to the flow, we name the variables as:
  • RecordIdFromScreen to store Record Id
  • UserIdFromScreen to store User Id

So, before we create Process Builder, we have to prepare the Flow.

As long as you understand the object structure and fields, this blog show you how easy to create a Process Builder powered with autolaunched Flow.

Monday, October 26, 2015

Salesforce: Attach File with code

In previous blog, we discussed about how to attach file to a record using "File" and "Attachment". As you read in that blog, to attach file as Attachment, user need to have Edit permission on the parent record.

In some use cases, permission to edit record is not ideal, example: support users not supposed to edit an opportunity record, but they just need to read the opportunity and may need to attach file. Chatter File is a great option for this limitation, but for some reasons, company may just want to use Attachment, rather than split between Attachment and File.

In this blog, we will introduce to use Apex class for user to upload file as Attachment. Remember that when using Apex class, by default it will not check user permission for the record, as long as user able to open the record and the user profile have access to the Apex class and Visualforce page.

So, here are few items and steps needed to built custom attach file functionality as Attachment, in this example, we are going to use Opportunity object:

1. Create Apex Class
This is the core program to upload the file to Salesforce and attached to the parent record.
1:  public class TicketAttachment   
2:  {  
3:    /* Start - Variables */  
4:    public Id recId         {get;set;}   
5:    public Attachment objattachment {get{  
6:                      if(objattachment == null)  
7:                        return objattachment = new Attachment();  
8:                      return objattachment;    
9:                     }set;  
10:                   }  
11:    /* End - Variables */  
13:    /* Start - Constructor */  
14:    public TicketAttachment(ApexPages.StandardController ctlr)   
15:    {   
16:      recId = ctlr.getRecord().Id;      
17:    }   
18:     /* End - Constructor */  
20:    /*  
21:      * MethodName    : upload  
22:      * param       : -  
23:      * Description    : This function used to upload Attachment and redirect the user back to parent  
24:    */  
25:    public PageReference upload()   
26:    {  
27:      objattachment.OwnerId = UserInfo.getUserId();  
28:      objattachment.ParentId = recId;  
29:      try   
30:      {  
31:       insert objattachment;  
32:      }   
33:      catch (DMLException e)   
34:      {  
35:       ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));  
36:       return null;  
37:      }   
38:      return new Pagereference('/'+recId);  
39:    }  
41:    /*  
42:      * MethodName    : cancel  
43:      * param       : -  
44:      * Description    : This function redirect the user back to parent.  
45:    */  
46:    public PageReference cancel()   
47:    {  
48:      return new Pagereference('/'+recId);  
49:    }  
50:  }  

2. Create Apex Text Class
Each Apex class in Salesforce need to have a test class with minimum of  75% test coverage.

1:  /**   
2:  * \arg Description   : Test class for TicketAttachment controller class.  
3:  */  
4:  @isTest  
5:  private class Test_TicketAttachment   
6:  {  
7:    static Opportunity objTicket;  
8:    static PageReference pageRef;  
10:    //Preparing data for testing the functioanlity  
11:    static testMethod void setUpData()  
12:    {  
13:      objTicket = new Opportunity(Name='SA', StageName='Prospecting', CloseDate=Date.newInstance(2016, 2, 17));  
14:      insert objTicket;  
15:    }  
17:    //checking for upload functionality  
18:    static testMethod void test_FileUpload()   
19:    {  
20:      Test.startTest();  
21:      setUpData();  
22:      system.debug('==objTicket==='+objTicket);  
24:      pageRef = new PageReference('/apex/TicketAttachmentVF?id=objTicket.Id');   
25:      Test.setCurrentPage(pageRef);  
26:      pageRef.getParameters().put('id', objTicket.Id);  
28:      ApexPages.StandardController stdCTR = new ApexPages.StandardController(objTicket);  
29:      TicketAttachment objController = new TicketAttachment(stdCTR);  
31:      Attachment objAtt = new Attachment(Body = Blob.valueOf('Test Body'), Name = 'Test Attachment', ParentId = objTicket.Id);  
32:      insert objAtt;  
34:      pageRef = objController.upload();  
35:      //System.assertEquals(pageRef.getUrl(),'/'+objTicket.Id);  
37:      pageRef = objController.cancel();   
39:      Test.stopTest();  
40:    }
42:  }  

3. Create Visualforce Page
This Visualforce page served as user interface for user to upload a file.
1:  <apex:page standardController="Opportunity" extensions="TicketAttachment">   
2:    <apex:sectionHeader subtitle="Attachment Upload Example"/>  
3:    <apex:form enctype="multipart/form-data">  
4:      <apex:pageMessages />  
5:      <apex:pageBlock title="Upload a Attachment">  
6:        <apex:inputFile value="{!objattachment.body}" filename="{!}" id="file"/>  
7:        <apex:pageBlockButtons location="bottom">  
8:          <apex:commandButton action="{!upload}" value="Save"/>  
9:          <apex:commandButton action="{!cancel}" value="Cancel"/>  
10:        </apex:pageBlockButtons>  
11:      </apex:pageBlock>  
12:    </apex:form>  
13:  </apex:page>  

4. Create Custom Button or Link
This is standard Custom Button or Link, select Content Source = Visualforce page

5. Add Custom Button or Link to Page Layout
Custom button or link created will not appear in page layout until you add them.

6. Add Apex Class and Visualforce Page to user profile
Each user need to use apex class and visualforce page functionality need to have apex class and visualforce added to their Profile or Permission Set.

ReferenceSalesforce: Attach File to a Record

Sunday, October 25, 2015

Test Salesforce Mobile App with one/

Before Winter '16 release, we can use one/ append to the web browser URL to test or to demo Salesforce1 mobile app without need to use mobile device, as long as select Enable the Salesforce1 mobile browser app, from Salesforce1 Settings setup menu, example: But since Winter '16 release, which introducing Lightning Experience, using the same method will give you error message You can't access Lightning Experience (if you have not enable Lightning Experience).

But, if you have enable Lightning Experience, with above URL, it will re-direct to and bring you to Lightning Experience UI.

So, how to test Salesforce1 mobile app from web browser since Winter '16 release?

1. Developer tool
Use latest version of Google Chrome (as of now version 46) or latest Opera web browser (as of now version 32) -- do you know that Opera is using Chromium engine? Login to Salesforce and select Developer tools.

Change the URL with one/, example:, you can select a mobile device type here.

Note: you still need need to select Enable the Salesforce1 mobile browser app, from Salesforce1 Settings setup menu to use Developer tools.

2. Chrome browser extensions
There are a few Chrome browser extensions available for free to emulate Salesforce1 mobile app.

S1 Demo
This extension adds a small phone icon in the omnibar if you are on a current instance. Clicking the phone icon will open a window with roughly the same resolution as an iPhone 5 to the one/ for that Salesforce instance.  Handy for doing quick demos of Salesforce1 mobile applications on a desktop browser. The extension work in both "classic" and the Lightning UI.

Mobile User-Agent
Once this extension installed and enabled, you will notice a new icon with mobile image added to Chrome browser bar, click the icon will change the color to orange, but nothing else obviously change. With Mobile User-Agent enabled, you still need to change the browser URL to one/, example:, you will notice it does not bring you to Lightning Experience UI anymore.

Salesforce1 Simulator & Salesforce1 Sandbox Simulator
You need to run this simulator from Google App Launcher, as the name said, Salesforce1 Sandbox Simulator use to login to sandbox instance, while the former one for Production instance. You need to login to Salesforce from simulator with your normal Salesforce credential.


Friday, October 23, 2015

Salesforce: Attach File to a Record

Background: support users only have read-only access to Opportunity, but to attach file or edit attachment linked to a record Salesforce, user need to have edit record permission.

Attachment versus File
There are 2 technologies available in Salesforce to attach file to a record in Salesforce. Attachment has been available for long time and do not see any enhancements recently, while File is newer and keep enhance in last few releases, both can be used to link file to a record.

What is the different?
Search *
File name and Content search-able
File name search-able
Permission to add
Read record permission
Edit record permission
Where to add
Chatter feed
“Notes & Attachments” related list
Report *
By user upload the file

* search -  the system need 5-15 minutes to index the content depend on the file size, until the content searchable.
* report - only file shared to the user will be in the report, even you are admin, the file will be not in the report

To attach file to a record, scroll down to "Notes & Attachments" and click Attach File related list.

To use file in an object, first of all, you need to enable Chatter Feed. Example for a custom object called Service, navigate to Setup | Customize | ChatterFeed Tracking, look for Service and select Enable Feed Tracking.

Once Chatter Feed enabled for that object, you will notice "Show Feed" panel added at top of the record page layout.



Click Show Feed to see available actions:

If you do not see File option there, check the object page layout and make sure File action is added in Quick Actions in the Salesforce Classic Publisher.

Files uploaded as "File" from Chatter Feed will be added to "Notes & Attachments" related list.

If you notice the difference of File and Attachment in the related list:
  • Different Type
  • File extension will include in attachment, while not in File
  • You can edit attachment to change Attachment name, but nit for File
  • You can preview File for supported file type, but not for Attachment

Even you are admin, and able to see the file, it will be not in the File report if the file is not share to you.

Following report run by me as admin:

And the same report run as user:

Notice that a file called "fish" is not available in my report, because it do not share to me.

ReferenceConsiderations for Managing Files and Notes Attached to Records

Sunday, October 18, 2015

Salesforce: Accounts with Activities

In many organizations, activity (contain of Task and Event) is widely used to monitor relationship and communication with customer and prospect. Instead of all happened through email, ideally it need to be captured in Salesforce as well.

Customer and prospect in Salesforce is re-present by Account object. Activity logged in Contact and Opportunity will be roll-up to the Account, event the activity is not directly linked to Account.

Use case: management would like to monitor how is the activity logged in Salesforce by Account and by Sales Rep in high-level.

Solution: use Salesforce report to produce real-time data and schedule it for future run.


1. Create formula field in both Account and Activity

The purpose of both this field is to count unique record.

For Account: Setup | Customize | Accounts | Fields
Name the field as Account Count

For Activity: Setup | Customize | Activities | Activity Custom Fields
Name the field as Activity CountUse the same formula as in Account Count above.

2. Create custom report type

Navigate to Setup | CreateReport Types, create Accounts with & without Activities report type with following relationship.

3. Create matrix report

Add following Custom Summary Formula in the report:

# of Accounts = Account.Account_Count__c:SUM
# of Activities = Activity.Activity_Count__c:SUM
% of Accounts with Activities = Account.Account_Count__c:SUM - (RowCount - Activity.Activity_Count__c:SUM)) / Account.Account_Count__c:SUM

  • The first two formula is optional, maybe just on report creation to help to debug if % is correct
  • Account.Account_Count__c:SUM --> this will return unique number of Account
  • Activity.Activity_Count__c --> this will return unique number of Activity, although this should be always unique
  • RowCount --> this is total row return in report query, it will contain number of Account and if the Account have multiple activities, it will return the duplicate value, example: there are 10 accounts, 5 activities, but 3 of them linked to the same account, so row count will become 12 because 3 activities for the same Account.

4. Report result

The same solution can be used for other objects, such as how many percentage of Opportunities with Activities or Contact with Activities.

Wednesday, October 14, 2015

Salesforce: Getting Started with Campaign

Campaign in Salesforce is another module and represent with a tab. The marketing team can elaborate using Campaign to plan, manage, and track within Salesforce. It can be a direct mail program, seminar, print advertisement, email, or other types of marketing initiative.

Campaigns can be organized into hierarchies for easy analysis and child Campaigns will be rolled up into parent Campaign.

Here are few basic items you need to know about Campaign in Salesforce and relation to Lead:

1. Only users marked as Marketing User in user detail able to create Campaign, the user also needs to have Create permission in Campaign object.

2. Create new Campaign from Campaign tab or Create New panel (if Campaign tab exist).

3.Multiple ways to add members (Lead or Contact) to a Campaign:
  • From "Manage Members" button in Campaign
  • From Lead or Contact list view
  • From Lead or Contact report
  • From Lead or Contact related list "Campaign History"

4. For Lead or Contact added to a campaign, open the Lead or Contact, scroll down to Campaign History will show the campaign added.

5. A campaign can be mixed with members from Lead and Contact.

6. Ideally, new campaign member added Add with Status "Sent".

7. To mass update Campaign member Status, go to "Manage Members - Edit Members", otherwise click Edit link in Campaign member to change status one by one.

8. When Lead converted:
  • Campaign Member will change from Lead to Contact, total Contacts will add 1, but total Leads will stay.
  • Primary Campaign Source field in Opportunity will be filled with the latest campaign attached to the Lead
  • Campaign Influence list in Opportunity will be filled will all Campaigns related to the Lead before it converted
  • Converted Opportunity will be added into Opportunity related list in Campaign page, if the Campaign is the Primary Campaign Source

Here a screenshot Campaign with Hierarchy, notice the Total roll-up from child Campaigns.

** if your users do not see the hierarchies field, check field level security for the users.

Let us see the following sample, screenshot below is taken from a Campaign report, "This is Parent" campaign is the parent of "Test 1" campaign, Leads in Campaign is 1 for both campaigns, but since "This is Parent" is the parent campaign, the count in Leads in Hierarchy is sum for all child campaigns plus the parent itself, even the Lead is the same person, so this is not unique count.


Monday, October 12, 2015

Salesforce: Notes (enhanced version)

The enhanced Notes tool (new Notes) is generally available in Winter ’16. But, this new notes will not auto enabled in your org as part of Winter ’16, your admin need to enable it from SetupCustomize | NotesNotes Settings.

Once enabled, admin need to add Notes related list in all page layouts needed. Before activate the new Notes, note is combined with Attachment in the page related list.

After new Noted enabled, notice the "New Note" button disappear from Notes & Attachments related list.

Once new Notes enabled, admin need to add Notes related list to page layout, this is new related list which not exist before you enable the new Notes.

If user need create note after enable the new Notes, they need to click New Note button in Notes related list, note will be stored in the new Notes related list, while existing note will stay in Notes & Attachments related list.

One of the advantage of the new note that it support rich text formatting:

this is the old note

this is the new note

Here a benefits of new the notes:
  • Support rich text formatting, including bulleted and numbered lists.
  • With new Notes users can take notes for Cases, Tasks, and Events. 
  • New Notes support Quick Actions for Chatter Feed, as well as Actions for Salesforce1 mobile app.
  • In Lightning Experience environment, Notes will be auto save.
  • Create a report on your notes
  • The new note is content search-able (stored as Files), once you save the note, give a few minutes for Salesforce to index it before appear in search result.

Here comparison table between old and new note:

Print Notes
As the new Notes is stored as Files, you can create report with report type File and Content and filter with File Type equals SNOTE.

Tips: if you do not see any notes when run the report, you need to remove few columns added by default, such as: Downloaded By, Download Date, and etc.


Page-level ad