3

Purpose: I have a small requirement where i need to modify a global picklist values (i.e. add new values / deactivate existing values) from outside salesforce and to use those values in our daily business of creating/updating Account records of multiple record types.

There is already a well written article that show a working solution using tooling API for modifying global picklist values using tooling API.

Create/Update Global Value Set using Tooling API

But, there is a followup problem to this. I have a custom picklist field in Account object (i.e. with multiple Record types) that is referring to the above Global picklist. The new value added to the above global picklist is not available for use in account records untill the value is also addded to the account recordtypes. I am not able to find any solution of how to add the new global picklist values to the account records types.

Approach 1: I have used a similar tooling API to retrieve the specific record type using the following code

HttpRequest request = new HttpRequest();
Id account_recordtype_Id = 'xxxxxxxxxxxxxxxx';
request.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v41.0/tooling/sobjects/RecordType/' + account_recordtype_Id);
request.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
request.setMethod('GET');

HttpResponse response = (new Http()).send(request);
String resposeJSON = response.getBody();
System.debug('resposeJSON: ' + resposeJSON);

Problem in above approach: If i was able to get all picklists as part of above response, i would modify it accordingly and send a PATCH request to update the RecordType with new picklistvalues. But the above code is not getting me any custom picklist values as part of Metadata in JSON.

Approach 2: I have used Metadata API to retrieve the specific record type & update it with latest picklist value using the following code.

Reference link: Add new picklist values to all Record Types that use this Global Value Set

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

MetadataService.RecordType recordType = (MetadataService.RecordType) service.readMetadata(
    'RecordType', new String[] { 'Account.Account_RecordType' }
).getRecords()[0];

MetadataService.RecordTypePicklistValue cusPik;
for(MetadataService.RecordTypePicklistValue rpk : recordType.picklistValues) {
    if(rpk.picklist == 'CustomPicklist__c') {
        cusPik = rpk;
        break;
    }
}

MetadataService.PicklistValue newVal = new MetadataService.PicklistValue();
newVal.fullName = 'test option';
newVal.default_x=false;
cusPik.values.add(newVal);
service.updateMetadata(new MetadataService.Metadata[] { recordType });

Problem in above approach: The above code is updating the recordtype by adding the new picklist value "test option", but everytime i execute the above code, it is throwing System.CalloutException: IO Exception: Read timed out exception. I am not sure why this is happening.

Any help in resolving this issue either using tooling/metadata api is appreciated.

4
  • 1
    Does this answer your question? Add new picklist values to all Record Types that use this Global Value Set
    – identigral
    Commented Sep 12, 2022 at 15:38
  • @identigral, i updated the description with latest information that includes my attempt at Metadata too. Please verify and let me know the working solution if any Commented Sep 13, 2022 at 8:25
  • @Chakravarty System.CalloutException: IO Exception: Read timed out exception is a generic error. You can try increasing the timeout but if that doesn't work, you should generate the debug logs and add the relevant excerpt from there that shows where the timeout is happening.
    – identigral
    Commented Sep 13, 2022 at 23:26
  • 1
    @identigral, I tried your suggestion and it worked. Thanks a lot. The MEtadata api code works in fixing the above problem with just increasing the timeout using the following code. MetadataService.MetadataPort service = new MetadataService.MetadataPort(); service.timeout_x=120000; Commented Sep 21, 2022 at 9:42

1 Answer 1

0

I am not able to update all the records types in one transaction, but able to update individual record type in a single transaction. So, in order to update all the available record types, i have used the following code in a batch.

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.timeout_x=120000;
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

MetadataService.RecordType recordType = (MetadataService.RecordType) service.readMetadata(
    'RecordType', new String[] { 'Account.Account_RecordType' }
).getRecords()[0];

MetadataService.RecordTypePicklistValue cusPik;
for(MetadataService.RecordTypePicklistValue rpk : recordType.picklistValues) {
    if(rpk.picklist == 'CustomPicklist__c') {
        cusPik = rpk;
        break;
    }
}

MetadataService.PicklistValue newVal = new MetadataService.PicklistValue();
newVal.fullName = 'test option';
newVal.default_x=false;
cusPik.values.add(newVal);
service.updateMetadata(new MetadataService.Metadata[] { recordType }); 

Thanks for the answer @identigral

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .