The Development Benefits of Classic Features Coming to Lightning

For the last couple of years, our engineering teams have been busy building some of your favorite Classic features in Lightning Experience. It’s obvious how bringing these features to Lightning is important for admins and business users, but in this post we want to highlight some of the benefits for our developers.

Rebuilding features in Lightning often requires our teams to introduce new APIs or enhance existing ones. For example, in Winter ’19, my team worked on adding greater flexibility to the Opportunity Change Owner experience in Lightning and with this work we introduced two new fields for OwnerChangeOptions: KeepSalesTeam and KeepSalesTeamGrantCurrentOwnerReadWriteAccess. In this post we want to share a couple of examples of how these new API enhancements can be used to solve common business requirements.

Removing Opportunity Team via API

Use case: Jessica Adams, one of your top sales reps has recently been promoted to a management role and all her open opportunities must be transferred to other sales reps. Business asks the Salesforce development team to transfer all 200+ opportunities with their related open activities in Jessica’s name to new reps. They also ask that the existing opportunity team be removed from all the opportunities so that the new owners have the ability to review them and add their own opportunity team.

Before Winter ’19: Your development team would query all opportunities owned by Jessica and use OwnerChangeOptions with TransferOpenActivities to transfer ownership. Then you would have to query all opportunity team members associated to the opportunities and remove the records.

After Winter ’19: Your development team would query all opportunities owned by Jessica and use OwnerChangeOptions with TransferOpenActivities and KeepSalesTeam (set to false) to transfer ownership.

In the Java code example below, you can see that we instantiate a new OwnerChangeOption called keepSalesTeamOption. We then set its execute value to false (do not keep team) and its type to the newly introduced KeepSalesTeam. We then set keepSalesTeamOption and transferOpenActivitiesOption as our header options on our connection. These header options are then read as a part of our Opportunity update (change owner) requests.

// Query Opportunities with current owner
QueryResult result = query("SELECT Id, OwnerId FROM Opportunity WHERE OwnerId = '" + currentOwnerId + "'");

// Set KeepSalesTeam SOAP header option to false        
OwnerChangeOption keepSalesTeamOption = new OwnerChangeOption();
keepSalesTeamOption.setExecute(false);
keepSalesTeamOption.setType(OwnerChangeOptionType.KeepSalesTeam);

// Set TransferOpenActivities SOAP header option to true  
OwnerChangeOption transferOpenActivitiesOption = new OwnerChangeOption();
transferOpenActivitiesOption.setExecute(true);
transferOpenActivitiesOption.setType(OwnerChangeOptionType.TransferOpenActivities);

connection.setOwnerChangeOptions(new OwnerChangeOption[] { keepSalesTeamOption, transferOpenActivitiesOption });

// Set and update opportunities with new owner
// OwnerChangeOptions set will be common to all updated opportunities         
SObject[] opps = result.getRecords();
for (SObject opp : opps) {
    ((Opportunity)opp).setOwnerId(newOwnerId);
}
connection.update(opps);

 

Set Owner Opportunity access via API

Use case: The business recently hired Jake McIntyre as a Renewals Manager and going forward sales reps will no longer be responsible for renewal opportunities. Business asks the Salesforce development team to transfer all renewal opportunities with their notes and attachments to Jake, but they insist that the previous opportunities’ owners retain “Read/Write” access to the opportunities.

Before Winter ’19: Your development team would query all opportunities of record type “Renewal” and use OwnerChangeOptions with TransferNotesAndAttachments to transfer ownership to Jake. Then they would have to programmatically add the previous owner to the Opportunity Team with “Read/Write” access.

After Winter ’19: Your development team would query all opportunities of record type “Renewal” and use OwnerChangeOptions with TransferNotesAndAttachments and KeepSalesTeamGrantCurrentOwnerReadWriteAccess to transfer ownership to Jake.

In the Java code example below, you can see that we instantiate a new OwnerChangeOption called keepSalesTeamGrantOwnerReadWriteAccessOption. We then set its execute value to true (retain Read/Write access) and its type to the newly introduced OwnerChangeOptionType.KeepSalesTeamGrantCurrentOwnerReadWriteAccess. We then set keepSalesTeamOption, keepSalesTeamGrantOwnerReadWriteAccessOption, and transferNotesAndAttachmentsOption as our header options on our connection. These header options are then read as a part of our Opportunity update (change owner) requests.

// Query Opportunities with Renewal record type
QueryResult result = query("SELECT Id, OwnerId FROM Opportunity WHERE RecordTypeId IN (SELECT Id FROM RecordType WHERE name = 'Renewal')");

// Set KeepSalesTeam SOAP header option to true         
OwnerChangeOption keepSalesTeamOption = new OwnerChangeOption();
keepSalesTeamOption.setExecute(true);
keepSalesTeamOption.setType(OwnerChangeOptionType.KeepSalesTeam);

// Set KeepSalesTeamGrantCurrentOwnerReadWriteAccess SOAP header option to true  
OwnerChangeOption keepSalesTeamGrantOwnerReadWriteAccessOption = new OwnerChangeOption();
keepSalesTeamGrantOwnerReadWriteAccessOption.setExecute(true);
keepSalesTeamGrantOwnerReadWriteAccessOption.setType(OwnerChangeOptionType.KeepSalesTeamGrantCurrentOwnerReadWriteAccess);

// Set TransferNotesAndAttachments SOAP header option to true  
OwnerChangeOption transferNotesAndAttachmentsOption = new OwnerChangeOption();
transferNotesAndAttachmentsOption.setExecute(true);
transferNotesAndAttachmentsOption.setType(OwnerChangeOptionType.TransferNotesAndAttachments);

connection.setOwnerChangeOptions(new OwnerChangeOption[] { keepSalesTeamOption, keepSalesTeamGrantOwnerReadWriteAccessOption, transferNotesAndAttachmentsOption });

// Set and update opportunities with new owner
// OwnerChangeOptions set will be common to all updated opportunities          
SObject[] opps = result.getRecords();
for (SObject opp : opps) {
    ((Opportunity)opp).setOwnerId(newOwnerId);
}
connection.update(opps);

 

Keeping up with Release Notes

If you found the examples above relevant, then take a look at our Spring ’19 release notes — we introduced similar set of APIs for Account Change Owner. Going forward, as the Salesforce feature teams continue to fill in Lightning gaps you should take a look at the corresponding API for the features. Think about how you can use the new APIs and share your feedback on how we can make them better.

For more on APIs, check out the API Basics module on Trailhead.

About the authors

Aria Niazi
Sr. Product Manager, Salesforce
Aria is currently a Senior Product Manager responsible for Opportunity Management in Sales Cloud, Path, and Kanban. You can follow him on Twitter @arianiazi.

Jeff O’Donnell
Lead Software Engineer, Salesforce
Jeff has been a software engineer at Salesforce for over five years, focusing on both development and quality engineering for numerous features in Sales Cloud.

Leave your comments...

The Development Benefits of Classic Features Coming to Lightning