Salesforce Communities: Allow Partners to Delete

Salesforce releases Communities, which is a much needed improvement to the stoned-aged partner portal user interface. I took part in the pre-release and found that the new functionality comes with some positives and some negatives. One big negative that I found was the inability for Community Users to delete records. Salesforce.com provided a long list of reasons why partners should not be deleting records and why this basic functionality is not provided. But let's be serious... I am not going to field calls from partners because they need me or another admin in the org to remove records that they no longer need. After a week of taking these requests during the pilot, I decided to make the functionality available to Community Users - just because it would save me and those same partners some frustration.

At a high level, the technical requirement is to create a Visualforce page, a controller for that page, which performs that deletion request, and a custom button, which will be made available in the Community page layouts.

This functionality can be built for any/all objects in your org that are accessible to a set of Community Users but for the sake of illustrating this functionality in a copy & paste manner, I am going to provide the code for the Opportunity object.

So the first thing we need to do is create a controller for a Visualforce page, which we will create later. The code for the controller is below:

/*
	Created by: Greg Hacic
	Last Update: 3 June 2013 by Greg Hacic
	Questions?: greg@interactiveties.com
*/
public class deleteOpportunityController {
	
	private final Opportunity opp; //Opportunity object
	
	public deleteOpportunityController(ApexPages.StandardController standardPageController) {
		this.opp = (Opportunity)standardPageController.getRecord(); //instantiate the opp object for the current record
	}
	
	//method called from the Visualforce's action attribute
	public PageReference deleteThisOpportunity() {
		List<Opportunity> opportunitiesToDelete = new List<Opportunity>(); //list for holding updated records
		Opportunity opportunityToDelete = new Opportunity(Id = opp.Id); //set the object that we want to update
		opportunitiesToDelete.add(opportunityToDelete); //add the updated Opportunity to out list
		if (!opportunitiesToDelete.isEmpty()) { //if there is an update to process
			delete opportunitiesToDelete;
		}
		PageReference pageWhereWeEndUp = new PageReference('/YourCommunityName/006/o'); //set the return page reference to the Opportunity tab
		return pageWhereWeEndUp.setRedirect(true); //send the User on their way
	}

}

Those unfamiliar with the new Communities functionality will need to note that the code on line 22 ('/YourCommunityName/006/o') will need to be tweaked based upon the name of your community. Replace the "YourCommunityName" to the actual name of your community.

On a side note, I really think salesforce.com should alter the URLs they are using for communities because it is a headache to manage code across multiple communities in a single org. Just my $0.02...

So now we need the Visualforce page that will allow us to run the code above. That page is below:

<!--
	Created by: Greg Hacic
	Last Update: 3 June 2013 by Greg Hacic
	Questions?: greg@interactiveties.com
-->
<apex:page standardController="Opportunity" extensions="deleteOpportunityController" action="{!deleteThisOpportunity}">
	<apex:pageMessages></apex:pageMessages>
	<apex:detail relatedList="true"></apex:detail>
</apex:page>

Yes, the page is oversimplified but this is because if the logic works as intended then the User should never really see this page. They will simply be redirected to this page and then redirected (again) to the Opportunity tab once the deletion logic completes. However, this Visualforce page will provide a way to show error messages to Users should any unforeseen errors/issues be encountered.

The last thing you need is the button setup. We will create a new button reading "Delete" that will be added to the page layouts that Community Users will see. The click stream for accessing custom buttons on the Opportunity object is as follows Setup > Customize (under the 'App Setup') > Opportunities > Buttons and Links. On the resulting page you will find a listing of your standard Opportunity buttons and any overrides for them in addition to a section listing custom buttons and links. Scroll down to the "Custom Buttons and Links" section and click the "New" button.

The next page will allow you to dictate how you want the button to display on the page and function when clicked. Provide a "Label" for your button. This will be the actual text listed in the button on the page layout. After you tab (or click) out of that field Salesforce should auto-populate the "Name" field. Choose the "Display Type" of "Detail Button." For "Behavior" you should select "Execute JavaScript" and for "Content Source" you should select "OnClick JavaScript." Please see the screenshot below for an illustration of this setup.

The actual Javascript for the button is as follows:

/*
	Created by: Greg Hacic
	Last Update: 3 June 2013 by Greg Hacic
	Questions?: greg@interactiveties.com
*/
var confirmDeletion = confirm("Are you sure you want to delete this record?"); //prompt the User for confirmation that they truly want to delete this record
if (confirmDeletion == true) { //if they confirm the deletion
	parent.location.href = '/YourCommunityName/apex/deleteOpportunity?id={!Opportunity.Id}'; //send them to the Visualforce page where we will run the deletion logic
}}

Be careful here because you need to ensure that you use the Community name in this Javascript too. On line 8 remove the "YourCommunityName" string and replace with your Community name. Also note that if you named your visualforce page something other than "deleteOpportunity" then you will need to alter that string on line 8 further.

Useful code is only truly useful to other developers when there is appropriate test coverage. So here is that piece of the puzzle:

/*
	Created by: Greg Hacic
	Last Update: 3 June 2013 by Greg Hacic
	Questions?: greg@interactiveties.com
*/
@isTest
private class deleteOpportunityControllerTEST {
	
	@isTest //defines method for use during testing only
	static void successLogic() {
		//BEGIN: perform some setup steps...
		List<Account> accounts = new List<Account>();
		accounts.add(new Account(Name = 'Interactive Ties', Website = 'http://www.interactiveties.com/'));
		insert accounts;
		List<Opportunity> opportunities = new List<Opportunity>();
		opportunities.add(new Opportunity(AccountId = accounts[0].Id, Amount = 200000, CloseDate = date.today(), Name = 'iTies Test Opportunity', StageName = 'Identified'));
		insert opportunities;
		//END: perform some setup steps...
		Test.startTest();
		PageReference visualForcePage = new PageReference('/apex/deleteOpportunity?id='+opportunities[0].Id);
		Test.setCurrentPage(visualForcePage);
		ApexPages.StandardController standard_controller = new ApexPages.standardController(new Opportunity(Id = opportunities[0].Id));
		deleteOpportunityController extVisualForcePage = new deleteOpportunityController(standard_controller);
		String validationURLString = extVisualForcePage.deleteThisOpportunity().getURL();
		System.assertEquals(true, validationURLString.contains('/006/o'));
		Test.stopTest();
	}

}

I didn't comment the test logic but you can reach out to me if you have questions. If I get too many questions then I will comment the code. I'm just lazy this evening...

So that's the code for permitting record deletions by Community Users. My opinion is that Community Users should be allowed to delete records but, until salesforce.com feels this way too, you may use this as a decent option for granting this permission. Of course, you will have to code a variation of this solution on an object by object basis, which sucks.

Honestly, I didn't expect that salesforce.com would permit this type of hack but I am glad that they do because (did I mention) allowing partners to delete some records makes for less headaches.

Automated Exchange Rates in Salesforce.com

Reduce Repetitive Tasks, Eliminate Errors & Free Up Your Administrators.

Birthday Reminders for Salesforce.com

It might lead to a sale. Or it might make you feel good.