· tutorials · 3 min read

Effortlessly Sync Custom Fields Across Opportunity Products and Quote Line Items

Learn how to sync custom fields from quote line items to custom fields on opportunity products using Apex code.

Using the native quote object in Salesforce extends functionality of quoting. This allows users to send pdfs of quotes, as well as keep a versioned storage of all quotes sent to customers. Although quotes are linked to opportunities, many of the intuitive features are missing, including custom fields on quote line items syncing with custom fields on opportunity products.


  • Quotes Enabled
  • Expose the Opportunity Line Item Id in a formula
  • Enterprise Edition

Enable Quotes

To enable quotes in an org:

  1. Go to setup
  2. Search Quotes and go to Quote Settings
  3. Click Enable

Create Opportunity Line Item Id Formula

To expose the Opportunity Line Item ID on the Quote Line Item:

  1. Go to setup
  2. Go to the Object Manager
  3. Find the Quote Line Item
  4. Go to Fields & Relationships and create a new field

The field should have the following properties: Type: Formula Label: Opportunity Line Item Id Name: Opportunity_Line_Item_Id__c Return Type: Text Formula: CASESAFEID(OpportunityLineItem.Id)

Creating Custom Fields

Once we’ve set up the basic Salesforce configuration, we can move on to creating custom fields for the data we want to link. This works for any writable field types, but for this example I will use a date field, called Shipment_Date__c

These custom fields need to be created on both the Quote Line Items and the Opportunity Products

Writing an Apex Trigger

Now that we’ve set up the necessary configuration in Salesforce and created our custom fields, we can write an Apex trigger to link the data between the quote line item and opportunity products. In your preferred editor, create an Apex trigger named QuoteLineItemTrigger for the quote line item object. In the trigger context, use “after insert” and “after update” to send DML.

Apex Trigger

trigger QuoteLineItemTrigger on QuoteLineItem (after insert, after update) {

We use a Trigger Handler system for better code architecture, so create the Apex class QuoteLineItemTriggerHandler

Apex Class

public class QuoteLineItemTriggerHandler {

    public static void updateOpportunityLineItems(List<QuoteLineItem> qlis){
        Map<Id, QuoteLineItem> qliMap = new Map<Id, QuoteLineItem>();
        for(QuoteLineItem qli : qlis){
            if(qli.Opportunity_Line_Item_Id__c != null){
                qliMap.put(qli.Opportunity_Line_Item_Id__c, qli);
        List<OpportunityLineItem> olis = [SELECT Id FROM OpportunityLineItem WHERE Id in : qliMap.keySet()];
        for(OpportunityLineItem oli : olis){
            // Map Fields
            oli.shipment_date__c = qliMap.get(oli.Id).shipment_date__c;
        if (olis.size > 0){
            update olis;

Any additional fields you want to link within this system will be inserted in the Map Fields section. Just replace shipment_date__c with the API name of your field.


Implementing the trigger framework above will help you link Salesforce data between Quote Line Items and Opportunity Products. If you want a visual walkthrough, check the video here:

Need Our Help To Get Your Data Into Salesforce?

Join dozens of other companies by learning how you can get all your company's data in one place.

Back to Blog