[SalesForce] Finding if which users have a record type available to them using SOQL

I would like to be able to execute a SOQL query that will allow me to see which users have access to a certain record type for a certain object.

For example, if I have a case record type called Phone Team, I would like to make a query that returns the names of all the users that have been assigned the Phone Team record type, as can be seen in the native user interface in a profile's Object Settings page.

So far I have managed to get a query that can get the names of all the users that have, for example, read access to the case object:

SELECT Assignee.Name FROM PermissionSetAssignment 
    WHERE PermissionSetId IN 
        (SELECT ParentId FROM ObjectPermissions WHERE SObjectType = 'Case' 
             AND PermissionsRead = true AND Parent.IsOwnedByProfile = true)

However, there doesn't seem to be any way to access record type assignment in the same way that you can object permissions.

I see from this post that the info can be obtained via the metadata API, but I would much prefer to do it by SOQL if possible.

Thanks

Best Answer

This is possible through Apex, but not SOQL --- and no Metadata API required.

To determine whether a given SObject's RecordType is available to a given user's profile, you will need to use the Apex DescribeSObjectResult getRecordTypeInfos() call on that SObject (see the docs here). This returns a list of RecordTypeInfo objects corresponding to all RecordTypes on that SObject, each of which has an isAvailable() method which will tell you if the RecordType is available to the running user's Profile.

For example, say that you have 2 Case Record Types, 'Phone Team' and 'Web Team', with both available to your Profile. Let's make 'Phone Team' unavailable to test. Go into your Profile, and scroll down to the Record Types area, and click on Case, and then remove 'Phone Team' from the list of available Record Types.

Now, add the following method to a utility class:

// Returns a List of the Names of all RecordTypes
// available to the running user for a given SOBject type
public static List<String> GetAvailableRecordTypeNamesForSObject(
    Schema.SObjectType objType
) {
    List<String> names = new List<String>();
    List<RecordTypeInfo> infos = objType.getDescribe().getRecordTypeInfos();
    // If there are 2 or more RecordTypes...
    if (infos.size() > 1) {
        for (RecordTypeInfo i : infos) {
           if (i.isAvailable() 
           // Ignore the Master Record Type, whose Id always ends with 'AAA'.
           // We check the Id because Name can change depending on the user's language.
            && !String.valueOf(i.getRecordTypeId()).endsWith('AAA'))
                names.add(i.getName());
        }
    } 
    // Otherwise there's just the Master record type,
    // so add it in, since it MUST always be available
    else names.add(infos[0].getName());
    return names;
}

And run the following from Anonymous Apex to get the available Case record types:

 List<String> availableCaseTypes = 
      GetAvailableRecordTypeNamesForSObject(Case.SObjectType);

 System.debug(availableCaseTypes);
 // returns ('Web Team')

Just FYI, the reason this is not possible from SOQL is that the only RecordType-related SObject exposed in SOQL is the RecordType object, whose IsActive field will tell you whether or not a RecordType is globally active/inactive, but provides no information whatsoever on whether a given RecordType is available to a user or profile.

Related Topic