Fetch dependent picklist values depending on record type

The problem

The main problem with getting picklist based on recordtype, there is no "out of box" solution. You can easly fetch all values from picklist but without information about recordtypes. 



The solution

You need use "User Interface API", not very elegant solution, but it works. Give more time Salesforce for implement such obvious functionality (the idea arose only 8 years ago).

/ui-api/object-info/{objectApiName}/picklist-values/{recordTypeId}/{fieldApiName}

Step by step:

public static String innerSalesforceCallout(String serviceEndpoint) {
    if (String.isEmpty(serviceEndpoint)){
        return null;
    }
Http http = new Http(); HttpRequest webReq = new HttpRequest(); webReq.setMethod('GET'); webReq.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); webReq.setEndpoint(serviceEndpoint);
    try {
    HttpResponse res = http.send(webReq);
    } catch (System.CalloutException ex) {
        System.debug(ex);
    }
    if (res.getStatusCode() == 200) {
        return res.getBody();
    }
    return null;
}

As you can see for authorization we use current user sessionId. Remember to add to this user "API Enabled" permission. 

Example response:

{
"controllerValues" : {
        "Australia" : 0,
        "Brazil" : 1,
        "China" : 2,
        "Colombia" : 3,
        "France" : 4,
        "Italy" : 5,
        "Mexico" : 6,
        "New Zealand" : 7,
        "Nigeria" : 8,
        "Senegal" : 9,
        "South Korea" : 10,
        "US" : 11
      },
      "defaultValue" : null,
      "url" : "/services/data/v50.0/ui-api/object-info/account/picklist-values/012000000000000AAA/Cities__c",
      "values" : [ {
        "attributes" : null,
        "label" : "Cali",
        "validFor" : [ 3 ],
        "value" : "Cali"
      }, {
        "attributes" : null,
        "label" : "Chicago",
        "validFor" : [ 11 ],
        "value" : "Chicago"
      }, {
        "attributes" : null,
        "label" : "Dakar",
        "validFor" : [ 9 ],
        "value" : "Dakar"
      }, {
        "attributes" : null,
        "label" : "Lagos",
        "validFor" : [ 8 ],
        "value" : "Lagos"
      }, {
        "attributes" : null,
        "label" : "Los Angeles",
        "validFor" : [ 11 ],
        "value" : "Los Angeles"
      }, {
        "attributes" : null,
        "label" : "Oaxaca",
        "validFor" : [ 6 ],
        "value" : "Oaxaca"
      }, {
        "attributes" : null,
        "label" : "Wellington",
        "validFor" : [ 7 ],
        "value" : "Wellington"
      } ]
    },

Now we have information about dependences and values.

For example Cities__c is dependent of another picklist where is country. Now we want get all cities from New Zealand (7).

 public static List<ESD_selectOption> getDependencePicklistByRT(String parentPicklistName, String objectName, String childPicklistField, String rtDeveloperName) {
        List<ESD_selectOption> pickListValuesList = new List<ESD_selectOption>();

        if (String.isEmpty(parentPicklistName) || String.isEmpty(objectName) || String.isEmpty(childPicklistField) || String.isEmpty(rtDeveloperName)) {
return pickListValuesList; }
        Id recordTypeId = Schema.SObjectType.Case.getRecordTypeInfosByDeveloperName().get(rtDeveloperName).getRecordTypeId();
String response = ESD_HTTPCalls.innerSalesforceCallout(Url.getOrgDomainUrl().toExternalForm() + '/services/data/v50.0/ui-api/object-info/' + objectName + '/picklist-values/' + recordTypeId + '/' + childPicklistField); if (String.isNotEmpty(response)) { Map<String, Object> responseDeserialized = (Map<String, Object>) JSON.deserializeUntyped(response); Object controllerValues = (Object) responseDeserialized.get('controllerValues'); Map<String, Object> controllerValuesMap = (Map<String, Object>) controllerValues; String picklistId = (String.valueOf(controllerValuesMap.get(parentPicklistName))); for (Object o : (List<Object>) (responseDeserialized.get('values'))) { Map<String, Object> obj = ((Map<String, Object>) o); if (String.valueOf(obj.get('validFor')).contains(picklistId)) { pickListValuesList.add(new ESD_selectOption((String) obj.get('value'), (String) obj.get('label'))); } } } return pickListValuesList; }

And call method: getDependencePicklistByRT('New Zealand', 'Account', 'Cities__c', 'RTdevName')

We hope that you can use this solution in Your project :)

See you soon,
Michał on behalf of Salesforce Freaks ;) 

Comments

Popular posts from this blog

How to start work with Anypoint Studio?

Security Vulnerabilities in Salesforce