You need to sign in to do that
Don't have an account?
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:
- determine the ContactID (the actual student record)
- add the Class__c.Id and School (Account ID) fields
- 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
If you could paste your code in an easier-to-read format (e.g. some line breaks), it would be easier to help.
Sorry about the code format... Hopefully it looks better now. Thanks for any help!
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.