+ Start a Discussion
RelaxItsJustCodeRelaxItsJustCode 

Need help making a Service Class more effective, please help

public with sharing class ServiceClass 
{
     public static Map<String, RecordType> CaseRecordTypesNameMap
    {
        get
        {
            if(CaseRecordTypesNameMap == null){
                CaseRecordTypesNameMap = new Map<String,RecordType>();
                for(RecordType rt: [Select Id, Name from RecordType where sObjectType = 'Case' ])
                CaseRecordTypesNameMap.put(rt.Name, rt);
            }
            return CaseRecordTypesNameMap;

        }
        
        private set;
    }

     public static Map<String, RecordType> TaskRecordTypesNameMap
    {
        get
        {
            if(TaskRecordTypesNameMap == null){
                TaskRecordTypesNameMap = new Map<String,RecordType>();
                for(RecordType rt: [Select Id, Name from RecordType where sObjectType = 'Task' ])
                TaskRecordTypesNameMap.put(rt.Name, rt);
            }
            return TaskRecordTypesNameMap;

        }
        
        private set;
    }
}

 What I would like to do is take these two functions and make them so they would work with any sObjectType in the system, by passing the sObjectType = variable passed from class call the ServiceClass above.

 

Secondly, a little suggestion on how to call the class with the two parameters?

 

Thank you,

Steve Laycock

Best Answer chosen by Admin (Salesforce Developers) 
manuel-jose-condemanuel-jose-conde

try this :

 

replace:

 

ServiceClass.RecordTypesNameMap.get('PM Case').Id

 

by

 

ServiceClass.getRecordTypesNameMap('Case').get('PM Case').Id

 

 

Let me know

All Answers

manuel-jose-condemanuel-jose-conde

hi,

 

