How to format phone numbers correctly in Salesforce

Background

We are using Service Voice/Amazon Connect and therefore we want all the phone numbers in our Salesforce org to have the same format starting with +61 so that we can dial out from the phone numbers saved on various records - leads, contacts and accounts.

Introduction

We want to format all phone numbers in Salesforce to the Australian format

  • Mobile +61 4XX XXX XXX
  • Landline +61 3 XXXX XXXX
  • Tollfree number to the format +61 1800 XXX XXX or +61 1300 XXX XXX

It is ideal to use a validation rule on the respective objects to check incorrect formats.

If we use a validation rule instead of a Trigger during a lead conversion it would stop the record from being saved, as the phone number format does not conform to the validation rule. So, for this use case, we believe this is the best solution.

What should be the approach while using a Trigger

It is ideal to have only one trigger per object as the order of execution cannot be controlled. So, It is best to follow the approach of a Trigger accommodating all the contexts of a Trigger execution.

By following this approach, the Trigger will be scalable and is devoid of any business logic and the order of execution can be controlled by using if statements.

In this case we are using insert and update actions of after context because our code logic remains the same for both scenarios. To detach program logic from the Trigger we are making use of utility classes, which will be called for the defined events.


Trigger and Classes

We making use of the Salesforce Developer Console to code the Trigger and Apex Classes.

The triggers on Account, Contacts and Lead are created with ‘after insert’ and ‘after update’ trigger events.

Once the trigger events are defined, the Trigger will be collecting the list of IDs that have undergone the changes, in this case, it will be making use of Trigger.new to collect the list of IDs that have undergone changes to a list variable.

By using the list of IDs we have to run a SOQL query to collect the list of records to be transferred to the Apex Class which will be running the logic to update the format.

The Apex class should be coded with a static class with input list parameters (this list is being transferred from Trigger while calling the static method of the class), the rest of the logic will be making use of this list to carry out the changes.

The Apex class should also have a static boolean variable with default value true. This boolean variable should be set to false before calling the method from the trigger to avoid trigger recursion.

By using a list as the variable being transferred from the Trigger to the Apex class we are making sure that the solution is bulkified. Inside the Apex class, we are making use of a ‘for loop’ to traverse through the list of records received from the Trigger one by one and we will be declaring a list of contact, account or lead object types to have all the changed records to be saved.

Here we are following the best practice of avoiding any DML operations inside the ‘for loop ‘to avoid an overhead to the solution. Moreover, it is to make sure we are not exceeding the governor limits. Once we update all the records for the correct phone number format we will be executing the DML operation to update all the changed records.

We are making use of string manipulation functions to format the phone number, but before doing anything to change the format we have to make sure that the field needs to be formatted.

For that we are making use of the following functions; deleteWhitespace(), replaceAll(), replaceFirst(), ValueOf(), startsWith(), length() and substring(). Users could enter the phone number in any format like 04XXXXXXXX, (61)2XXXXXXXX, etc. So we need to make sure that we are handling all such scenarios.

Initially we are removing all whitespaces from the phone number field using deleteWhitespace() function and then we are removing all special characters using replaceAll() function.

Also we are removing ‘0’ and ‘61’ at the start of the phone number (if present) using replaceFirst() function. Once these steps are done, we will have either 9 digits (Mobile and landline) or 10 digits (Tollfree) numbers.

Now we are  checking the length of the phone number and based on the length, different logics will be followed to format it to the required format. Also we have written test classes to perform unit testing.

We are attaching the link to the code base here.

Written by Abinesh Azhahianambi