Skip to content

Round Robin Assignment for any user lookup field using Apex

Last updated on September 15, 2022

This article walks you through the assigning of a custom lookup to user field on the opportunity object via round-robin assignment with the ability to add/remove the assignee and implement the same logic for other user lookup fields. It is a pain to assign users manually in a round-robin manner. So I created the following solution in a more automated way using a custom object and an apex trigger. You can apply the same logic to any lookup to the user field for any standard or custom object.

Let’s say, you have a lookup to user fields “Customer Success Rep” on the opportunity object. And you want to assign a user to this field dynamically with a round-robin algorithm and the admin should be able to add/remove users from the round-robin assignment.


Solution

Step 1

Create a custom object to store the round-robin assignees’ information.

Custom Object: Round-Robin Assignee

Fields

  1. Name (Standard field, make it auto Number with display format as RRA-{00000})
  2. Assignee (Lookup to the User object and make it required on the page layout)
  3. Last Assignment Date/Time (Date/time field)
  4. Sort Number (Number field with 0 decimal places)
  5. Total Assignments

Then create a round-robing assignment record for each user that you want to assign to the custom field.

Step 2

Create an opportunity apex trigger that assigns a Customer Success Rep when a new opportunity is created by looking at the custom Round-Robin Assignee records.

Apex Trigger: OpportunityTrigger

Trigger OpportunityTrigger on Opportunity (before insert){
    
    if(trigger.isInsert && trigger.isBefore){        
        OpportunityTriggerHandler.AssignCSRandUnderwriter(trigger.new);
    }
    
}

Apex Class: OpportunityTriggerHandler

public class OpportunityTriggerHandler{

	public static void AssignCSRandUnderwriter(list<Opportunity> Opps){
        list<Round_Robin_Assignee__c> RRAssigneesToUpdate = new list<Round_Robin_Assignee__c>();
        
        list<Round_Robin_Assignee__c> CSRAssignees = new list<Round_Robin_Assignee__c>();
        CSRAssignees = [SELECT Assignee__c, Last_Assignment_Date_Time__c, Total_Assignments__c FROM Round_Robin_Assignee__c WHERE Assignee__r.isActive = TRUE Order by Last_Assignment_Date_Time__c ASC, Sort_Number__c ASC];
        
        integer CSRindex = 0;
        
        
        for(Opportunity opp : Opps){
            
            if(CSRAssignees.size() > 0){
                
                Round_Robin_Assignee__c RRAssignee = CSRAssignees.get(Math.mod(CSRindex, CSRAssignees.size()));
                opp.Customer_Success_Rep__c = RRAssignee.Assignee__c;
                
                RRAssignee.Last_Assignment_Date_Time__c = system.now();
                RRAssignee.Total_Assignments__c = RRAssignee.Total_Assignments__c == null ? 1 : RRAssignee.Total_Assignments__c+1;
                CSRindex++;
                RRAssigneesToUpdate.add(RRAssignee);
            }
        }
        if(RRAssigneesToUpdate.size() > 0){
            update RRAssigneesToUpdate;
        }
    }	
}

Boom! You are done.