see below (changes in italic, I've just changed  CaseRecordTypesNameMap which is now a new method named getCaseRecordTypesNameMap)

 

public with sharing class ServiceClass
{
     private static Map<String, RecordType> CaseRecordTypesNameMap = new Map<String,RecordType>();
     
     public static Map<String, RecordType> getCaseRecordTypesNameMap(String sObjectName)
     {
            
        if(!CaseRecordTypesNameMap.containsKey(sObjectName) && sObjectName <> null){
            List<RecordType> recTList = [Select Id, Name from RecordType where sObjectType = :sObjectName] ;
            
            for(RecordType rt: recTList)
                CaseRecordTypesNameMap.put(rt.Name, rt);
        }
        return CaseRecordTypesNameMap;

    }

     public static Map<String, RecordType> TaskRecordTypesNameMap
    {
        get
        {
            if(TaskRecordTypesNameMap == null){
                TaskRecordTypesNameMap = new Map<String,RecordType>();
                for(RecordType rt: [Select Id, Name from RecordType where sObjectType = 'Task' ])
                TaskRecordTypesNameMap.put(rt.Name, rt);
            }
            return TaskRecordTypesNameMap;

        }
        
        private set;
    }
}

 

To call this class from any other apex class just do as follows:

 

Map<String, RecordType> CaseRecordTypesNameMap = ServiceClass.getCaseRecordTypesNameMap('Account');

 

//Prints current size of the map.
System.debug(CaseRecordTypesNameMap.size());

 

Regards

Manuel

RelaxItsJustCodeRelaxItsJustCode
public with sharing class ServiceClass 
{
     public static Map<String, RecordType> CaseRecordTypesNameMap
    {
        get
        {
            if(CaseRecordTypesNameMap == null){
                CaseRecordTypesNameMap = new Map<String,RecordType>();
                for(RecordType rt: [Select Id, Name from RecordType where sObjectType = 'Case' ])
                CaseRecordTypesNameMap.put(rt.Name, rt);
            }
            return CaseRecordTypesNameMap;

        }
        
        private set;
    }

     public static Map<String, RecordType> TaskRecordTypesNameMap
    {
        get
        {
            if(TaskRecordTypesNameMap == null){
                TaskRecordTypesNameMap = new Map<String,RecordType>();
                for(RecordType rt: [Select Id, Name from RecordType where sObjectType = 'Task' ])
                TaskRecordTypesNameMap.put(rt.Name, rt);
            }
            return TaskRecordTypesNameMap;

        }
        
        private set;
    }
   
  }

Your solution returns a list of recordtypes allocated to an object.  What I need is to be able to pass in sObjectName and the RecordType Name to retrieve a single recordtypeid.

 

ServiceClass.TaskRecordTypesNameMap.get('PM Task').Id

 Above is what I'm currently using but instead of having to build a look up function for every object I'd rather get it all done in one single call passing two params sObjectName and RecordType Name.  Any ideas?

manuel-jose-condemanuel-jose-conde

hi,

 

I think you can do it with changes I sent you....

 

Map<String, RecordType> CaseRecordTypesNameMap = ServiceClass.getCaseRecordTypesNameMap('Account');

CaseRecordTypesNameMap.get('your recordtype name').id;

 

 

 

RelaxItsJustCodeRelaxItsJustCode

I modified the code to be more dynamic not object specific that is the goal. First, it's not recognizing the sObjectName var

     private static Map<String, RecordType> RecordTypesNameMap = new Map<String,RecordType>();
     
     public static Map<String, RecordType> getRecordTypesNameMap(String sObjectName)
     {
            
        if(!RecordTypesNameMap.containsKey(sObjectName) && sObjectName <> null)
    { 
            List<RecordType> recTList = [Select Id, Name from RecordType where sObjectType = :sObjectName] ;
            
            for(RecordType rt: recTList)
                CaseRecordTypesNameMap.put(rt.Name, rt);
        }
        return CaseRecordTypesNameMap;

     }

 

Error: Compile Error: Variable does not exist: sObjectName at line 40 column 44

 

 

manuel-jose-condemanuel-jose-conde

the problem is not that variable but 

CaseRecordTypesNameMap
RelaxItsJustCodeRelaxItsJustCode

Sorry tried that fix, and with the following I still receive the same variable issue,

 

     private static Map<String, RecordType> RecordTypesNameMap = new Map<String,RecordType>();
     
     public static Map<String, RecordType> getRecordTypesNameMap(String sObjectName)
     {
            
        if(!RecordTypesNameMap.containsKey(sObjectName) && sObjectName <> null)
	{ 
            List<RecordType> recTList = [Select Id, Name from RecordType where sObjectType = :sObjectName] ;
            
            for(RecordType rt: recTList)
                RecordTypesNameMap.put(rt.Name, rt);
        }
        return RecordTypesNameMap;

     }

 

manuel-jose-condemanuel-jose-conde

Can you share your class?

 

Because I have the initial class (the one I sent you) running in my dev sandbox without any issues.

 

 

Manuel

RelaxItsJustCodeRelaxItsJustCode
public with sharing class ServiceClass 
{
     private static Map<String, RecordType> RecordTypesNameMap = new Map<String,RecordType>();
     
     public static Map<String, RecordType> getRecordTypesNameMap(String sObjectName)
     {
            
        if(!RecordTypesNameMap.containsKey(sObjectName) && sObjectName <> null)
	{ 
            List<RecordType> recTList = [Select Id, Name from RecordType where sObjectType = :sObjectName] ;
            
            for(RecordType rt: recTList)
                RecordTypesNameMap.put(rt.Name, rt);
        }
        return RecordTypesNameMap;

     }
}

 Thanks Manuel I really appriciate it.

 

Thank you,

Steve Laycock

manuel-jose-condemanuel-jose-conde

Steve,

 

can you show me the code that is calling "our" class?

 

There is nothing wrong with that class (i tested it now). I think you have a variable named sObjectName that is not defined yet but in the code that is calling our class. 

 

Line 40?

RelaxItsJustCodeRelaxItsJustCode
Map<String, RecordType> RecordTypesNameMap = ServiceClass.getRecordTypesNameMap('Case');

 This is how I was calling it in the following class but I have change it since.  Please show me how you are calling it.  Below is the current class calling the serviceclass.

public class CaseFunctions
{
   public static void CaseValidationBeforeComplete(Map<Id,Case> oldMap, Map<Id,Case> newMap)
   {
        List<Id> caseIds = new List<Id>();
  
        for (Case c : newMap.Values()){      
            
            if(c.RecordTypeId == ServiceClass.RecordTypesNameMap.get('PM Case').Id && (c.Status == 'Completed' || c.Status == 'Closed'))
            {
                 caseIds.add(c.Id);
            }
        }
        for(Training_Information__c customobj : [Select Id, Status__c,Case__c From Training_Information__c Where Case__c in: caseIds])
        {
            if(customobj.Status__c == 'Pending' || customobj.Status__c == 'Scheduled')
            {    
                 newMap.get(customobj.Case__c).addError('Training has not been completed.');
            }     
        }    
        
        for(Development_Request__c customobj : [Select Id, Stage__c,Case__c From Development_Request__c Where Case__c in: caseIds])
        {
            if(customobj.Stage__c != 'Completed' && customobj.Stage__c != 'Cancelled DR/ VOID' && customobj.Stage__c != 'Draft')
            {
                newMap.get(customobj.Case__c).addError('There are open Development Request associated with this Case.');
            }
        }  

        for(Task T : [Select Id, Status, WhatId, RecordTypeId From Task Where WhatId in: caseIds])
        {
            if(T.RecordTypeId == ServiceClass.RecordTypesNameMap.get('PM Task').Id && (T.Status != 'Completed' && T.Status != 'Discarded'))
            {
                newMap.get(T.WhatId).addError('There are still open PM Task on this Case.');
            }
        }
    }    
}

 Thanks Manuel,

 

Steve

manuel-jose-condemanuel-jose-conde

try this :

 

replace:

 

ServiceClass.RecordTypesNameMap.get('PM Case').Id

 

by

 

ServiceClass.getRecordTypesNameMap('Case').get('PM Case').Id

 

 

Let me know

This was selected as the best answer
RelaxItsJustCodeRelaxItsJustCode

Your AWESOME Manuel!

 

Thank you very much!

 

It worked!

 

Steve Laycock

manuel-jose-condemanuel-jose-conde

Steve,

 

I think that we, developers, should always take a defensive approach when developing sw, that is specially true when developing in multi-tenant platforms so that we avoid (bad) surprises, if you see what I mean.

 

I would change the line that calls "our" class to check also if there is available that given recordtype to prevent system to throw a null pointer exception in case there is no "PM Case'....it can happen....imagine if someone renames the record type...

 

So this:

c.RecordTypeId == ServiceClass.getRecordTypesNameMap('Case').get('PM Case').Id

 

would be replaced by:

 

(ServiceClass.getRecordTypesNameMap('Case').get('PM Case') <> null && c.RecordTypeId == ServiceClass.RecordTypesNameMap.get('PM Case').Id)

 

 

Cheers

Manuel