Category Archives: Company Update

Wedid: Salesforce As Retail Coordination System


A consultancy company needs to provide solution to the customer encompassing a portfolio of the retail information relating to the property, budgeting, landlord, solicitor etc. The challenges identified in the solution are:

  • each detailed information need to be linked to create a connected entity as documents need to be generated at each record level containing the summarised entities
  • all steps need to be tracked in each of the leasing opportunities to capture the offer/counter offer stages
  • elaborate documents need to be generated



All retail entity is tracked and managed from the objects in the diagram to create a linkage.  Precise data modelling is required. When documents are generated, retrieving information for each entity will not be an issue.

Each offer stage will be tracked individually. Once a final offer is decided, a trigger is implemented to roll up the final result to the opportunity.

Related Objects Account
Associated Entity (Custom)
Account Site (Custom)
Site (Custom)
Offer (Custom)
Components Data Modelling
Salesforce Apex
Conga Composer
Complexity Medium

Deploying Salesforce Process Builder

You may have developed process builder to streamline your business processes in sandbox and you may want to deploy them into production instances.

Do not panic if you are not seeing the component “Process Builder” or any similar term in the change set you are creating. They are actually grouped together with flows and its part of the component type “Flow Definition”.


Once, the processes are deployed to production just double check if the processes are still active and if it not, activate it if you would like to start use them in your production.

Distribution Engine App: Assignment Algorithm

Distribution Engine allows you to choose the types of algorithm matching. For example, assign owner based on certain criteria in the record.

Round Robin

Sequential assignment among the team member that ensures objects are assigned out fairly. For example:

Assignment / User User 1 User 2 User 3
Record #1 1  x  x
Record #2  x 2  x
Record #3  x  x 3
Record #4 4 x x
Record #5 x 5 x
Record #6 x x 6

Sequence used for the round robin will order by who was assigned to last. This ensures that the team members who have not been assigned to recently are first in line.

Round robin with sticky assignment

Sticky assignment assigns duplicated records to the same owner. For example, duplicated records with same email address will be assigned to the same owner.

Note!: Sticky assignment is case sensitive.

Round robin lookup owner

Match records in other objects and assign to the same owner. For example, Lead has the same company name as account name, assign to the same owner.

Note: This matching algorithm is NOT case sensitive.

Salesforce: Sending Email to Custom Email Address

Question: Imagine that you have a custom email field name – ‘Secondary Email Address’. When sending an email to a Contact, can you send it to the secondary email address instead of the Contact email address?

Answer: Yes, you can. When sending out an email, you should be able to choose whether if you would like to send it to the primary email address or any other email addresses. For example:

Second email

NOTE!: This feature is available for Contact & Person Account. It is not available for Account or Opportunity.

Salesforce: Restoring Deleted Records from Recycle Bin

Usually after a record is being deleted, it will be stored in the recycle bin for 15 days. These records are being recognised by a checkbox field called IsDeleted. When a record is being deleted, this checkbox will automatically be checked.

Question: Can we update the IsDeleted checkbox to True?

Aparently this checkbox is made READ ONLY. So how can we restore records from the recycle bin?

WARNING: You will not be able to restore any records if they are being HARD DELETED.

Method #1: Manual restore

If you only have a few data, suggest that you restore them manually. Simple go to Home -> Recycle Bin, select the records that you would like to restore and click on ‘Undlete’ button.

* Once records are restored, any child tied to these records will also be restored.

Method #2: Developer Console

You can try running a few lines of codes in the developer console. Depending on the scenario, you can program the code to restore based on different condition.

For example: Restore all Account where Isdeleted = TRUE and Created Date = TODAY().

Method #3: Re-importing deleted records

You can use Apex Data Loader to export all deleted data and re-import them. Apex Data Loader ‘Export All’ allows you to export ALL data including any soft deleted data (in recycle bin).

*This will not restore any child records as this method is as if you are re-importing all the data from scratch.*

Method #4: Workbench

You can also try Salesforce Workbench where it can query all deleted records and undelete them straight from Workbench.

Salesforce: Restrict Opportunity to Specific Pricebook

Question: Is there anyways that you can restrict specific Account to only use a specific Pricebook? For example, Account – Acme Pty Ltd needs to be tied to only Acme Pricebook. Therefore, all the Opportunity created under Acme Pty Ltd can only use Acme Pricebook.


