+ Start a Discussion
aiyaz_SFDCaiyaz_SFDC 

Round Robin Trigger - not compiling!

Hello All,

 

I'm receiving a compile error -

 

(Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST:SOBJECT:Lead at line 21 column 29)

 

for the following trigger code which I found in the salesforce wiki.  I'm unsure what is wrong with the "Initial term", can anyone help with this?

 

 

 

/* * Simple round robbin lead assignment, * trigger assumes the following custom fields on the User object * User. * Receiving_Leads__c -- are they open for new leads at this time * Open_Leads_Owned__c -- how many leads do they have right now * * if no matching new owner is found the default for the org is the new owner */ trigger triggerLeadRoundRobin on Lead ( before insert , after insert, after update , after delete) { if (Trigger.isBefore && Trigger.isInsert) { // find the user who can accept leads and which has the fewest at the moment Double least = 99999; // start with large number, find which user has least for ( User u : [select id,lastname,Open_Leads_Owned__c from User where isActive = true and Receiving_Leads__c = true]) { if ( u.Open_Leads_Owned__c == null || u.Open_Leads_Owned__c < least) { Trigger.new.ownerid = u.id; // this user will own the new lead least = u.Open_Leads_Owned__c; // changes owner before record is inserted } } } /* remaining code will keep the (summary field) Open_Leads_Owned__c * uptodate on each user record adjusts the value on insert, delete and transfer */ if (Trigger.isAfter) { if (Trigger.isInsert) { System.assert(Trigger.old == null,' old data row cannot exist at insert?'); System.assert(Trigger.new != null,' expected new object row in isInsert'); leadOwnerRelation.updateOpenLeadCount( Trigger.new.ownerid ); // call to a package } else if (Trigger.isUpdate ) { // as in change owner // here we have to recalc both the old owner and new owner System.assert(Trigger.old != null,' old data row must exist at update'); System.assert(Trigger.new != null,' what, no new in Trigger data in update'); if (Trigger.old.ownerid != Trigger.new.ownerid ) { // update includes a transfer owner leadOwnerRelation.updateOpenLeadCount( Trigger.old.ownerid ); leadOwnerRelation.updateOpenLeadCount( Trigger.new.ownerid ); } } else if (Trigger.isDelete) { System.assert(Trigger.old != null,' old data row must exist at delete time'); System.assert(Trigger.new == null,' cant have new object in isDelete'); leadOwnerRelation.updateOpenLeadCount( Trigger.old.ownerid ); } } } // end of trigger

 

WhyserWhyser

Hey aiyaz,

 

Your problem is highlighted in red below

 


aiyaz_SFDC wrote:

Hello All,

 

I'm receiving a compile error -

 

(Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST:SOBJECT:Lead at line 21 column 29)

 

for the following trigger code which I found in the salesforce wiki.  I'm unsure what is wrong with the "Initial term", can anyone help with this?

 

 

 

/* * Simple round robbin lead assignment, * trigger assumes the following custom fields on the User object * User. * Receiving_Leads__c -- are they open for new leads at this time * Open_Leads_Owned__c -- how many leads do they have right now * * if no matching new owner is found the default for the org is the new owner */ trigger triggerLeadRoundRobin on Lead ( before insert , after insert, after update , after delete) { if (Trigger.isBefore && Trigger.isInsert) { // find the user who can accept leads and which has the fewest at the moment Double least = 99999; // start with large number, find which user has least for ( User u : [select id,lastname,Open_Leads_Owned__c from User where isActive = true and Receiving_Leads__c = true]) { if ( u.Open_Leads_Owned__c == null || u.Open_Leads_Owned__c < least) { Trigger.new.ownerid = u.id; // this user will own the new lead least = u.Open_Leads_Owned__c; // changes owner before record is inserted } } } /* remaining code will keep the (summary field) Open_Leads_Owned__c * uptodate on each user record adjusts the value on insert, delete and transfer */ if (Trigger.isAfter) { if (Trigger.isInsert) { System.assert(Trigger.old == null,' old data row cannot exist at insert?'); System.assert(Trigger.new != null,' expected new object row in isInsert'); leadOwnerRelation.updateOpenLeadCount( Trigger.new.ownerid ); // call to a package } else if (Trigger.isUpdate ) { // as in change owner // here we have to recalc both the old owner and new owner System.assert(Trigger.old != null,' old data row must exist at update'); System.assert(Trigger.new != null,' what, no new in Trigger data in update'); if (Trigger.old.ownerid != Trigger.new.ownerid ) { // update includes a transfer owner leadOwnerRelation.updateOpenLeadCount( Trigger.old.ownerid ); leadOwnerRelation.updateOpenLeadCount( Trigger.new.ownerid ); } } else if (Trigger.isDelete) { System.assert(Trigger.old != null,' old data row must exist at delete time'); System.assert(Trigger.new == null,' cant have new object in isDelete'); leadOwnerRelation.updateOpenLeadCount( Trigger.old.ownerid ); } } } // end of trigger

 


Do you know what Trigger.new and Trigger.old returns?

 

Let's say you have about 3 leads being updated that are calling your trigger.

 

Trigger.new = {Lead{id='9a8h9124ah9'; FirstName='test'; LastName='test';etc.}; Lead{id='9a8hasd9ah9'; FirstName='test'; LastName='test';etc.}; Lead{id='9a8h9235ah9'; FirstName='test'; LastName='test';etc.} }

 

I didn't write down all the fields that go with the trigger, but it includes all standard and custom fields on the lead. Trigger.new and Trigger.old returns an ARRAY or a LIST of objects based on the trigger definition, which in your case is, Leads.

 

The difference between Trigger.new and Trigger.old is that the old contains all the original values before the update, and Trigger.new will contain the updated values.

 

When you say Trigger.new.ownerId, do you see why you are getting an error? You're looking for a field in an array, when you should be looking for a field in a Lead object.

 

You can do

 

for ( Lead l : Trigger.new ) { // All your code here // Instead of referring to Trigger.new.ownerid, you can now say // l.ownerid = u.Open_Leads_Owned__c; }

Your assert statements will never be null, because Trigger.new and old will always contain the array lead(s) that are changing. I didn't look too deeply into your isAfter code, so I'm not too sure what you're trying to accomplish there.

 

 

MaxaMaxa

is it possible to modify this trigger to assign leads wiht specific industries to specific people in roud robyn fashion?

do i just use some thign like this

for ( User u : [select id,lastname,Open_Leads_Owned__c from User           
                    where isActive = true and Receiving_Leads__c = true] && Lead ld:[select id, Industry, from Lead where indutry ='Heavy')

 

 

or am i doign some thing wrong?

WhyserWhyser

@Maxa 

I'm not sure if that code is able to compile...

 

Is this a lead trigger? You shouldn't be needing to query leads if this is a lead trigger since Trigger.new should contain all the new/updated leads.

 

Perhaps approach it like this. It's not round robin, but it's randomly assigned.

 

// Get all your users that you want to assign to leads for a specific industry

List< User > uList = [select id from User where isActive = true and Receiving_Leads__c = true];

 

// Now go through your list of Leads being updated that have a specific industry

if ( uList.size() > 0 )

{

  for ( Lead l : Trigger.new )

  {

     if ( Lead.industry = 'Heavy' ) Lead.ownerId = uList.get( Math.floor( Math.random() * uList.size() ).intValue() );

  }

}

 

Of course, I've had people just copy my code and say that it doesn't work. This is just a guideline, adjust the code to make it do however you need it to... so if you have different industries or different user criteria for assignment, adjust the code accordingly.

Message Edited by Whyser on 07-17-2009 01:09 PM
MaxaMaxa
thanks for your help i try it out
Thys MichelsThys Michels

What do I need to enter in the place of: Trigger.old.ownerid and Trigger.new.ownerid?

Thys MichelsThys Michels

Can anyone post an update to this code?