Still fumbling my way through this problem:
Help understand Apex class / bulkilfy
I decided to go ahead and create a query in Apex that gets the Leads I need to be reassigned and push those into the RoundRobin apex class. I've got the query working, tested in developer console and is working. My next I wanted to try is to get the list of leads into the RoundRobin class, I figured I can start to mess with the scheduler to try to accomplish that. Ive scheduled it to run every 15 minutes for testing and its just sitting their as "Scheduled". I suspect maybe the code Ive borrowed from the internet isnt actually working or executing anything? Ive included the code below. Thank you!
global class scheduledCron implements Schedulable{
global void execute(SchedulableContext SC) {
new RRA();
}
}
and here is the apex with the queries for users and leads
public with sharing class RRA {
list<roundRobinAssigner.RoundRobinAssignment> rras = new list<roundRobinAssigner.RoundRobinAssignment>();
List<User> users = [SELECT Id FROM User WHERE Lead_Reassignment__c = true AND IsActive = true AND ProfileId = '00e4P000000KDMk'];
List<Lead> leads = [SELECT Id
FROM Lead
WHERE OwnerID IN : users
AND Next_Business_Date__c = 2020-08-31
AND (Status__c = 'New' OR
Status__c = 'Attempting Contact 1' OR
Status__c = 'Attempting Contact 2' OR
Status__c = 'Attempting Contact 3' OR
Status__c = 'Attempting Contact 4' OR
Status__c = 'Attempting Contact 5')
];
public void createrrassigns(){
for (lead a:leads){
roundRobinAssigner.RoundRobinAssignment rra = new roundRobinAssigner.RoundRobinAssignment();
rra.groupName = 'Online_Round_Robin';
rra.recordId = a.id;
rras.add(rra);
}
roundRobinAssigner.assign(rras);
}
}
and the RoundRobin assigner class just incase:
public without sharing class roundRobinAssigner {
public static final integer customSettingNameLimitLength = 40;
@InvocableMethod(label='Assign objects')
public static void assign(list<RoundRobinAssignment> rras) {
// what was the last user index?
list<RoundRobin__c> RRSettings = [select id, GroupName__c, FieldName__c, Object__c, IndexOfLastUsed__c from RoundRobin__c];
Set<Id> recordIds = new Set<Id>();
map<string, list<GroupMember>> usersByGroup = new map<string, list<GroupMember>>();
List<SObject> objectList = new List<SObject>();
// get the records
for (RoundRobinAssignment rra:rras){
// default field
if (rra.fieldName == null){
rra.fieldName = 'OwnerId';
}
list<groupMember> groupUsers = new list<groupMember>();
// see if we have it already in our map
if (usersByGroup.get(rra.groupName) == null){
groupUsers = [select Group.Name, GroupId, UserOrGroupId from GroupMember where Group.Name =: rra.groupName];
//store in the map so we don't have to query about this group again
usersByGroup.put(rra.groupName, groupUsers);
} else {
groupUsers = usersByGroup.get(rra.groupName);
}
// what kind of object is this, anyway?
Id rId = id.valueOf(rra.recordId);
string Obj = rid.getSObjectType().getDescribe().getName();
RoundRobin__c matchingRR = recordMatcher(RRSettings, rra.fieldName, Obj, rra.groupName);
sObject so = rid.getSObjectType().newSObject(rid);
integer nextIndex = getNextIndex(matchingRR, groupUsers);
so.put(rra.fieldName, groupUsers[nextIndex].UserOrGroupId);
matchingRR.IndexOfLastUsed__c = nextIndex;
// if the original list didn't contain the matching one, we need to add it here
boolean isNew = true;
for (RoundRobin__c rr: RRSettings){
// we already had that on our list
if (rr.Id == matchingRR.Id){
rr.IndexOfLastUsed__c = matchingRR.IndexOfLastUsed__c;
isNew = false;
}
}
if (isNew){
//we hadn't seen it before
system.debug('inserting a RR custom setting');
RRSettings.add(matchingRR);
}
objectList.add(so);
}
update objectList;
// because we may have incremented them
update RRSettings;
}
public static integer getNextIndex(RoundRobin__c match, list<GroupMember> groupUsers){
if (match.IndexOfLastUsed__c == null){
// it's null, so grab the first one!
return 0;
} else if (match.IndexOfLastUsed__c >= groupUsers.size()-1){
// you've used them all
system.debug(match.IndexOfLastUsed__c + ' is the last match, which is >= the group size of ' + groupUsers.size() + 'so we are going back to 0' );
return 0;
} else {
// return the next one
return integer.valueOf(match.IndexOfLastUsed__c + 1);
}
}
public static RoundRobin__c recordMatcher(list<RoundRobin__c> records, string FieldName, string Obj, string GroupName){
for (RoundRobin__c rr:records){
if (rr.FieldName__c == FieldName && rr.Object__c == Obj && rr.GroupName__c == GroupName){
return rr;
}
}
// we never found it, so create one
RoundRobin__c rrNew = new RoundRobin__c();
rrNew.FieldName__c = FieldName;
rrNew.Object__c = Obj;
rrNew.GroupName__c = GroupName;
// because name is required
rrNew.Name = nameShortener(Obj, FieldName, GroupName);
// how "too long" is it?
insert rrNew;
return rrNew;
}
public static string nameShortener(string Obj, string FieldName, string GroupName) {
integer tooLongness = Obj.length() + FieldName.length() + GroupName.length() + 2 - customSettingNameLimitLength; // for separators
if (tooLongness <=0) {
return Obj + '-' + FieldName + '-' + GroupName;
}
integer wholesToChop = Math.round(Math.floor(tooLongness / 3));
integer remainderToChop = Math.mod(tooLongness, 3);
Obj = Obj.left(Obj.length() - wholesToChop);
FieldName = FieldName.left(FieldName.length() - wholesToChop);
GroupName = GroupName.left(GroupName.length() - wholesToChop);
if (remainderToChop > 0) {
GroupName = GroupName.left(GroupName.length() - 1);
}
if (remainderToChop > 1) {
FieldName = FieldName.left(FieldName.length() - 1);
}
return Obj + '-' + FieldName + '-' + GroupName;
}
//what Process Builder/Flow Builder can reference for the input variables
public class RoundRobinAssignment {
@InvocableVariable(required=true label='group name')
public string groupName;
@InvocableVariable(required=true label='recordId')
public string recordId;
@InvocableVariable(required=false label='field name (default = ownerId)')
public string fieldName;
}
}
I pretty much have no freakin idea what Im doing and Im going a bit crazy, thanks for any insights here!!