Given this example trigger on the SBQQ__Quote__c object, I can log data whenever the quote is created/updated/deleted/undeleted.

trigger QuoteTrigger on SBQQ__Quote__c (after insert, after update, after delete, after undelete) {
  // etc...

I want this trigger to run when objects related to the quote update. Some example scenarios that aren't working:

  1. "Submit an Approval" which kicks off a ProcessInstance for this Quote doesn't result in this Quote trigger being updated. This is even more of an issue because adding a trigger for ProcessInstance is disallowed.
  2. "Add Task" to the quote doesn't hit this trigger, despite it being related to the quote.
  3. ProcessInstanceStep, aka a user adding their approval to the quote doesn't result in the quote being updated.

Is there a sane solution for getting trigger events for the quote without having to write a trigger for every object related to the quote? Hoping there's some other kind of event(s) that I might be able to add to this single quote trigger.

I feel like I'm going to have to fallback to polling all of these tables on a regular basis.

Also the pubsub system is not a viable option because it seems like I would have to emit custom events and keep an active connection to the salesforce instance.

1 Answer 1


The trigger on an object only works for that object. Unless another process on a related object (being either a child or parent one) triggers a change on your object, the trigger won't run.

Is there a sane solution for getting trigger events for the quote without having to write a trigger for every object related to the quote?

No. You need to write triggers to handle every related object change. Or at least that is the best practice here in your case.

As a gimmick you could have a handful of fields on your CPQ Quote that gets updated once a related record is updated, and you can poll from that field. The caveat here is that you will need to get some automation on the related objects anyway to update the field on the parent quote.

As an idea, I would suggest you to deploy a simple trigger on each object you have, related to the CPQ Quote, that fires a common class where you can handle the appropriate update:

trigger CPQQuote on SBQQ__Quote__c (after insert, after update) {
  new HandleCPQQuoteChanges().run();

And in HandleCPQQuoteChanges you could have something like this:

public class HandleCPQQuoteChanges {
  public HandleCPQQuoteChanges() {
    // do some init work if you must here, like checking a
    // custom setting or custom metadata
  public void run() {
    // your trigger executes here regardless of the object that fired it

    // and you can access the related records with the Trigger static variable:
    List<Object> records = Trigger.new;

    // if you want to check what object you are handling, you could
    // compare the SObject and perform specific logic depending on 
    // the related record's type
    Schema.SObjectType sot = records.getSObjectType();

    if (sot == Schema.Account.getSObjectType()) {
      // do something specific if the related record that fired the logic
      // is an Account

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .