+ Start a Discussion
sfdc dev 2264sfdc dev 2264 

Case trigger bulkification help needed

Hi,

I have a trigger which is updating account id on case object , The logic is working fine, I just want to bulkify the trigger with the best coding standards as i have written a query inside a for loop

Kindly help me with that pls
 
MY TRIGGER :

trigger trgAccountAutopopulate  on Case (before insert,before update) {


if(Trigger.isbefore){
Id groupwaiversRecordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Group Waivers').getRecordTypeId();
for(Case casenew: Trigger.new){

if(casenew.Recordtypeid==groupwaiversRecordTypeId ){
if(casenew.IATA_DAI__c!=null){
Account AccIATA=[Select id, IATA_Number__c from account where IATA_Number__c =: casenew.IATA_DAI__c limit 1];
casenew.Accountid=AccIATA.id;
}

if(casenew.TIDS__c!=null){
Account AccTIDS=[Select id, Agency_TIDS_Number__c from account where Agency_TIDS_Number__c =: casenew.TIDS__c limit 1];
casenew.Accountid=AccTIDS.id;

}

}
}


}
}

Thanks in Advance
HARSHIL PARIKH AKA:GovindHARSHIL PARIKH AKA:Govind
I understand your question here and I see the trigger would work but it woul fail right after the first 100 records whether its update or insert.

Here is what I can offer you though...
see the below trigger,
 
Trigger trgAccountAutopopulate  on Case (before insert,before update) 
{
    
    List<Account> allSFAccounts = [Select Id, IATA_Number__c, Agency_TIDS_Number__c FROM Account
                                                WHERE IATA_Number__c != Null
                                                OR   Agency_TIDS_Number__c != Null LIMIT 50000];
                                                
        // This query willl fetch the first 50,000 Account Records.
        // Then you gonna need to write a batch apex to fo the job which is
        // to fetch next 50000 then next 50000 until it reaches the bottom of youe account database
    
    if(Trigger.isbefore)
    {
        Id groupwaiversRecordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Group Waivers').getRecordTypeId();
        
        for(Case casenew: Trigger.new)
        {
            if(casenew.Recordtypeid==groupwaiversRecordTypeId )
            {
                if(casenew.IATA_DAI__c != null)
                {                                  
                    For(Account act : allSFAccounts )
                    {
                      If((casenew.IATA_DAI__c == act.IATA_Number__c) || (casenew.TIDS__c == act.Agency_TIDS_Number__c))
                      {
                          casenew.AccountId = act.Id;
                      }
                    }   
                }          
            }
        }
    
    
    }
}

If you have less than 50,000 Accounts who has IATA_Number__c or Agency_TIDS_Number__c as not null then trigger is good to go for now.
But if you think you may have way of than 50,000 accounts with either IATA_Number__c != null or Agency_TIDS_Number__c != null then I would say you need to implement the batch apex.

Again, let's say you have 200,000 Accounts in your org and let's say there are 150,000 of them has Agency_TIDS_Number__c  and IATA_Number__c  both blank then you don't need to worry about batch apex. But however, that is very less likely to be the scenario.

Hope this helps!
sfdc dev 2264sfdc dev 2264
Thanks bro , i tried your code , but its updating a wrong value

I modified the code through a map

Pls let  me know the modified code is fine or need any modifications,
 
MY MODIFIED CODE :

