11

The objective is to have assignment rules fired on a Lead record creation. It seems the rule can be assigned only when using "update" DML in an "after insert" trigger. Why does another DML must be executed after insert to have lead assignment rule assigned?

//Does not work
trigger LeadTrigger on Lead (before insert) {    
    for (Lead l : Trigger.new) {        
        Database.DMLOptions dmo = new Database.DMLOptions();
        dmo.assignmentRuleHeader.useDefaultRule = true;
        so.setOptions(dmo);
    }
}


//Works: Records must be *updated* in after insert trigger in order to have the rule assigned
trigger LeadTrigger on Lead (after insert) {
    List<Lead> ls = new List<Lead>();

    for (Lead l : Trigger.new) {
        ls.add(new Lead(id = l.id));
    }

    Database.DMLOptions dmo = new Database.DMLOptions();
    dmo.assignmentRuleHeader.useDefaultRule = true;
    Database.update(ls, dmo);
}

Moreover, testing of the rule assignment fails even though the rule has been assigned to the Lead. We cannot test assignment rule outcome (ownerId=defaultQueueId for example) since the rule will change on PROD eventually.

//Test method failing for a lead *having* rule assigned:    
public static void assertDefaultAssignmentRules(SObject sobj) {
    Database.DMLOptions dmo = sobj.getOptions();

    System.assertNotEquals(null, dmo, 'DMLOption is null');
    System.assert(dmo.assignmentRuleHeader.useDefaultRule, dmo);
}
2
  • I am trying to understand your code. I also want to run the Lead Assignment rule via triggers. Could you please let me know that why you have used the line: ls.add(new Lead(id = l.id));? Thanks in advance for your help. Kind regards,
    – user7797
    Commented Apr 9, 2014 at 14:36
  • Leads, being inserted, are added to the list so they can be updated in order to get the assignment rule assigned (see Database.update(ls, dmo)). A lead record in the update list only needs "id" field and no other field should be updated. Commented Apr 14, 2014 at 22:45

2 Answers 2

7

Lead reassignment within a trigger can be done with future methods such as the following. Your after insert / after update trigger will need to collect up a set of lead ids that qualify for reassignment and then once all other afterinsert/afterupdate operations are complete, call the future method below:

Note use of DmlOptions:

@future
public static void futureLeadReassign(Set<ID> lIdReassignSet) { 
    
    List<Lead> lUpdList = [SELECT Id FROM Lead WHERE Id IN: lIdReassignSet];
    Database.DMLOptions dmo = new Database.DMLOptions();
    dmo.assignmentRuleHeader.useDefaultRule = true;         
    for (Lead l:lUpdList) {
        // use leadAssignment rules when updating
        l.setOptions(dmo);
    }
    
    try {update(lUpdList);}
    catch (DmlException e) {/* do something here like send email to sysad with error */}
}
2
  • Works! The assignment to dmo can be made outside the loop, by the way. Commented Oct 15, 2020 at 14:29
  • @SanderdeJong - optimized code per your suggestion
    – cropredy
    Commented Oct 15, 2020 at 16:31
2

DMLOptions are additional settings you can specify when you are performing DML in Apex. They don't apply to data input by any other means (unless, like you've discovered, you issue an explicit update)

DMLOptions settings take effect only for record operations performed using Apex DML and not through the Salesforce user interface.

If you are loading in this data via Data Loader, you can specify the assignment rule to use in the Data Loader Settings.

As for the assertion, have you tried enclosing the test within Test.startTest() and Test.stopTest(). (It might also be an idea to assert in the trigger context, as I'm not sure the DMLOptions would survive / be available after the completion of the DML Operation.)

2
  • Thanks for the response. I will be using update DML in order to assign default lead assignment rule to records (I think there should be consistency in how records are processed regardless of how they are created). Test method fails regardless of Test.start/stopTest. Commented Jul 4, 2013 at 21:23
  • 4
    DMLOptions apply to DML initiated from Apex Code (such as in Visualforce). Once you're in a trigger, the DML has already started, and so the DMLOptions have no effect (because they were already given by the initial DML function).
    – sfdcfox
    Commented Jul 6, 2013 at 2:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .