• 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);
}

 

 

 

 

  • April 06, 2010
  • Like
  • 0

I understand that the sandbox can be refreshed through eclipse.  How do I do this?

 

I can see the meta elements in Production (objects, custom objects, tabs, layouts, etc).  But when I use "Deploy to Server" and deploy to the Sandbox, it doesn't copy over these elements.

 

Suggestions?

 

Thanks,

  • March 10, 2010
  • Like
  • 0

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 ]);

 

 

 

  • March 02, 2010
  • Like
  • 0

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; }

 

 

 

 

 

  • March 02, 2010
  • Like
  • 0

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);
}

}

 

 

 

 

 

 

  • March 01, 2010
  • Like
  • 0

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
  • February 24, 2010
  • Like
  • 0

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
  • February 23, 2010
  • Like
  • 0

If I anticipate uploading 1000+ records at once, do I need to have my triggers ready to process bulk records?

 

Ben

  • February 19, 2010
  • Like
  • 0

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;

 

 

 

  • February 19, 2010
  • Like
  • 0

I am trying to open a new linked record using a formula field... I would like the new record to have 2 fields pre-populated -- since I am linking the new record back to two different objects.  How do I do this?

 

 

Sample -- The new record  should open in the edit mode:

                Related Student Record : XXXXXX (filled in)

                Related Case Record : XXXXXX (filled in)

 

This works -- when one field pre-populated and passed through:

 

 

HYPERLINK( "https://na5.salesforce.com/a0U/e?CF00N70000002NBfE=" & Related_Student__r.Name & "&CF00N70000002NBfE_lkid="& Related_Student__r.Id &"&retURL=%2F"& Id , "New Call: " & Related_Student__r.Student_First_Name__c & " " & Related_Student__r.Student_Last_Name__c, "self")

 

 

 

This doesn't work -- when I try to pre-populate two fields:

 

 

HYPERLINK( "https://na5.salesforce.com/a0U/e?CF00N70000002NBfE=" & Related_Student__r.Name & "&CF00N70000002NBfE_lkid="& Related_Student__r.Id &"&CF00N70000002qLox="& CaseNumber &"&CF00N70000002qLox_lkid="& Id &"&retURL=%2F"& Id , "New Call: " & Related_Student__r.Student_First_Name__c & " " & Related_Student__r.Student_Last_Name__c, "self")

 

 

  • February 19, 2010
  • Like
  • 0

How do you create a new record on an object different from the trigger?

 

More specifically whenever I create a record in 1 object, I want to create a corresponding record in another object.

 

So far I have the following, but I get an error:

System.NullPointerException: Attempt to de-reference a null object

 

 

 

trigger UpdateLabor_After on Labor__c (after insert, after update) { String RelatedLabor = null, RelatedSchool = null, RelatedDistrict = null, temp_id = null; Labor__c[] labor = trigger.new; RelatedSchool = labor[0].Related_School__c; RelatedDistrict = labor[0].Related_District__c; if(System.Trigger.isinsert) { Student_Attendance_Labor__c [] newrecord; RelatedLabor = labor[0].Id; newrecord[0].Related_Labor__c = RelatedLabor; newrecord[0].Related_School__c = RelatedSchool; newrecord[0].Related_District__c = RelatedDistrict; insert newrecord [0]; }

 

 The error looks like its related to the line:

	Student_Attendance_Labor__c [] newrecord;

 

How do I define a record that doesn't yet exist?

 

  • February 18, 2010
  • Like
  • 0

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!

 

 

  • February 11, 2010
  • Like
  • 0

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(); }

 

 

  • January 19, 2010
  • Like
  • 0

I'm interested in automatically creating a detail record when a new master record is created.  Ideally it could happen when the user clicks on the "new" master record button and the detail record is simulataneously created and linked to the master.  I am trying to avoid having to do this manually.

 

Once I have them linked, we are all set and I can pull the data that is needed.  

 

Any thoughts on

a) best way to do this Visualforce, Apex code, S-control, etc?

b) what should it look like (ie what's the code)?

 

Ben

  • September 29, 2009
  • Like
  • 0

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);
}

 

 

 

 

  • April 06, 2010
  • Like
  • 0

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 ]);

 

 

 

  • March 02, 2010
  • Like
  • 0

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; }

 

 

 

 

 

  • March 02, 2010
  • Like
  • 0

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);
}

}

 

 

 

 

 

 

  • March 01, 2010
  • Like
  • 0

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
  • February 24, 2010
  • Like
  • 0

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
  • February 23, 2010
  • Like
  • 0

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;

 

 

 

  • February 19, 2010
  • Like
  • 0

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!

 

 

  • February 11, 2010
  • Like
  • 0

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(); }

 

 

  • January 19, 2010
  • Like
  • 0