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
GeneRegistryGeneRegistry 

Assignment Rules and dmo.assignmentRuleHeader.assignmentRuleId

Hello

My organization has our own custom Lead Assignment Rules but they aren't firing whenever a Lead comes in from an external source. I've come to find out that the following code has to be executed as detailed here: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_database_dmloptions.htm

Unfortunately, there realy isn't a controller or class that inserts Leads, which is where the code detailed above would be inserted at. Instead, we are using a third party vendor that has set up web pages which then push the form information and create a Lead.

The closest thing I have is a before insert trigger with the following code:

if(Trigger.isInsert){
        Database.DMLOptions dmo = new Database.DMLOptions();
	dmo.assignmentRuleHeader.assignmentRuleId= '01Q60000000JZmdEAG';
			
	for(Lead l : Trigger.new){
		l.setOptions(dmo);
	}
}

 
This doesn't appear to be working though. Whenever Leads come in, they don't trigger the rules. Any help would be greatly appreciated.

Best Answer chosen by Admin (Salesforce Developers) 
kibitzerkibitzer

Try an after-insert trigger.

 

Then use Database.Update to update the leads.

 

This isn't a 100% solution for every organizaiton - configuration, settings & workflows can interfere.


Dan

 

All Answers

kibitzerkibitzer

Try an after-insert trigger.

 

Then use Database.Update to update the leads.

 

This isn't a 100% solution for every organizaiton - configuration, settings & workflows can interfere.


Dan

 

This was selected as the best answer
GeneRegistryGeneRegistry

I'll be able to test this on Monday and let you know if it worked. Thanks for the reply though.

GeneRegistryGeneRegistry

I got the following error:

 

The following error occurs:
Apex trigger LeadTriggerAfter caused an unexpected exception,
contact your administrator:
LeadTriggerAfter: execution of AfterInsert caused by: System.SObjectException:
DML statment cannot operate on trigger.new or trigger.old: Trigger.LeadTriggerAfter: line 33, column 1

kibitzerkibitzer

You can requery to obtain a list of objects you can update.

 

Dan

 

GeneRegistryGeneRegistry

It sounds like I would need to implement your suggestion in a scheduled job as opposed to this trigger though and I don't think that solution really meets my company's needs.

Any idea why it's not firing in the before insert trigger?

GeneRegistryGeneRegistry

Interestingly enough I actually ran into a problem that may be related...

 

I'm also trying to create 3 opportunities in an after insert trigger for Accounts and it's not firing either when I do lead-convert. It does fire when I do a manual Account creation though. Seems like there may be some sort of lock that prevents certain actions perhapse??

kibitzerkibitzer

Well, the DMLOptions approach for running assignment rules only takes effect when you do an update.

And you can't do an update in a before trigger - you set fields directly at that point.

So the logical place to do the update is during the after trigger.

You shouldn't need a scheduled job - you can requery the records during the after trigger and perform the update at that point.

 

However... that's not 100% reliable - because if you have workflows or other things going on in the system you might be trying to run assignment rules in the same context during which they've already run. Apex only allows you to nest things so far before it decides you're in an infinite loop and stop performing operations. So, while I don't know for sure - in my experience it's not reliable to run assignment rules a second time in a context in which they've already run.

 

The safest thing to do is to perform a future call, passing the IDs of the records you want to reassign, and perform the reassignment then.

kibitzerkibitzer

On conversions you should always use after triggers. That's because before triggers do not fire by default during a conversion. You can enable those triggers and validation rules via lead settings, but it can have other side effects so I wouldn't recommend changing that setting without careful thought and planning - it might impact other code or business processes on your system.

GeneRegistryGeneRegistry

Good to know about the conversion not triggering any before triggers. Didn't know that limitation existed. EDIT: It appears that even trigger afters do not get executed upon conversion.

As for my assignment rules, I can't use the after trigger since I would need to be updating the very records that the after trigger acts upon.

I still don't understand why the before trigger doesn't work. I've tried the following code that actually inserts a Lead and it works fine:

Database.DMLOptions dmo = new Database.DMLOptions();
dmo.assignmentRuleHeader.assignmentRuleId= '01Q60000000JZmdEAG';

Lead l = new Lead();
l.Name = 'Test Blah blah blah'
l.setOptions(dmo);
insert l;

 Very frustrating!!

kibitzerkibitzer

It's perfectly fine to update the same objects that the trigger is acting on in an after trigger. Doing so will cause another after Update trigger - so you need to use a static variable to prevent processing the record again (this design pattern is discussed at some length in my book).

 

The before trigger doesn't work because it's not the setOptions that is triggering the assignment rules, it's the DML operation with the assignmentRuleHeader already set. Changing the assignmentRuleHeader during a before trigger has no impact. I don't know why they decided to do it that way, but that's how it is.

 

The insert command works because it is a DML operation - it doesn't really matter when you call it.

 

Dan

 

GeneRegistryGeneRegistry

Alright that explained a lot. Thanks fpr the help and for the patience.

That finally worked. I implemented a SOQL query in the trigger after on Leads under the if(Trigger.IsInsert). I also implememted the flag you suggested via a global class as suggested in this thread: http://boards.developerforce.com/t5/Apex-Code-Development/Trigger-is-fired-twice-due-to-the-workflow-rule-field-update/m-p/123488#M14861 

Now the Lead assignment rules work like a charm.

Thanks again.

kibitzerkibitzer

Glad it worked out.

 

Now, just so you know... that particular design pattern is... well... not particularly good, efficient or elegant. (you certainly don't need a global class for this purpose - any public class will do).

 

The solution you have works now, but is fragile - as time goes on and you find yourself extending the system further (or someone else does), there's a decent possibility that you're going to start seeing unexpected, intermittent and hard to reproduce failures.

 

Some places where you may start seeing problems:

- Data imports where you're doing assignment on import (rules you trigger may not run)

- Interactions with other code that tries to do assignments

- Code that tries to insert leads during a context that includes lead insertion.

 

Not suggesting you do anything about it now - since it is working for you. But I do encourage you to learn how to handle some more advanced architectures.

 

Dan

 

GeneRegistryGeneRegistry

Alright. Thanks for the heads up.