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
Terry411Terry411 

Help Optimizing a Trigger

My code is working but it's certainly not optimized so I'm hoping for tips on how to clean this up...

 

The code is tracking students (Attend_Record__c) who attended attended class (Class__c) on a specific date (Attendance__c).   The object hierarchy would be Attendance__c is the parent to Attend_Record__c.  Class__c is a lookup object to Attendance__c.

 

When attendance is being taken for the student (Attend_Record__c) the only value entered is a Student_Id__c.  Based on that field, I resolve a variety of other fields:

  1. determine the ContactID (the actual student record)
  2. add the Class__c.Id and School (Account ID) fields
  3. determine the status of the student's contract and the type of contract (this will come either from an object that all users have access to (Student_Lookup__c) or from the contract (limited access)

I'm not sure how to implement best practices when I need to retrieve data from 3 or 4 different places.  How would you consolidate this to optimize it?

 

trigger trgAttendRecord_GetContactBasedOnStudentId on Attend_Record__c (before insert, before update) {
  // This trigger populates Attend_Record__c.Student__c based on the data entered in Attend_Record__c.Student_Id__c
  
  // if we already have the status, there is no need to run this code.  Also allows mass data loading
  if (trigger.new[0].Status__c > '') {
    if (trigger.new[0].Update_Status__c == false) return;
    if (trigger.new[0].Update_Status__c == null) return;
  }
  
  
  // step 1 - retrieve the student id from Student_Lookup__c.Student_ContactID__c
  set<string> SI = new set<string>();  
  set<Id> AttendId = new set<Id>();  
  for (Attend_Record__c arc : trigger.new) {
    if (arc.Student_Id__c == null) {
      continue ;
    }
    if (arc.Student_Id__c == '') {
      continue ;
    }
    SI.add(arc.Student_Id__c);
    AttendId.add(arc.Attendance_For__c);
  }
  
  
  // step 2 - create a map of the StudentIds and ContactIds for reference    
  map<string, string> StudentIdMap = new map<string, string>();
  for (Student_Lookup__c s:[select Student_Id__c, Student_ContactID__c from Student_Lookup__c where Student_Id__c IN :SI])  
    StudentIdMap.put(s.Student_Id__c, s.Student_ContactID__c);
  
  
  // step 3 - get parent (Attendance__c) field vaules
  string txtClass = null;
  string txtSchool = null;
  for (Attendance__c[] ac2 : [Select a.Id, a.Class__c, a.Class__r.School__c from Attendance__c a where a.Id IN :AttendId]) {
    for (Attendance__c a : ac2) {
      txtClass = a.Class__c;
      txtSchool = a.Class__r.School__c; 
    }
  }
  
  
  // step 4 - resolve the student id to return the ContactId and status
  for (Attend_Record__c arc2 : Trigger.new) {
    // reset Update_Status__c flag
    arc2.Update_Status__c=false;
    
    // get the Student's ContactId
    arc2.Student__c = StudentIdMap.get(arc2.Student_Id__c);
    
    // Check Student Role - if empty set it to Student
    if (arc2.Role__c == '') arc2.Role__c = 'Student';
    
    // set default for Program name
    arc2.Program__c = '';
    
    // get Student's Class Status
    List<Student_Lookup__c> slc = [Select s.School_ClassID__c, s.School_AccountID__c, s.Program_Name__c from Student_Lookup__c s  where s.Student_ID__c = :arc2.Student_Id__c];
    for (Student_Lookup__c sl: slc) {
      // set Program name
      arc2.Program__c = sl.Program_Name__c;
      
      // set agreement Status
      if (sl.School_ClassID__c == txtClass) {
        arc2.Status__c = 'Student';
      } else if (sl.School_AccountID__c == txtSchool) {
        arc2.Status__c = 'Guest Time';
      } else arc2.Status__c = 'Guest Location';
    }

    if (slc.isEmpty()) {
      // set agreement Status
      List<contract> c = [Select c.EndDate, c.Student__c from Contract c where c.Student_ID__c = :arc2.Student_Id__c order by c.EndDate asc];
      if (c.isEmpty()) {
        arc2.Status__c = 'No Agreement';
      } else {
        for (contract c2 : c) {
          arc2.Student__c = c2.Student__c;
        }
        arc2.Status__c = 'Expired Agreement';
      }
    }    
  }
}

 Thanks

aj2taylo2aj2taylo2

If you could paste your code in an easier-to-read format (e.g. some line breaks), it would be easier to help.

Terry411Terry411

Sorry about the code format... Hopefully it looks better now.  Thanks for any help!

uptime_andrewuptime_andrew

The key problem is you have SOQL queries inside  your for loop (Step 4);  you should re-visit your code to do the queries on the list of Ids first, do the query, save in a MAP, and then reference the map in your for loop.