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

2 thoughts on “An employee contact record for every Salesforce user

  1. This is pretty awesome! One hitch I’m having though… the Account name doesn’t seem to want to populate. I’ve tried adding in the 15-digit ID on the metadata record, and I’ve tried making sure the user’s account name is the same as the one I want populated… what am I missing?

    Liked by 1 person

    • Rob Alexander says:

      Glad you like it, James. Can you please clarify your statement about trying to make sure the user’s account name is the same as the one you want populated? I’m not sure I understand what you mean.

      Like

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 )

Google+ photo

You are commenting using your Google+ 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 )

w

Connecting to %s