function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Lindsey Colvin2Lindsey Colvin2 

Quote Line Item Trigger to call a class

I'm in need of some help.  I'm writing a trigger on Quote Line Item with intent to call a class to fire (the class will sync the line items back to the Opportunity) any time there is an after update on a Quote Line Item where the Quote's Primary_Quote__c checkbox == true.  Here is the code that I have currently.  It appears according to the debug that it is not returning the QLI ids.  Can someone please help steer me in the right direction?
 
trigger QuoteLineItem_Trigger on QuoteLineItem (after Update)
{

      ApexPages.StandardController stdController;
      public string currentRecordId {get; set;}
      set<id> quoteIds = new set<id>();
      
      if(trigger.isAfter && trigger.isUpdate) {
         system.debug('%%%%%%%%%%% Entering the After Update on Quote');

      for(QuoteLineItem QLI : trigger.new){
         if( QLI.Quote!=NULL && QLI.Quote.Primary_Quote__c == true ) {
         system.debug('%%%%%%%%%%% Not finding the right Quote');
         
         ApexPages.StandardController controller = new ApexPages.StandardController(QLI.Quote);
         system.debug('%%%%%%%%%%% +controller');
         vlocity_cmt.LineItemManagementController stdcontroller = new vlocity_cmt.LineItemManagementController(controller);
         stdcontroller.doSynchToQuote();
         system.debug('%%%%%%%%%%% This is not syncing');
    
         }                 
      }
   }
}

Any help is appreciated!  
pconpcon
I think the reason this is not working for you is that the lookup that you are using "Primary_Quote__c" is not populated inside of the trigger.  These lookup fields are not populated without first querying them.  So I would instead do this
 
trigger QuoteLineItem_Trigger on QuoteLineItem(after update) {
    Set<Id> quoteIds = new Set<Id>();

    for (QuoteLineItem qli : Trigger.new) {
        quoteIds.add(qli.QuoteId);
    }

    quoteIds.remove(null);

    if (!quoteIds.isEmpty()) {
        for (Quote q : [
            select Id
            from Quote
            where Primary_Quote__c = true and
                Id in :quoteIds
        ]) {
            ApexPages.StandardController stdController = new ApexPages.StandardController(q);
            vlocity_cmt.LineItemManagementController controller = new vlocity_cmt.LineItemManagementController(stdController);
            controller.doSynchToQuote();
        }
    }
}

One thing to note about this, if "doSynchToQuote" is doing any DML operations, you could quickly exhaust your governor limits because you are operating inside of a loop.  If it does, I would suggest that you reach out to whomever owns the vlocity_cmt package and see if they have a bulk ready way to do what that method does.
Lindsey Colvin2Lindsey Colvin2
Thank you for your help!  You were right, that did get me past the error I was receiving, but now I am getting too many SOQL queries. 
pconpcon
That's most likely because the vlocity_cmt package is doing SOQL inside of it and you are calling that from inside the loop.  So for example, if between the constructor for the class and the doSynchToQuote method they are doing 10 SOQL calls, if you have more than 9 quotes to sync, you will hit the DML limit for the number of SOQL calls.  What I would recommend is to reach out to whomever owns the vlocity_cmt package and see if there is a bulk ready way to sync the quotes.  The problem with using the Visualforce controller in the trigger is that most Visualforce controllers assume that you are working with a single record and are not written in a way that is condusive to iterating over multiple records.
Lindsey Colvin2Lindsey Colvin2
Ok, I tried moving this to the Quote object, instead of QLI.  It now works for any changes to existing line items!  However, when I try to insert a new line item, I get Apex trigger Quote_Trigger caused an unexpected exception, contact your administrator: Quote_Trigger: execution of AfterUpdate caused by: System.NullPointerException: Attempt to de-reference a null object.  Here is what I have:
 
trigger Quote_Trigger on Quote(after update) {
    Set<Id> quoteIds = new Set<Id>();

    for (Quote quo : Trigger.new) {
        
        
     
        
    quoteIds.remove(null);

    if ( quo!=NULL && quo.Primary_Quote__c == true ) {
            
        
            ApexPages.StandardController stdController = new ApexPages.StandardController(quo);
            vlocity_cmt.LineItemManagementController controller = new vlocity_cmt.LineItemManagementController(stdController);
            controller.doSynchToQuote();
        }
    }
  }

Thoughts on this?  
pconpcon
I've updated the code to get rid of any extra stuff you don't need.  
 
trigger Quote_Trigger on Quote(after update) {
    for (Quote quo : Trigger.new) {
        if (quo.Primary_Quote__c == true ) {
            ApexPages.StandardController stdController = new ApexPages.StandardController(quo);
            vlocity_cmt.LineItemManagementController controller = new vlocity_cmt.LineItemManagementController(stdController);
            controller.doSynchToQuote();
        }
    }
}
Can you tell me which line the NullPointerException is occuring?  You should have an error that shows a bunch more information.

This code won't get rid of the too many SOQL errors if the vlocity_cmt stuff is the culprit.  This still uses it inside of a loop which has the same issue.  And if you want the sync to happen when the QuoteLineItem is updated and rolled up to the Quote, then this trigger may never happen if the Quote object isn't updated.  It would be better to do it on the QuoteLineItem and find a way with vlocity_cmt to handle the bulk usecase.