Option #1: Validation rule

  1. Create a lookup from Account to Price Book
  2. Create a validate rule on the Opportunity – check the PriceBook ID on Opportunity against Price Book on the account. Throw error if does not match.
    For example: Pricebook2Id <> Account.Price_Book__c.


Option #2: Trigger

  1. Create a lookup from Account to Price Book
  2. Create a trigger on Opportunity to populate the Price Book ID from the account
  3. Optional: You can also validate in the trigger if the sales rep tries to change the price book.


Additionally, you can also implement a checkbox in Opportunity to apply flexibility to above solutions. This is to cater for a scenario where one of the Acme Pty Ltd Opportunity needs to use Standard Pricebook. So, when this checkbox is checked for this particular Opportunity, the user can then choose any other pricebooks.

Sample Validation rule will look like: NOT(ISBLANK(Account.Price_Book__c)) && NOT(ISBLANK(Pricebook2Id))  && Ignore_Account_Pricebook__Checkbox__c == FALSE && Pricebook2Id <> Account.Price_Book__c

Form Assembly E-Signature

Form Assembly now allows you to capture e-signature. So how can we capture and store the signature image in Salesforce?

The sample scenario used in this article is to capture the signature image and store in Salesforce as attachment.

Connector setup:

After enabling e-signature in Form Assembly, you will need to setup the connector in Form Assembly. For example:
esignature as attachment

The form will automatically attach the image to Salesforce when %%ESIG_SIGNATURE_IMG%% is mapped to body. For more aliases, refer to the documentation here –

  • You need to  specify an extension in the File Name mapping, ie: Signature.png. If this is not done, the image will not have an extension when it is downloaded from Salesforce.
  • You won’t be able to see the actual image inside Salesforce, as it will send it as an attachment or download link.

Salesforce: Setting Private User Access Consideration

When an organisation has multiple branches where different user channel can access Salesforce, it’s only common the sharing settings for User is set to private. This will help to prevent a user from viewing another user.

However, there is one setting that needs to be considered when making user access private – Group tasks. This feature in enabled by default in Salesforce to allow assigning tasks to groups – role and subordinates/public groups as shown below.


Disabling this feature helps mask and not expose the list of roles to the users. Simply navigate to Setup > Activities Setting > (uncheck group tasks) to turn off this feature.


Imagine if you are providing support with different level of subscriptions and would like to have different priority given to different level of support.
ie: Gold Member Subscription will have higher priority over Silver Member Subscription.
Prioritising Email to Case Routing
By using Email to Case routing, you will be able to receive cases from different subscriber with different priority set. For example:

  • Email from needs to have a high priority
  • Email from needs to have a medium priority
  • Email from needs to have a low priority

Below image is where you can set the Case priority coming from different email address. servlet.FileDownload  Once routing is set up, support sent to different email address will automatically have priority populated and Support engineers can work on the Cases accordingly.

Salesforce Apex: Namespace and Field Name in AggregateResult

In Salesforce SOQL, we can use the aggregate function to summarize data in query. When an aggregate function is used, Salesforce will return the result as AggregateResult object and we can retrieve the value by calling AggregateResult.get(‘field name’). For example:

for(AggregateResult ar : [select count(Id), Business_Type__c from Account group by Business_Type__c]){
	system.debug(ar.get('expr0'));		//get the value of count(id)
	system.debug(ar.get('Business_Type__c'));	//get the grouped by field value

However, things get a little bit tricky when you have a namespace in the Salesforce instance and you have custom field in the SOQL. The sample query will still work, but you will get an error saying “Invalid aggregate result field” when you are trying to retrive the value of custom field.

To overcome this, you can choose to:

Option 1

Prepend the custom field with a namespace, for instance,

system.debug(ar.get('namespace__Business_Type__c'));	//get the grouped by field value

Option 2

Use alias in the SOQL to represent a custom field in query result.

for(AggregateResult ar : [select count(Id), Business_Type__c businesstype from Account group by Business_Type__c]){
	system.debug(ar.get('businesstype'));	//get the grouped by field value

Personally, I would prefer to use Option 2 as I don’t have to hard code the namespace in all the SOQL.