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
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student 

Please Help with fixing Trigger and Bulkification

Hey there,

I have a trigger which runs off a referral__c object. Basically, the way it works is that:

Every referal field within the trigger is a lookup or a Master-detail relationship.

R.Referee__c = lookup to Account being referred
R.Referred_IPC__c = Lookup to service which is a child of Account. (An IPC service must be taken on by referee to make the trigger happen)
R.Referrer__c = Master_detail lookup to Account.

When these three fields are filled the trigger creates two service__c records.

Now all this worked well asides from recursion each time I edited to records (So I edited the extra two statements to the if statement)

I attempted to make it so that the two lookups to service, where filled with the ID's of the two added services, but I failed. When I tested the trigger I received this error:

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger Referral_AddBonusService caused an unexpected exception, contact your administrator: Referral_AddBonusService: execution of AfterInsert caused by: System.FinalException: Record is read-only: Trigger.Referral_AddBonusService: line 33, column 1

Then I tried to change the code a tiny bit (as seen below), it works, except that if there are multiple services, it wont neccessarily add the right one. Please Help me to finish this trigger so that it will insert the two service and update the referal record with the inserted Ids.

My two questions are:

1. Can someone please help me set the last two lookups within the trigger.
2. Help me properly bulkify my code.

The

Thank you so much in advance for your time. Below is my code:

trigger Referral_AddBonusService on Referral__c (After Update, After Insert) {


List <Service__c> SerList = new List <Service__c> ();
List <Referral__c> RefList = new List <Referral__c> ();

    // New Account status record
    
    for (Referral__c R : Trigger.new) {
    
   if (R.Referee__c != null && R.Referred_IPC__c != null && R.Referrer__c != null && R.Referrer_Bonus_Service__c == null && R.Referee_Bonus_Service__c == null) { 

        Service__c Ser1 = new Service__c (); //instantiate the object to put values for future record       
        // now map Service fields to new vehicle object that is being created with this Trigger
        
        Ser1.Account__c = R.Referrer__c; // and so on so forth untill you map all the fields. 
        Ser1.Service_name__c = 'Momentum Support';
        Ser1.Service_Type__c = 'referrer-Free';
     
        
        SerList.add(Ser1);
        
       //Again
       Service__c Ser2 = new Service__c (); 
       
       Ser2.Account__c = R.Referee__c; // and so on so forth untill you map all the fields. 
         Ser2.Service_name__c = 'Momentum Support';
        Ser2.Service_Type__c = 'Referee-Free';
        
        
        SerList.add(Ser2);
        
        R.Referee_Bonus_Service__c = Ser2.Id;
         R.Referrer_Bonus_Service__c = Ser1.id;
         
         RefList.add(R);
        
        
       } 
        
    }
    try {
        insert SerList;
        Update RefList;   
    } catch (system.Dmlexception e) {
        system.debug (e);
    }
 

    
    
}

and 
trigger Referral_AddBonusService on Referral__c (Before Update, Before Insert) {


List <Service__c> SerList = new List <Service__c> ();
List<Service__c> SerIdList = [Select Id, Account__c, CreatedDate  from Service__c ORDER BY CreatedDate ];


    // New Account status record
    
    for (Referral__c R : Trigger.new) {
    
   if (R.Referee__c != null && R.Referred_IPC__c != null && R.Referrer__c != null && R.Referrer_Bonus_Service__c == null && R.Referee_Bonus_Service__c == null) { 

        Service__c Ser1 = new Service__c (); //instantiate the object to put values for future record       
        // now map Service fields to new vehicle object that is being created with this Trigger
        
        Ser1.Account__c = R.Referrer__c; // and so on so forth untill you map all the fields. 
        Ser1.Service_name__c = 'Momentum Support';
        Ser1.Service_Type__c = 'referrer-Free';
     
        
        SerList.add(Ser1);
        
       //Again
       Service__c Ser2 = new Service__c (); 
       
       Ser2.Account__c = R.Referee__c; // and so on so forth untill you map all the fields. 
         Ser2.Service_name__c = 'Momentum Support';
        Ser2.Service_Type__c = 'Referee-Free';
        
        
        SerList.add(Ser2);
        
       } 
        
    }
    try {
        insert SerList;
        
    } catch (system.Dmlexception e) {
        system.debug (e);
    }
    
    for(Referral__c R:trigger.new)
{
for(Service__c S:SerIdList){
        if(S.Account__c == R.Referee__c)
            R.Referee_Bonus_Service__c = S.Id;
if(S.Account__c == R.Referrer__c)
            R.Referrer_Bonus_Service__c = S.Id;

        }

}

}

