Deleting Salesforce Contacts You Don’t Own

If you have a private sharing model for Accounts and Contacts in Salesforce, you might have run into this problem. You can only delete records you don’t own in Salesforce if you have been given Modify all Data permissions for the object or if you are in a Role above the owner. Our business requirements are a bit different from this. We wanted accounts to be private and shared by sharing rules to groups of other users. All of those users expect to be able to make changes to all contacts related to the account, including deleting contacts.

Let me digress here a minute: in my opinion, you shouldn’t delete contacts if they have any activities associated with them – they should be mark “Inactive” so we don’t lose all that history. We’ve added a before delete trigger to contacts to prevent them from being deleted in that case. In some cases, you might really need to delete a contact: it is a duplicate or there is no activity and it is just cluttering things up.

OK, back to the task at hand. Try as I might, I couldn’t figure out any way to accomplish deleting of contacts that were associated with accounts I could view and edit. I finally decided to roll my own solution with a custom button and some apex. It turned out to be pretty simple, but there is some room for improvement.

First the Apex code (complete with test!). In this code, I create a webservice that can be called by a custom button. It passes in the Contact Id and then deletes it. In the test, I create a contact and then try deleting the contact as a different user. Note that you might need to change the profile to get a valid user.

global without sharing class ContactUtil {
  webService static Boolean deleteContact(Id id) {
    Contact c = new Contact(id = id);
    try {
      delete c;
      return true;
    } catch (Exception e) {
      return false;
  }
}

  static testMethod void testDeleteContact() {
    Contact c = new Contact(LastName = 'Test');
    insert c;
    User u = [select id from user where Profile.Name = 'Sales User' and IsActive = true  limit 1];
    System.runAs(u) {
      deleteContact(c.Id);
    }

    Contact[] testContact = [select Id from Contact where Id = :c.Id];
    System.assert(testContact.isEmpty());
  }
}

Now that we have the webservice, we can create a button to add to the contact layout page. It will be a Detail Page Button that Executes JavaScript. Here’s what the javascript looks like. It prompts the user and if successful, redirects to the Contact tab.

{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/22.0/apex.js")}

if (confirm("Are you sure?")) {
  if (sforce.apex.execute("ContactUtil","deleteContact", {id:"{!Contact.Id}"})) {
    window.location.replace('/003/o');
  }
}

Add this button to your page layout and remove the standard delete button. Now your users will be able to delete any contacts that they can view on the detail page.

A couple of words of caution. You might have noticed that there is no validation that the user should be able to delete the contact. Ideally, I’d like to test to see if the user has write access to that contact record. If so, then allow the delete. I’ve been unable to find a way to test record level access, so I’ve left it wide open. [UPDATE: I found a way! https://verticalcode.wordpress.com/2012/04/03/deleting-salesforce-contacts-you-dont-own-part-2/] Because of this, make sure that you only give permissions to the the ContactUtil class who you want to be able to delete all contacts.

Advertisements

3 thoughts on “Deleting Salesforce Contacts You Don’t Own

  1. Wow, this is possible solution to my problem. However, I’m not a coder so I’m potentially may be too deep here. It seems rather straightforward, except for your last statement “make sure that you only give permissions to the the ContactUtil class who you want to be able to delete all contacts”. How exactly do I do that?

    My exact need is to allow users to delete any contact owned by one particular user. So I made a sharing rule that allows all users to read/write contacts owned by that user, but as you know, can’t grant them access to delete.

    If you can explain your last point on permissions, I think I may be able to do this.

    Thanks!

    • You give permissions to classes by going to Setup->Develop->Apex Classes and clicking on ContactUtil then click on Security. You, of course need to have the class created first. Always test in a sandbox first and then deploy to production using Change Sets or the IDE.

  2. Pingback: Deleting Salesforce Contacts You Don’t Own (Part 2 « Vertical Code

Leave a Reply

Fill in your details below or click an icon to log in:

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