3

I'm working on an insert trigger that's assigning the Opportunity Record Type based on a value of a field on a custom lookup Account. Our org has a few record types that are available to users, so default record type won't be good enough, and the record type assignments go according to the account type they're related to. I see an open ideaExchange for the concept of mapping Opportunity Record Types, but nothing really pointed to a customized solution that would fit our org needs. I see 2 options:

  1. query on the before trigger for the account field and assign value
trigger OpportunityTrigger on Opportunity (before insert) {
    
       if(trigger.isInsert && trigger.isBefore){
        set<id> relatedFacilityAcctIds = new set<id>();
        
        for(Opportunity opp: trigger.new){
            relatedFacilityAcctIds.add(opp.facility__c);
        }
        if(relatedFacilityAcctIds.size() > 0){
            map<id, Account> facilityAccountMap = new map<id, Account>([select id, type 
from account where id in :relatedFacilityAcctIds]);
            
            for(Opportunity opp: trigger.new){
                if(facilityAccountMap.containsKey(opp.facility__c)){
                    if(facilityAccountMap.get(opp.Facility__c).type == 'ALF'){
                        opp.recordTypeId = OPPORTUNITY_RT_ID_ALF;   
                    }
                }
            }
        }
    } 
  1. Create a formula field on the Opportunity that references that value on the lookup account and in the after insert trigger (formula fields don't populate on before inserts, so can't do it there) grab that lookup value and assign record type, and update opportunity.
trigger OpportunityTrigger on Opportunity (after insert) { 

if(trigger.isInsert && trigger.isAfter){
        List<Opportunity> oppsToUpdate = new list<Opportunity>();
        for(Opportunity opp : trigger.new){
            if(opp.facility_type__c == 'ALF'){ //formula field -> facility__r.type
                oppsToUpdate.add(new Opportunity(Id = opp.Id, RecordTypeId = OPPORTUNITY_RT_ID_ALF));
            } 
        }
        update oppsToUpdate;
    }

Which method is more preferred - cleaner/more efficient/better practice?

1 Answer 1

4

There's a tradeoff either way. You will either need to use a query or you will need to use a DML operation. Strictly speaking, a recursive DML operation is far more expensive than a simple query, so unless you really need to save on a SOQL call, you should just go ahead and use a query.

As an aside, you don't really need the results of the query, so you can save some time and memory by just keeping the IDs of matching records.

    Set<Id> facilityIds = new Set<Id>();
    for(Opportunity record: Trigger.new) {
        facilityIds.add(record.facility__c);
    }
    // If nothing to do, return early
    facilityIds.remove(null);
    if(facilityIds.isEmpty()) {
        return;
    }
    // Keep the ALF records
    facilityIds.retainAll(new Map<Id, Account>(
        [SELECT Id FROM Account WHERE Id = :facilityIds and type = 'ALF']
    ).keySet());
    // And update the record type
    for(Opportunity record: Trigger.new) {
        if(facilityIds.contains(record.facility__c)){
            record.recordTypeId = OPPORTUNITY_RT_ID_ALF;
        }
    }

You must log in to answer this question.

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