An employee contact record for every Salesforce user

There are a number of reasons why it might be helpful for every Salesforce user to have a related contact record that is updated whenever certain user fields are updated. A couple of those reasons might be:

  • using cases for internal support (to benefit from case contact functionality)
  • making the built-in contact hierarchy org chart work for your company

Here is an Apex class I’ve created to accomplish this:

public with sharing class UpsertUserContact {
    @Future
    public static void execute(Set<Id> userIds) {

        List<Contact> contactsToUpsert = new List<Contact>(); // Create a list of contacts to upsert

        List<RecordType> employeeRTs = [SELECT Id FROM RecordType
                                        WHERE SobjectType = 'Contact' AND DeveloperName = 'Employee'
                                        LIMIT 1];

        List <Employee_Contact_Setting__mdt> companyAcctIds = [SELECT ID__c
                                                               FROM Employee_Contact_Setting__mdt
                                                               WHERE DeveloperName =: 'Company_Account'
                                                               LIMIT 1];

        List<User> users =
            [SELECT Id, Email, FirstName, LastName, Department, ManagerId, Fax, Phone, MobilePhone, Title, Street, City, State, PostalCode, Country
             FROM User
             WHERE Id IN : userIds AND IsActive = true AND UserType = 'Standard'];

        List<Id> userManagerIds = new List<Id>();

        for(User managedUser: users){
            if (managedUser.ManagerId != null){
                userManagerIds.add(managedUser.ManagerId);
            }
        }

        List<Contact> managerContacts = [SELECT Id,User__c from Contact
                                         WHERE User__c IN : userManagerIds];

        Map <Id,Id> managerContactMap = new Map<Id,Id>();	// Create a manager contact map of userId, contactId

        for(Contact managerContact: managerContacts){
            managerContactMap.put(managerContact.User__c,managerContact.Id);
        }

        List<Contact> contacts =
            [SELECT Id, User__c
             FROM Contact
             WHERE User__c IN: userIds];

        Map <Id,Id> userContactMap = new Map <Id,Id>();	// Create a user contact map of userId, contactId

        for(Contact userContact: contacts){
            userContactMap.put(userContact.User__c,userContact.Id);
        }

        for (User u : users){								// Loop through each upserted user

            Contact c = new Contact(						// Create a contact record in memory
                RecordTypeId = employeeRTs[0].Id,			// Populate the record type
                User__c = u.Id,								// Populate the user lookup
                Email = u.Email,							// Populate the email
                FirstName = u.FirstName,					// Populate the first name
                LastName = u.LastName,						// Populate the last name
                Department = u.Department,					// Populate the user department
                Fax = u.Fax,								// Populate the fax number
                Phone = u.Phone,							// Populate the phone number
                MobilePhone = u.MobilePhone,				// Populate the mobile phone number
                Title = u.Title,							// Populate the title of user
                MailingStreet = u.Street,					// Populate the mailing street
                MailingCity = u.City,						// Populate the mailing city
                MailingState = u.State,						// Populate the mailing state
                MailingPostalCode = u.PostalCode,			// Populate the postal code
                MailingCountry = u.Country,					// Populate the country
                OwnerId = u.Id);							// Populate the contact owner
            if (companyAcctIds.size() > 0) {
                c.AccountId = companyAcctIds[0].ID__c;		// Populate the account lookup
            }
            if (managerContactMap.get(u.ManagerId) != null) {
                c.ReportsToId = managerContactMap.get(u.ManagerId); // Populate the Reports To field
            }
            if (userContactMap.get(u.Id) != null) {
                c.Id = userContactMap.get(u.Id);			// specify the contact to be updated
            }

            contactsToUpsert.add(c);						// Add the contact to the bulk upsert list

        }

        if(contactsToUpsert.size() > 0){
            upsert contactsToUpsert;						// Upsert all contacts in single DML statement
        }
    }

}

Here’s the Apex trigger I created to call the above class:

trigger UserTrigger on User (after delete, after insert, after undelete, after update, before delete, before insert, before update) {

    //Handles all user triggers

    if ((trigger.isInsert || trigger.isUpdate) && trigger.isAfter){

            Set<Id> userIds = new Set<Id>();

            for (User u : trigger.new) {

                // Add the user id to the set of ids
                userIds.add(u.Id);
            }
            if (!System.isFuture() && !System.isBatch()) {
                //upsert contact records with the changes in user records
                UpsertUserContact.execute(userIds);
            }

    }
}

Prerequisites:

  • custom lookup field called User (User__c) on the contact object
  • custom metadata type of Employee Contact Setting (Employee_Contact_Setting__mdt) with
    • custom field of ID (ID__c)
    • record called Company Account (Company_Account)

There you have it!

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s