• Tom Guo 19
  • NEWBIE
  • 20 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 1
    Replies
My question is around asking what is the best practice when it comes to implementing Triggers to only fire when certain fields change and how to incorporate more filters in a manner that is efficient and aligns with best practices.  

For example, I have a Trigger on Contract which fires only when a checkbox field -> Apply Billing Frequency to All Lines is changed. In this case, if it is changed, the class and method ContractTriggerHandler.handleBeforeUpdate fires:
trigger ContractTrigger on Contract (before update) {
    
    if(Trigger.isBefore && Trigger.isUpdate){
        // Contract.Apply_Billing_Frequency_to_all_Lines__c has been Changed
        List<Contract> filteredContracts = new List<Contract>();
        for(Contract newContract: Trigger.new){
            Contract oldContract = Trigger.oldMap.get(newContract.Id);
            if(newContract.Apply_Billing_Frequency_to_all_Lines__c!=oldContract.Apply_Billing_Frequency_to_all_Lines__c){
                filteredContracts.add(newContract);
            }
        }
        ContractTriggerHandler.handleBeforeUpdate(filteredContracts);
    }
    
}
My questions are as follows: 

1) To confirm, these filter criteria should be implemented on the Trigger and not the Class correct? 
2) Do I write the same logic for each different condition? For example, if I want to add to my Trigger and have it only fire when Contract.Some_Custom_Field_c changes, I'll write within this same trigger another conditional checking values of the old map with the new map and see if the Contract.Some_Custom_Field_c has been changed. Is there a more efficient way of doing this? 
3) I'm guessing as I add this code where I want the trigger to only fire when specific changes are made, I'll have to be more specific in my class methods so that I don't only have handleBeforeUpdate handling everything that is in this case handling changes when Trigger.isBefore and Trigger.isUpdate. Any advice/ best practice guidelines on how to segment the methods within the class? 

Thank you for your help. 
I am trying to get the Contact Name and Email of the Primary Opportunity Contact. I am having difficulty as what is being returned is the Id of the contact and no email. 

Could someone let me know what key piece I'm missing here? 
 
List<OpportunityContactRole> primaryContactInfo = [SELECT OpportunityId, Contact.Name, Contact.Email
                    FROM OpportunityContactRole
                    WHERE OpportunityId ='0063h00000551YKAAY' AND isPrimary = TRUE];

System.debug(primaryContactInfo[0].get((string)'OpportunityId'));
System.debug(primaryContactInfo[0].get((String)'ContactId'));

How would I expose Contact.Name and Contact.Email? 
I'm looking for other/ better ways to implent the code below. 

Use Case: 

I have a custom Project__c object which gets created when an Opportunity becomes Closed Won. If the Opportunity has certain Opportunity Products which have the Hours_Contribute_to_Project__c checkbox set to true, when the Project is created, it will tally all the quantities of these respective Opportunity Products to see how many hours were purchased and input the value within the respective Project record. Project and Opportunity have a lookup relationship. 

Code: 
 The following code works but I'm wondering how to make it more efficient without the SOQL query in the FOR loop. Thanks!
public static void CalculateHoursPurchased(List<Project__c> projectList){
    
    for(Project__c a: projectList){
        
        AggregateResult hoursPurchased = [SELECT SUM(Quantity)
                                          FROM OpportunityLineItem
                                          WHERE Hours_Contribute_to_Project__c = TRUE AND Opportunity.Id = :a.Opportunity__c];
        
        Decimal b = (decimal)hoursPurchased.get('expr0');
        a.Hours_Purchased__c = b;
        
    }
    
}

 
I am trying to get the Contact Name and Email of the Primary Opportunity Contact. I am having difficulty as what is being returned is the Id of the contact and no email. 

Could someone let me know what key piece I'm missing here? 
 
List<OpportunityContactRole> primaryContactInfo = [SELECT OpportunityId, Contact.Name, Contact.Email
                    FROM OpportunityContactRole
                    WHERE OpportunityId ='0063h00000551YKAAY' AND isPrimary = TRUE];

System.debug(primaryContactInfo[0].get((string)'OpportunityId'));
System.debug(primaryContactInfo[0].get((String)'ContactId'));

How would I expose Contact.Name and Contact.Email?