1

I have a class which helps to perform a particular operation on a particular object. The code which was designed completely on contact object.

I can write new class and use the same code on another object and use that, but I don't want to duplicate the code.

How can I make the code more generic where I can use the code in different objects as well.

Below is my sample code.

public class ContactClass {

    public static void UserAssignment(List<Contact> contacts){

        AssignmentRulesParser parser = new AssignmentRulesParser();
        Map<Integer, String> orderToAssignmentTeamMap = new Map<Integer, String>();
        List<String> recruitersForContactsToUpdate = new List<String>();
        Boolean allowReassignUser = false;

        Map<Integer, List<String>> assignmentRules = parser.parse('Contact');

        List<Assignment_Rules__c> assignRules = [
                                    SELECT Order__c, Assignment_Team__c
                                    FROM Assignment_Rules__c
                                    WHERE sObject_API_Name__c = 'Contact'];
        system.debug('assignRules>>>'+assignRules);

        for (Assignment_Rules__c rule : assignRules) {
            orderToAssignmentTeamMap.put(Integer.valueOf(rule.Order__c), rule.Assignment_Team__c.trim());
        }

        Integer maxOrderValue = 0;
        for (Integer v_index : assignmentRules.keySet()) {
            if (maxOrderValue <= v_index) { maxOrderValue = v_index; } 
        }

        for (Contact contact : contacts) {
            for (Integer i = 0; i <= maxOrderValue; i++) {
                if (assignmentRules.containsKey(i)) {
                    for (String rule : assignmentRules.get(i)) {
                        allowReassignUser = false;
                        List<String> splittedRule = rule.trim().split(' ', 3);
                        system.debug(splittedRule[0] + 'splittedRule[0] ::');
                        system.debug(splittedRule[1] + 'splittedRule[1] ::');
                        system.debug(splittedRule[2] + 'splittedRule[2] ::');
                        if (splittedRule[1] == '==') {
                            if (Contact.get(splittedRule[0]) == splittedRule[2]) {
                                allowReassignUser = true;
                                continue;
                            } else {
                                break;
                            }
                        } else if (splittedRule[1] == '!=') {
                            if (Contact.get(splittedRule[0]) != splittedRule[2]) {
                                allowReassignUser = true;
                                continue;
                            } else {
                                break; 
                            }
                        }

                    }

                    system.debug('allowReassignUser>>>'+allowReassignUser);

                    datetime timeNow = DateTime.now();

                    if (allowReassignUser) {

                        system.debug('orderToAssignmentTeamMap.get(i) ::' + orderToAssignmentTeamMap.get(i));
                        List<Config__c> recruiters = [
                                                SELECT Active_User__c, Assignment_Order__c, Group_Name__c, User__r.Id,
                                                Last_Assigned__c, No_Availability_End_Date_Time__c, Group_Name__r.Name__c,
                                                User__c,End_Time_Formula__c, Start_Time_Formula__c, 
                                                Working_Hours_End_Time__c, No_Availability_Start_Date_Time__c
                                                FROM Config__c
                                                WHERE Group_Name__r.Name__c =:orderToAssignmentTeamMap.get(i)
                                                AND Active_User__c = true
                                                ORDER BY Assignment_Order__c ASC];


                        system.debug('recruiters.size() ::' + recruiters.size());

                        Integer nextIndexToConsider = null;     
                        if(recruiters.size() == 1) {
                            if(contact.RecordTypeId == rtConType[0].Id) {
                                contact.Account_Manager__c = recruiters[0].User__r.Id;
                            } else {
                                contact.Recruiter__c = recruiters[0].User__r.Id;
                            }
                        } else if(recruiters.size() > 1) {          

                            for (Integer j = 0; j < recruiters.size(); j++) {
                                system.debug('j loop value :' + j); 
                                system.debug('recruiters[j].Last_Assigned__c ::' + recruiters[j].Last_Assigned__c);


                                if (recruiters[j].Last_Assigned__c || nextIndexToConsider != null) {
                                    system.debug('assign check  ::');
                                    datetime timeworkingHrs = DateTime.now();

                                    DateTime notAvailableStartTime = null;
                                    if(j != recruiters.size()-1) {
                                        if(recruiters[j+1].No_Availability_Start_Date_Time__c != null) {
                                            notAvailableStartTime = recruiters[j+1].No_Availability_Start_Date_Time__c;
                                        } else {
                                            notAvailableStartTime = null;
                                        }                                   
                                    } else if(recruiters[0].No_Availability_Start_Date_Time__c != null) {
                                        notAvailableStartTime = recruiters[0].No_Availability_Start_Date_Time__c;
                                    }

                                    Datetime notAvailableEndTime = null;
                                    if(j != recruiters.size()-1) {
                                        if(recruiters[j+1].No_Availability_End_Date_Time__c != null) {
                                            notAvailableEndTime = recruiters[j+1].No_Availability_End_Date_Time__c;
                                        } else {
                                            notAvailableEndTime = null;
                                        }
                                    } else if(recruiters[0].No_Availability_End_Date_Time__c != null) {
                                        notAvailableEndTime = recruiters[0].No_Availability_End_Date_Time__c;
                                    }


                                    DateTime startTime = null;
                                    if(j != recruiters.size()-1) {
                                        if(recruiters[j+1].Start_Time_Formula__c != null) {
                                            startTime = DateTime.parse(recruiters[j+1].Start_Time_Formula__c);
                                        } else {
                                            startTime = null;
                                        }                                   
                                    } else if(recruiters[0].Start_Time_Formula__c != null) {
                                        startTime = DateTime.parse(recruiters[0].Start_Time_Formula__c);
                                    }

                                    Datetime endTime = null;
                                    if(j != recruiters.size()-1) {
                                        if(recruiters[j+1].End_Time_Formula__c != null) {
                                            endTime = DateTime.parse(recruiters[j+1].End_Time_Formula__c);
                                        } else {
                                            endTime = null;
                                        }
                                    } else if(recruiters[0].End_Time_Formula__c != null) {
                                        endTime = DateTime.parse(recruiters[0].End_Time_Formula__c);
                                    }

                                    system.debug('startTime ::' + startTime);
                                    system.debug('endTime ::' + endTime);
                                    system.debug('timeworkingHrs ::' + timeworkingHrs);

                                    if(!((notAvailableStartTime != null && notAvailableStartTime < timeworkingHrs) && (notAvailableEndTime != null && notAvailableEndTime > timeworkingHrs))) {

                                        if((startTime == null || startTime < timeworkingHrs) && (endTime == null || endTime > timeworkingHrs)) {
                                            system.debug('check here ::'); 
                                            if(contact.RecordTypeId == rtConType[0].Id){
                                                system.debug('inside AM ::');
                                                contact.Account_Manager__c = (j == (recruiters.size() - 1))
                                                    ? recruiters[0].User__r.Id : recruiters[j + 1].User__r.Id;
                                            } else {
                                                system.debug('inside 1 ::');

                                                contact.Recruiter__c = (j == (recruiters.size() - 1))   
                                                    ? recruiters[0].User__r.Id : recruiters[j+1].User__r.Id;
                                                system.debug('contact.Recruiter__c ::' + contact.Recruiter__c);
                                            }

                                            break;
                                        } else {
                                            nextIndexToConsider = Math.mod((j+1), recruiters.size());
                                            j = nextIndexToConsider - 1;
                                            system.debug('nextIndexToConsider ::' + nextIndexToConsider);
                                        }
                                    } else {
                                        nextIndexToConsider = Math.mod((j+1), recruiters.size());
                                        j = nextIndexToConsider - 1;
                                        system.debug('nextIndexToConsider ::' + nextIndexToConsider);
                                    }
                                }
                            }
                        }

                        system.debug('recruiters>>>'+recruiters);

                        for (Config__c recruiter : recruiters) {
                            if(contact.Recruiter__c != null){
                                system.debug('last assign 1 ::');
                                recruiter.Last_Assigned__c = recruiter.User__r.Id == contact.Recruiter__c;

                        }

                        system.debug('recruiters after update>>>'+recruiters);

                        update recruiters;
                        break;
                    }
                }
            }
        }

    }   
}

If you check my code, I am performing round robin and using it to update values in a single object. But as the class is associated with contact object, I can't use it for any other object. I can use sObject concept to handle it but I think I can't assigned field mappings through it. Any ideas will be helpful to proceed on this.

2
  • 2
    Step one is simplify what you have. This code is way to complex to genericize.
    – Adrian Larson
    Nov 16, 2016 at 13:48
  • hmm ok. but I will see if I can reduce any no of lines to make code more easy. It has so many iterations which I need to check and even I am using custom settings to fetch some reuiqred criteria and use it for my implemetation. I am looking for how I can convert the public static void UserAssignment(List<Contact> contacts){} method for dynamic object handling
    – KSL
    Nov 16, 2016 at 15:38

2 Answers 2

0

The broad answer is to make use of dynamic SOQL based on information you obtain using describe calls and to only use the methods of the base SObject class (put and get field values) when accessing or updating data. If your logic requires additional configuration you can make use of e.g. custom settings to hold that configuration.

While this might sound complicated the code doesn't have to be. For example, this code is one way to clone child objects of any type:

private static void cloneChildren(
        SObjectType type,
        SObjectField parentField,
        Id oldParentId,
        Id newParentId,
        SObject[] oldChildren,
        SObject[] newChildren
        ) {
    List<String> fields = new List<String>(type.getDescribe().fields.getMap().keySet());
    for (SObject sob : Database.query(''
            + ' select ' + String.join(fields, ',')
            + ' from ' + String.valueOf(type)
            + ' where ' + String.valueOf(parentField) + ' = :oldParentId'
            )) {
        SObject clone = sob.clone();
        clone.put(parentField, newParentId);
        oldChildren.add(sob);
        newChildren.add(clone);     
    }
}
0
0

created a new class and a new method where I can dynamically query though Sobject and its related fields. Below is some sample code which I have used. Also, executing all this flow through a process builder

Apex code:

public static List getRecords(String objName,List recIds) {

    Map<String,Schema.SObjectType> gd = Schema.getGlobalDescribe();
    Schema.SObjectType sobjType = gd.get(objName);


    //Schema.sObjectType sObjectTypeVar = objName.sObjectType;
    DescribeSObjectResult describeResult = sobjType.getDescribe();

    List<String> fieldNames = new List<String>( describeResult.fields.getMap().keySet() );

    String query =
      ' SELECT ' +
          String.join( fieldNames, ',' ) +
      ' FROM ' +
          describeResult.getName() + 
      ' WHERE Id = ' + '\'' + recIds.get(0) + '\'';

  System.debug('query : '+query );

    // return generic list of sobjects or typecast to expected type
    List<SObject> records = Database.query( query );        
    System.debug( records );
    return records;
}

public class RecordDetails {
    @InvocableVariable
    public List<String> ids;

    @InvocableVariable
    public String ObjectName;

    @InvocableVariable
    public List<String> recordTypes;

    @InvocableVariable
    public String fieldToBeUpdated;

} 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.