How to Sync Quotes using Apex

Sharing is Caring

In Salesforce, quotes are a representation of prices that have been proposed to a customer for products or services. If you aren’t familiar with opportunities, quotes and products please review my post about Designing a Sales Process in Salesforce.

An opportunity may have lots of quotes associated to it but only one quote may be synced to an opportunity at a time. Quote syncing links a quote a specific opportunity which allows updates to update between the Opportunity and Quote. Basically, when an Opportunity is added or removed it can be removed from the list of Opportunity Products without having to write any code. Keep in mind that this means Opportunity Products will be automatically removed and readded. I have been confused a few times by this.

After an opportunity is synced to a quote there’s a few changes that will happen:

  • The Synced Quote is set
  • The Syncing checkbox on the Quote is set.
  • The Quote Products and Opportunity Products are merged.
  • The Opportunity Amount becomes readonly to the user regardless of whether a quote is currently syncing or not.

For the most part, if you are automatically creating quotes and emailing them it’s really trivial to sync the quote automatically.

Quotes can be synced manually, and pretty easily, but it can be automated very easily saving sales staff dozens of clicks a day if your sales process is very short.

To sync a quote manually, you can do the following steps:

  1. Open the newly created quote, and then click the Start Sync button.
  2. If you go through the prompts, you can sync the quote. The Opportunity’s Synced Quote field stores the Quote that is currently being synced.
  3. If you need to unsync the quote, you go to the quote currently syncing and press the Stop Syncing button.

To Sync a quote in apex, it’s really easy:

Opportunity opp = new Opportunity();
insert opp;

//Pretend generateNewQuote sets the Name, adds products, etc.
Quote q = generateNewQuote(opp.Id);

// the first step before syncing is to insert the quote
insert q;

// after inserting the quote we need to update the opportunity
 opp.SyncedQuoteId = q.Id
update opp;

A much more common pattern is to create the quote on a page, or maybe through some sort of automated process and then sync the quote automatically through an apex after trigger. You need to sync the quote in an After Insert / After Update Quote Trigger because the Id wouldn’t necessarily be set for the Quote and the record wouldn’t necessarily be committed to the database yet. See my post What’s the difference between Before and After Triggers for some more information regarding this.

Here’s a very simple example of how to do it in a trigger:

trigger QuoteTrigger on Quote (before update, before insert, after update, after insert) {
	// for ease of example we're not going to use a trigger framework because it would make the example 100x longer. 
	// Logic shouldn't be in a trigger.
	
	if (Trigger.isInsert) {	
		if (System.isAfter) {
			QuoteService qs = new QuoteService();
			qs.SyncQuotes(Trigger.new);
		}
	}
}

public with sharing class QuoteService {
	
	public void SyncQuotes(List<Quote> quotes) {
		List<Opportunity> opps = new List<Opportunity>();
		
		// Loops through the List of Quotes and gets the OpportunityId.
		for (Quote q : quotes) {
			if (string.isNotEmpty(q.OpportunityId) {
				Opportunity opp = new Opportunity(Id = q.OpportunityId);
				opp.SyncedQuoteId  = q.Id;
				
				opps.add(opp);
			}
		}
		
		if(!opps.isEmpty()) {
			update opps;
		}
	}
}

If you use a trigger, make sure that you take the time and follow Apex Trigger Best Practices.

Possibly your company is doing some awesome stuff with Artificial intelligence (Einstein, etc) but most likely the sales person is talking to the opportunity on the phone and going through some sort of Quote Process and adding products.

Sharing is Caring

Brian is a software architect and technology leader living in Niagara Falls with 13+ years of development experience. He is passionate about automation, business process re-engineering, and building a better tomorrow.

Brian is a proud father of four: two boys, and two girls and has been happily married to Crystal for more than ten years. From time to time, Brian may post about his faith, his family, and definitely about technology.