• bpol
  • NEWBIE
  • 60 Points
  • Member since 2009

  • Chatter
    Feed
  • 2
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 14
    Questions
  • 16
    Replies

I am getting the error "Loop must iterate over a collection type: SOBJECT: ROI__c" coming from the second loop in the excerpt below.

 

Not sure how to resolve...

 

 

Set <id> studentListIds = new set <id> ();

for (Student__c aa :studentList) {
     studentListIds.add (aa.id);
}
	
ROI__c roiStudentList = [select Id, Related_Student__c from ROI__c where Related_Student__c in :studentListIds];
		
for(ROI__c xx : roiStudentList) {
     System.assertNotEquals(null, xx.Related_Student__c);
}

 

 

 

 

I can't tell why this isn't working...

 

Is there a way to add a de-bugging method to the trigger to see what is happening? 

 

How do I know if the first few definitions (particularly of the list "list_relatedstudents" isn't null after I try to define it; then when I go to update the list with "update list_relatedstudents" nothing happens)?

 

 

trigger Bulk_CallLogs on Student_Call_Log__c (after insert, after update) { list<Student_Call_Log__c> list_thelogs = new list<Student_Call_Log__c>(); // list contains all of the logs being processed // Step 1 set <id> list_relatedstudents_temp = new set <id> (); for (Student_Call_Log__c log :list_thelogs) { list_relatedstudents_temp.add(log.related_student__c); } list<Student__c> list_relatedstudents = ([select id, Most_Recent_Call_Note__c, Tech_Support_Logs__c, Call_Count__c from Student__c where id IN :list_relatedstudents_temp]); // Step 2 list<Student_Call_Log__c> list_relatedlogs = ([select id, related_student__c, date__c, note__c from Student_Call_Log__c where related_student__c IN :list_relatedstudents order by Date__c DESC ]); list<Student_Call_Log__c> list_relatedlogs_mostrecent = ([select id, related_student__c, date__c, note__c from Student_Call_Log__c where related_student__c IN :list_relatedstudents order by Date__c DESC limit 1 ]);

 

 

 

Here's a bulk trigger I just wrote (I am new to this)... and it looks ok on paper. 

 

But when I add or update 1 record in the sandbox... the parent record remains unchanged.  Nothing happens... not even an incorrect answer.

 

Any thoughts?

 

Basic idea of the trigger is to update parent record (Student__c) when child records (Student_Call_Log__c) is changed.  I update the following fields on the Student__c object: call count, most recent call note and tech_support_log__c.

 

 

trigger Bulk_CallLogs on Student_Call_Log__c (after insert, after update) { // 1. Loop through Trigger.new & throw the relevent info in a list (either list of leads, list of lead id's, etc) // 2. Use the list to query related objects to populate another list // 3. Loop through the 2nd list to create a map of LeadID to related object // 4. Loop again through Trigger.new to add the related info to Lead using the map from #3 list<Student_Call_Log__c> list_thelogs = new list<Student_Call_Log__c>(); // list contains all of the logs being processed // Step 1 set <id> list_relatedstudents_temp = new set <id> (); for (Student_Call_Log__c log :list_thelogs) { list_relatedstudents_temp.add(log.related_student__c); } list<Student__c> list_relatedstudents = ([select id, Most_Recent_Call_Note__c, Tech_Support_Logs__c, Call_Count__c from Student__c where id IN :list_relatedstudents_temp]); // Step 2 list<Student_Call_Log__c> list_relatedlogs = ([select id, related_student__c, date__c, note__c from Student_Call_Log__c where related_student__c IN :list_relatedstudents order by Date__c DESC ]); list<Student_Call_Log__c> list_relatedlogs_mostrecent = ([select id, related_student__c, date__c, note__c from Student_Call_Log__c where related_student__c IN :list_relatedstudents order by Date__c DESC limit 1 ]); map<id, id> map_students = new map<id, id>(); map<id, date> map_log_date = new map<id, date>(); map<id, String> map_log_calltype = new map<id, string>(); map<id, String> map_log_callresult = new map<id, string>(); map<id, String> map_log_note = new map<id, string>(); map<id, Integer> map_log_counter = new map <id, integer>(); Integer counter = 1; //Step 3-A for (Student__c s :list_relatedstudents) { for (Student_Call_Log__c log :list_relatedlogs) { map_students.put(s.id, log.id); map_log_date.put(log.id, log.Date__c); map_log_calltype.put(log.id, log.Call_Type__c); map_log_callresult.put(log.id, log.Call_Results__c); map_log_note.put(log.id, log.note__c); map_log_counter.put(log.id, counter); } } //Step 4-A String temp_lognote = null; counter = 0; for (Student__c s :list_relatedstudents) { for (Student_Call_Log__c log :list_relatedlogs) { temp_lognote = temp_lognote + map_log_date.get(log.id) + ' -- ' + map_log_calltype.get(log.id) + ' -- ' + map_log_callresult.get(log.id) + ' -- ' + map_log_note.get(log.id) + '\n'; counter = counter + map_log_counter.get(log.id); } s.Tech_Support_Logs__c = temp_lognote; s.Call_Count__c = counter; temp_lognote = null; counter = 0; } //Step 3-B map<id, id> map_students_mostrecent = new map<id, id>(); map<id, string> map_log_mostrecentnote = new map<id, string>(); for (Student__c s :list_relatedstudents) { for (Student_Call_Log__c log :list_relatedlogs_mostrecent) { map_students_mostrecent.put(s.id, log.id); map_log_mostrecentnote.put(log.id, log.note__c); } } //Step 4-B for (Student__c s :list_relatedstudents) { for (Student_Call_Log__c log :list_relatedlogs_mostrecent) { s.Most_Recent_Call_Note__c = map_students_mostrecent.get(log.id); } } //Update records update list_relatedstudents; }

 

 

 

 

 

Here's my original code and test... but I still have 0 coverage

 

Trigger:

 

 

trigger Bulk_CallLogs on Student_Call_Log__c (after delete, after update) {

// 1. Loop through Trigger.new & throw the relevent info in a list (either list of leads, list of lead id's, etc)
// 2. Use the list to query related objects to populate another list
// 3. Loop through the 2nd list to create a map of LeadID to related object
// 4. Loop again through Trigger.new to add the related info to Lead using the map from #3


list<Student_Call_Log__c> list_thelogs = new list<Student_Call_Log__c>(); // list contains all of the logs being processed

// Step 1
set <id> list_relatedstudents_temp = new set <id> ();

for (Student_Call_Log__c log :list_thelogs) {
list_relatedstudents_temp.add(log.related_student__c);
}

list<Student__c> list_relatedstudents = ([select id from Student__c where id IN :list_relatedstudents_temp]);

// Step 2
list<Student_Call_Log__c> list_relatedlogs = ([select id, related_student__c, date__c from Student_Call_Log__c where Id IN :list_thelogs order by Date__c DESC ]);

list<Student_Call_Log__c> list_relatedlogs_mostrecent = ([select id, related_student__c, date__c from Student_Call_Log__c where Id IN :list_thelogs order by Date__c DESC limit 1 ]);

map<id, id> map_students = new map<id, id>();
map<id, date> map_log_date = new map<id, date>();
map<id, String> map_log_calltype = new map<id, string>();
map<id, String> map_log_callresult = new map<id, string>();
map<id, String> map_log_note = new map<id, string>();
map<id, Integer> map_log_counter = new map <id, integer>();
Integer counter = 1;

//Step 3-A

for (Student__c s :list_relatedstudents) {
for (Student_Call_Log__c log :list_relatedlogs) {
map_students.put(s.id, log.id);
map_log_date.put(log.id, log.Date__c);
map_log_calltype.put(log.id, log.Call_Type__c);
map_log_callresult.put(log.id, log.Call_Results__c);
map_log_note.put(log.id, log.note__c);
map_log_counter.put(log.id, counter);
}
}

//Step 4-A

String temp_lognote = null;
counter = 0;

for (Student__c s :list_relatedstudents) {
for (Student_Call_Log__c log :list_relatedlogs) {
temp_lognote = temp_lognote + map_log_date.get(log.id) +
' -- ' + map_log_calltype.get(log.id) +
' -- ' + map_log_callresult.get(log.id) +
' -- ' + map_log_note.get(log.id) + '\n';
counter = counter + map_log_counter.get(log.id);
}
s.Tech_Support_Logs__c = temp_lognote;
s.Call_Count__c = counter;
temp_lognote = null;
counter = 0;
}

map<id, id> map_students_mostrecent = new map<id, id>();
map<id, string> map_log_mostrecentnote = new map<id, string>();

//Step 3-B

for (Student__c s :list_relatedstudents) {
for (Student_Call_Log__c log :list_relatedlogs_mostrecent) {
map_students_mostrecent.put(s.id, log.id);
map_log_mostrecentnote.put(log.id, log.note__c);
}
}

//Step 4-B

for (Student__c s :list_relatedstudents) {
for (Student_Call_Log__c log :list_relatedlogs_mostrecent) {
s.Most_Recent_Call_Note__c = map_students_mostrecent.get(log.id);
}
}

}

 

Test:

@isTest
private class Test_Bulk_CallLogs {

static testMethod void myUnitTest() {
// TO DO: implement unit test

//set initial test parameters
//create Parent Account, Account, Opportunity, Implementation, Student and Call Log records
String userid = null;
Integer i = null;
String impid = null;
String impid2 = null;
userid = '00570000001KoP8AAK';

Account testaccountdistrict = new Account (Name = 'Test District', type = 'District', County__c = 'Alameda County');
insert testaccountdistrict;
Account testaccountschool = new Account (Name = 'Test School', type = 'School', ParentId = testaccountdistrict.Id, County__c = 'Alameda County');
insert testaccountschool;
Opportunity testoppy = new Opportunity (AccountId = testaccountdistrict.id, Name = 'Test Oppy', StageName = 'Closed-Won', CloseDate = System.today(), Fiscal_Year_Extreme__c = '2010', Program_Type__c = 'Targeted', Deal_Type__c = 'Standard @Avanza', Payment_Type__c = 'Attendance');
insert testoppy;
Implementation__c testimp = new Implementation__c (name = 'Test Implementation', related_account__c = testaccountschool.id, related_opportunity__c = testoppy.id, Area_Manager__c = userid, Delivery_Date__c= system.today(), Start_Date__c = system.today(), Related_Student_Count__c=0);
insert testimp;
Implementation__c testimp2 = new Implementation__c (name = 'Test Implementation2', related_account__c = testaccountschool.id, related_opportunity__c = testoppy.id, Area_Manager__c = userid, Delivery_Date__c= system.today(), Start_Date__c = system.today(), Related_Student_Count__c=0);
insert testimp2;
impid2 = testimp2.id;
Student__c teststudent = new Student__c (Student_First_Name__c='Test First Name', Student_Last_Name__c ='Test Last Name', Related_Opportunity__c = testoppy.id , Related_School__c = testaccountschool.id, Grade_FY10__c = 10, Related_Implementation__c = testimp.id);
insert teststudent;

List<Student_Call_Log__c> calllogs = new List<Student_Call_Log__c>();

for(Integer j = 0; i < 200; j++){
Student_Call_Log__c testcall = new Student_Call_Log__c (Note__c='hello'+ j, Date__c = System.today(), Call_Type__c = 'Assessment', Call_Results__c ='ok', Caller_Name__c = 'AVANZA', Related_Student__c = teststudent.Id);
calllogs.add(testcall);
}
// Start the test, this changes governor limit context to
// that of trigger rather than test.
test.startTest();

// Insert the Log records that cause the trigger to execute.
insert calllogs;

// Stop the test, this changes limit context back to test from trigger.
test.stopTest();

// Query the database for the newly inserted records.
List<Student_Call_Log__c> insertedlogs = [SELECT Date__c, Note__c
FROM Student_Call_Log__c
WHERE Id IN :calllogs];

// Assert that the Description fields contains the proper value now.
for(Student_Call_Log__c log :insertedlogs){
System.assertEquals(System.today(), log.Date__c);
}

}

 

 

 

 

 

 

I've written my first bulk-ready trigger!! 

 

It works -- that is, it doesn't break and it updates with the correct data -- when editing a single record!!

 

But it doesn't work: specifically when I bulk upload records, the records upload, but the data generated by the trigger is _very_ incorrect, some is missing.  Not sure what happened.  Interestingly when I edit one of these uploaded records, and re-save the record, it looks good.

 

Help!

 

Here's the trigger... (it's a bit long)

 

>> The three fields I am trying to update are Record_Type__c, Related_School__c, and Related_District__c

>> I key off of Dept_Seg_1__c for Record_Type__c

>> I also key off of Dept_Seg_2__c and Dept_Seg__3__c which in combination can relate back to an Account which leads to the Record_School__c and Record_District__c

 

trigger Bulk_Labor_Before on Labor__c (before insert, before update) {

// Loop through all of the Labor Records and collect necessary lists
//------------------------------------------------------------------
list<Labor__c> thelabor = new list<Labor__c>(); // list contains all of the labor being processed

map<String, String> map_ltype_to_typename = new map<String, string> {
'201' => 'mh center', '310' => 'staffing', '410' => 'sales',
'510' => 'marketing', '610' => 'training', '710' => 'it',
'810' => 'accounting & finance', '820' => 'hr',
'110' => 'call center', '411' => 'recruiting', '150' => 'online - coaching',
'101' => 'onsite - coaching', '102' => 'onsite - coaching', '103' => 'onsite - coaching',
'104' => 'onsite - coaching', '105' => 'onsite - coaching', '106' => 'onsite - coaching',
'' => ''};
map<id, String> map_lId_to_typename = new map<id, String> ();

list<string> list_districtschool = new list<string>();
list<string> list_schools = new list <string>();
map<id, String> map_lId_to_districtschool = new map<id, string>();
map<id, string> map_lId_to_districtORschool = new map <id, string>();
map<String, id> map_districtschool_accountid = new map<String, id>();
map<String, id> map_districtschool_accountid_parent = new map<String, id>();
map<string, id> map_school_accountid = new map <String, id>();
map<string, id> map_school_accountid_parent = new map <String, id>();

String temp_recordtype = null; // temporary, working variable
String temp_districtcode = null, temp_schoolcode = null, temp_dscode=null;
String dORs = null;

for (Labor__c l :trigger.new) {
thelabor.add(l); // add labor to the main list

temp_recordtype = map_ltype_to_typename.get(l.Dept_Seg_1__c); // set map for general cases

if (l.Dept_Seg_1__c == '150') { // set map to exceptions
if (l.Dept_Seg_2__c == '00004') (temp_recordtype = 'online - tech support');
if (l.Dept_Seg_2__c == '00002') (temp_recordtype = 'online - admin');
if (l.Dept_Seg_2__c == '20000') (temp_recordtype = 'online - admin');
if (l.Dept_Seg_3__c == '0000001') (temp_recordtype = 'online - admin');
if (l.Dept_Seg_3__c == '0000005') (temp_recordtype = 'online - admin');
}
map_lId_to_typename.put(l.id, temp_recordtype);


temp_districtcode = string.valueOf(l.Dept_Seg_2__c);
temp_schoolcode = string.valueOf(l.Dept_Seg_3__c);
if (temp_schoolcode == null){
(temp_schoolcode = '0000000');
}

if (temp_districtcode == null) {
if (temp_schoolcode == '0000000') (temp_schoolcode = '');
dORs = 'S';
temp_dscode = temp_schoolcode;
list_schools.add(temp_schoolcode); // create list of accounts with no district code
}

if (temp_districtcode != null) {
dORs = 'D';
temp_dscode = temp_districtcode + temp_schoolcode;
list_districtschool.add(temp_dscode); // create list of accounts with a district

// code (and possibly a school code)
}

map_lId_to_districtORschool.put(l.id,dORs);

map_lId_to_districtschool.put(l.id,temp_dscode);

}

list <Account> the_districtschoolaccounts = ([select id, parentid, Account_DS_code__c, Account_D_code__c, Account_S_code__c from Account
where Account_DS_Code__c IN :list_districtschool]); // create list of accounts with district codes
list <Account> the_schoolaccounts = ([select id, parentid, Account_DS_code__c, Account_D_code__c, Account_S_code__c from Account
where Account_S_Code__c IN :list_schools]); // create list of accounts w school codesonly

// Create a map of the labordistricts and schools and associated account ids
for (Account a :the_districtschoolaccounts) {
map_districtschool_accountid.put(a.Account_DS_code__c, a.id);
map_districtschool_accountid_parent.put(a.Account_DS_code__c, a.parentid);
}
for (Account a :the_schoolaccounts) {
map_school_accountid.put(a.Account_S_code__c, a.id);
map_school_accountid_parent.put(a.Account_S_code__c, a.parentid);
}

// Loop through all of the Labor Records and insert relevant data
// --------------------------------------------------------------
for (Labor__c l :thelabor){
l.Record_Type__c = map_lid_to_typename.get(l.id);
if (map_lId_to_districtORschool.get(l.id)=='D') {
l.Related_School__c =

map_districtschool_accountid.get(map_lId_to_districtschool.get(l.id));
l.Related_District__c =

map_districtschool_accountid_parent.get(map_lId_to_districtschool.get(l.id));
}
if (map_lId_to_districtORschool.get(l.id)=='S') {
l.Related_School__c =

map_school_accountid.get(map_lId_to_districtschool.get(l.id));
l.Related_District__c =

map_school_accountid_parent.get(map_lId_to_districtschool.get(l.id));
}
}

}

 

 

 

 

 

Message Edited by bpol on 02-24-2010 01:49 AM
Message Edited by bpol on 02-24-2010 02:06 AM

I'm new, so I know I have the syntax wrong.  Any help with creating a bulk trigger would be greatly appreciated.

 

For each record that is inserted or updated, the trigger should

  • >review the field "Dept_Seg_1__c",
  • >lookup the mapped value "record_type__c" --- there is a map of Dept_Seg_1__c to record_type__c, and
  • >update the field "record_type__c" on all of the new/inserted records

 

Thanks!

 

Ben 

 

 

trigger UpdateLabor_Before on Labor__c (before insert, before update) {

//Create nested map of Labor ID TO Map of Record Type IDs TO Record Type Names
Map<ID,Map<String,String>> labortypeMap = new Map<ID,Map<String,String>> ();
Map<Dept_Seg_1__c,Record_Type__c> labortypeNestMap = new Map<String,String>
{'201' => 'mh center', '310' => 'staffing', '410' => 'sales',
'510' => 'marketing', '610' => 'training', '710' => 'it',
'810' => 'accounting & finance', '820' => 'hr',
'110' => 'call center', '411' => 'recruiting', '150' => 'coaching'};

for(Labor__c laborloop : trigger.new) {
labortypeMap.put(laborloop.id,
Dept_Seg_1__c,
labortypeNestMap.get(laborloop.Record_Type__c));

// Set records to values based on map
Labor__c labor = new Labor__c (Record_Type__c = labortypemap.get.(Record_Type__c));
Labor__c.add(labor);

}

upsert labor;

}

 

 

Message Edited by bpol on 02-22-2010 04:28 PM

This works fine as a single trigger.  I'm new to writing bulk triggers. 

 

How do I go about bulk-ifying this trigger?

 

Ben

 

 

temp_studentid = sa[0].StudentID_SIS__c;
if (temp_studentid <> null) {
temp_recordtype = 'onsite - coaching';
try {
RelatedStudentId = [select
id, Extreme_Student_ID__c
from Student__c where Extreme_Student_ID__c = :temp_studentid].id;
} catch (system.Exception e4){
}

}

//----------------------------------------------------------------
// Set fields for Updating
//----------------------------------------------------------------

sa[0].Related_School_Account__c = RelatedSchoolid;
sa[0].Related_District_Account__c = RelatedDistrictid;
sa[0].Related_Student__c = RelatedStudentid;
sa[0].Record_Type__c = temp_recordtype;

 

 

 

I am trying to create a field on a master object that is a concatenation of a field on a detail object when certain things are true.

 

In this particular case, "Student__c" is the master object and "Student_Call_Logs__c" is the detail object.  I'd like to pull the notes & dates field from the call log when the call is of a particular type... and stick this info into 1 field that would look like

 

"date -- note

 date -- note

 date -- note"

 

So far I have...

 

 

trigger CountRelatedCallLogs on Student_Call_Log__c (after insert, after update) { //define parameters //Student__c is the master object; Student_Call_Logs__c is the detail object String sid = null, note = null, techlogs = null, temp_note = null, temp_date = null; Integer i = null, counter=null; Set<Id> techlogids = new set<Id>(); techlogs = ''; counter = 0; Student_Call_Log__c [] scl = Trigger.new; sid = scl[0].Related_Student__c; Student_Call_Log__c [] relatedCLogs =[select id from Student_Call_Log__c where Related_Student__c = :sid and Call_Type__c = 'Avanza Tech Support' order by Call_Date_Time__c DESC]; for (Student_Call_Log__c cl : relatedCLogs) { temp_note = relatedCLogs[counter].Note__c; temp_date = relatedCLogs[counter].Call_Date__c techlogs = techlogs + temp_date + ' -- ' + temp_note + '\n'; counter = counter+1; }

 

So, I seem to be stuck in that I can't put the info into one 1 field AND I don't know how to pull the date and stick that into a text field.

 

Thanks!

 

 

This is my first APEX coding... and, I need a bit of help. 

 

I am trying to count the # of related records...

 

I'd then, like to make a field on the current record equal to this count.

 

The following seems to work well... except I don't know how to limit the select statement to where the related_id = the id of the current record.  How do I make the variable "sid" = the id on the current record on the object Students?  Also, do I need a "loop" -- if so, how would this look?

 

Many thanks!

 

trigger CountRelatedCallLogs on Student__c (before insert, before update) { Student__c[] s = Trigger.new; String sid = null; Sid = s.id; LIST <Student_Call_Log__c> log = [SELECT Id, Related_Student__c, Date__c, Note__c FROM Student_Call_Log__c clog WHERE Student_Call_Log__c.Related_Student__c = :sid ORDER BY Related_Student__c, Id DESC LIMIT 1000]; s[0].Call_Count__c = log.size (); s[0].Most_Recent_Call_Note__c = sid(); }