Trigger trgAccountAutopopulate on Case (before insert, before update) {
    
    set<string> trackingIds = new set<string>();
    Map<string,Id> accountIATAMap = new Map<string,Id>();
    Map<string,Id> accountTIDSMap = new Map<string,Id>();
    Id groupwaiversRecordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Group Waivers').getRecordTypeId();

    for (Case  s: trigger.new) {
        if(s.IATA_DAI__c != null && s.Recordtypeid==groupwaiversRecordTypeId ) {
            trackingIds.add(s.IATA_DAI__c);
        }
        
        if(s.TIDS__c != null && s.Recordtypeid==groupwaiversRecordTypeId ) {
            trackingIds.add(s.TIDS__c);
        }
    }   
    for(account iata : [Select Id,IATA_Number__c from account WHERE IATA_Number__c IN :trackingIds]){
        accountIATAMap.put(iata.IATA_Number__c,iata.Id);
    }
    
    for(account tids : [Select Id,Agency_TIDS_Number__c from account WHERE Agency_TIDS_Number__c IN :trackingIds]){
        accountTIDSMap.put(tids.Agency_TIDS_Number__c,tids.Id);
    }
    
    for (Case  s: trigger.new) {
        if(s.IATA_DAI__c != null && s.Recordtypeid==groupwaiversRecordTypeId && accountIATAMap.containskey(s.IATA_DAI__c)){
            s.Accountid = accountIATAMap.get(s.IATA_DAI__c);
        }
        
        if(s.TIDS__c != null && s.Recordtypeid==groupwaiversRecordTypeId && accountTIDSMap.containskey(s.TIDS__c)){
            s.Accountid = accountTIDSMap.get(s.TIDS__c);
        }
        
    }
    
}

 
Amit Chaudhary 8Amit Chaudhary 8
In case of update you are updating Accountid every time. Please try oldMap like below
 
Trigger trgAccountAutopopulate on Case (before insert, before update)
{
    set<string> trackingIds = new set<string>();
    Map<string,Id> accountIATAMap = new Map<string,Id>();
    Map<string,Id> accountTIDSMap = new Map<string,Id>();
    
    Id groupwaiversRecordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByName().get('Group Waivers').getRecordTypeId();

    for (Case  s: trigger.new)
    {
        if(s.Recordtypeid == groupwaiversRecordTypeId)
        {
            if(Trigger.isInsert)
            {
                if(s.IATA_DAI__c != null )
                {
                    trackingIds.add(s.IATA_DAI__c);
                }
                
                if(s.TIDS__c != null )
                {
                    trackingIds.add(s.TIDS__c);
                }
            }
            else if (Trigger.isUpdate)    
            {
                Case oldCase = Trigger.oldMap.get(s.id);
                
                if(s.IATA_DAI__c !=oldCase.IATA_DAI__c &&  s.IATA_DAI__c != null )
                {
                    trackingIds.add(s.IATA_DAI__c);
                }
                
                if( s.TIDS__c !=oldCase.TIDS__c && s.TIDS__c != null )
                {
                    trackingIds.add(s.TIDS__c);
                }
            }
        }    
    }   
    
    for(account iata : [Select Id,IATA_Number__c from account WHERE IATA_Number__c IN :trackingIds]){
        accountIATAMap.put(iata.IATA_Number__c,iata.Id);
    }
    
    for(account tids : [Select Id,Agency_TIDS_Number__c from account WHERE Agency_TIDS_Number__c IN :trackingIds]){
        accountTIDSMap.put(tids.Agency_TIDS_Number__c,tids.Id);
    }
    
    for (Case  s: trigger.new)
    {
        if(s.Recordtypeid == groupwaiversRecordTypeId)
        {
            if(Trigger.isInsert)
            {
                if(s.IATA_DAI__c != null && accountIATAMap.containsKey(s.IATA_DAI__c) )
                {
                    s.Accountid = accountIATAMap.get(s.IATA_DAI__c);
                }
                
                if(s.TIDS__c != null && accountTIDSMap.containsKey(s.TIDS__c) )
                {
                    s.Accountid = accountTIDSMap.get(s.TIDS__c);
                }
            }
            else if (Trigger.isUpdate)    
            {
                Case oldCase = Trigger.oldMap.get(s.id);
                
                if(s.IATA_DAI__c !=oldCase.IATA_DAI__c &&  s.IATA_DAI__c != null && accountIATAMap.containsKey(s.IATA_DAI__c))
                {
                    s.Accountid = accountIATAMap.get(s.IATA_DAI__c);
                }
                
                if( s.TIDS__c !=oldCase.TIDS__c && s.TIDS__c != null && accountTIDSMap.containsKey(s.TIDS__c) )
                {
                    s.Accountid = accountTIDSMap.get(s.TIDS__c);
                }
            }
        }    
    }
    
}

Let us know if this will help you