Apex Trigger on Contact and Account Objects

Praveen Kuppakkatt
3 min readOct 12, 2020

Introduction

We are trying to format the phone numbers to the Australian format (Mobile number to the format of +61 4XX XXX XXX and Landline to the format of +61 3 XXXX XXXX). 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, I 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, I am following the approach of a Trigger accommodating all the contexts of a Trigger execution (in this case I am using insert, update, and delete actions of before and after contexts). To detach program logic from the Trigger I am making use of utility classes, which will be called for each context (before/after+insert, update or delete actions). By following this approach I am making sure that the Trigger is scalable and it is devoid of any business logic and hence I am taking the control of the order of execution by using if statements.

Trigger and Classes

I am making use of the Salesforce Developer Console to code the Trigger and Apex Classes. The triggers on Account and Contacts are partitioned into ‘isBefore’ and ‘isAfter’ contexts by making use of if statements. Under before and after contexts I have if statements for handling three different actions insert, update, or delete. Once the context and actions are identified, 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 I 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. By using a list as the variable being transferred from the Trigger to the Apex class I am making sure that the solution is bulkified. Inside the Apex class, I am making use of a ‘for loop’ to traverse through the list of records received from the Trigger one by one and I will be declaring a list of contact or account object types to have all the changed records to be saved. Here I am 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 I am not exceeding the governor limits. Once I update all the records for the correct phone number format I will be executing the DML operation to update all the changed records.

I am making use of string manipulation functions to format the phone number, but before doing anything to change the format I have to make sure that the field needs to be formatted. For that I am making use of the following functions; ValueOf(), startsWith(), length() and substring(). The current field value will be inspected to see if it is Null (which is very important as a contact/account record can be saved without values to these fields, if I don’t have this check then the Trigger will fire an error). Once that check is done, I am checking to see if the field value is already in the expected format, if it is in the expected format I am skipping any operations on that field. If the field value is not in the expected format I am checking to see if the phone number starts with a ‘0’ or if the size of the number is ‘0’, either of these cases will prompt different actions. If the phone number starts with ‘0’ I have a different logic to format the number to the desired format, or if it does not start with a ‘0’ I have a different logic to format it. I am attaching the link to the code base here.

--

--