Best Answer chosen by Developer.mikie.Apex.Student
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Solved 
trigger Referral_AddBonusService on Referral__c (Before Update, Before Insert) {


List <Service__c> SerList = new List <Service__c> ();
List <Id> AccIds = new List <Id> ();
    
    for (Referral__c R : Trigger.new) {
    
   if (R.Referee__c != null && R.Referred_IPC__c != null && R.Referrer__c != null) { 

        Service__c Ser1 = new Service__c (); //instantiate the object to put values for future record       
        // now map Service fields to new vehicle object that is being created with this Trigger
        
        Ser1.Account__c = R.Referrer__c; // and so on so forth untill you map all the fields. 
        Ser1.Service_name__c = 'Momentum Support';
        Ser1.Service_Type__c = 'referrer-Free';
        
        AccIds.add(R.Referrer__c);
        SerList.add(Ser1);
        
       //Again
       Service__c Ser2 = new Service__c (); 
       
       Ser2.Account__c = R.Referee__c; // and so on so forth untill you map all the fields. 
         Ser2.Service_name__c = 'Momentum Support';
        Ser2.Service_Type__c = 'Referee-Free';
        
           AccIds.add(R.Referee__c);
        SerList.add(Ser2);
        
        
        
       } 
        
    }
    
    
    
    
    try {
        insert SerList;
  
        
    } catch (system.Dmlexception e) {
        system.debug (e);
    }
SerList = [select id,Service_Type__c,Account__c   from Service__c where Account__c in : AccIds order by CreatedDate ];

 for (Referral__c R : Trigger.new) {
 for (Service__c S : SerList ) {
  if(S.Service_Type__c == 'Referee-Free' && S.Account__c == R.Referee__c){
    R.Referee_Bonus_Service__c = S.Id;
 } 
 if(S.Service_Type__c == 'referrer-Free' && S.Account__c == R.Referrer__c){
    R.Referrer_Bonus_Service__c = S.Id;
 }   
 }
 }   
}

All Answers

SaiGSaiG

Did you try using Maps?

Thanks,

Sai

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
No, I am quite new to apex. Would you possibly be able to provide some example code on how I may do this?
robdobbyrobdobby
When Sai mentions Maps, I assume he means something like this (after line 6 in your second listing):


Map <Id, Id> mapAccountIDServiceID = new Map <Id, Id> ();
for (Service__c nextService : SerIdList) {
     mapAccountIDServiceID.put(nextService.Account__c, nextService.Id);
}


Now you have a Map from Account to Service, which assumes that there is a  one to one relationship.  Now use this Map by replacing lines 46 to 52 with this:


Id accountRefereeId = mapAccountIDServiceID.get(R.Referee__c);
if (accountRefereeId != null) {
     R.Referee_Bonus_Service__c = accountRefereeId;
}

Id accountReferrerId = mapAccountIDServiceID.get(R.Referrer__c);
if (accountReferrerId != null) {
     R.Referrer_Bonus_Service__c = accountReferrerId;
}


I added a check for null as a sanity check because I'm not clear on your object model.
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Thank you for the reply robdobby. One account will have multiple services attached. Will this code still work if this is the case.

Thank you for your time!
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
I tried the code and yet it does not work. It adds the services, however it does not associate the records with the correct services. Please help
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Solved 
trigger Referral_AddBonusService on Referral__c (Before Update, Before Insert) {


List <Service__c> SerList = new List <Service__c> ();
List <Id> AccIds = new List <Id> ();
    
    for (Referral__c R : Trigger.new) {
    
   if (R.Referee__c != null && R.Referred_IPC__c != null && R.Referrer__c != null) { 

        Service__c Ser1 = new Service__c (); //instantiate the object to put values for future record       
        // now map Service fields to new vehicle object that is being created with this Trigger
        
        Ser1.Account__c = R.Referrer__c; // and so on so forth untill you map all the fields. 
        Ser1.Service_name__c = 'Momentum Support';
        Ser1.Service_Type__c = 'referrer-Free';
        
        AccIds.add(R.Referrer__c);
        SerList.add(Ser1);
        
       //Again
       Service__c Ser2 = new Service__c (); 
       
       Ser2.Account__c = R.Referee__c; // and so on so forth untill you map all the fields. 
         Ser2.Service_name__c = 'Momentum Support';
        Ser2.Service_Type__c = 'Referee-Free';
        
           AccIds.add(R.Referee__c);
        SerList.add(Ser2);
        
        
        
       } 
        
    }
    
    
    
    
    try {
        insert SerList;
  
        
    } catch (system.Dmlexception e) {
        system.debug (e);
    }
SerList = [select id,Service_Type__c,Account__c   from Service__c where Account__c in : AccIds order by CreatedDate ];

 for (Referral__c R : Trigger.new) {
 for (Service__c S : SerList ) {
  if(S.Service_Type__c == 'Referee-Free' && S.Account__c == R.Referee__c){
    R.Referee_Bonus_Service__c = S.Id;
 } 
 if(S.Service_Type__c == 'referrer-Free' && S.Account__c == R.Referrer__c){
    R.Referrer_Bonus_Service__c = S.Id;
 }   
 }
 }   
}

This was selected as the best answer