We learned last week that Metadata API can be pretty cool, huh? Sometimes it’s even the only way to retrieve what you expect to be covered by standard Apex functions, but unfortunately isn’t.
Let’s say you’d need the mapping from Opportunity Stage to the associated Probability per Record Type / Sales Process (in my case the requirement was to decouple Opportunity Probability from Stage, so you can manually enter a Probability – as long as the Probability occurs in your Sales Process, there is no need for it to match the Stage, but never mind). You find these closely related pieces of information in various places in the UI, so wouldn’t it make sense to provide something that basic as some kind of DescribeResult?
Well, Salesforce didn’t consider this necessary, but fortunately introduced Custom Metadata Types, which we can utilize by creating a new Custom Metadata Type, emulating the missing metadata and making the requested information available to be retrieved on the fly, in a resource-saving manner, in Apex code.
- SalesProcessMapping__mdt
with the fields
- RecordTypeId__c (Text, 18)
- StageName__c (Text, 255)
- optional: Probability__c (Integer, 3/0)
Now I could just tell you to populate the metadata manually and keep it up to date once stages or probabilities or record types change, we could finish here and you’d rightfully call me an awful blogger. Or we do it the proper, fully automated way, with Metadata API saving the day once more.
We’re relying once more on the service of MetadataService, which has been woven into the architectural design of my choice – a schedulable job which replenishes the Custom Metadata records by deleting, then rebuilding all records on execution. MetadataService helps in numerous ways:
- Deleting existing SalesProcessMapping__mdt custom metadata in the execute() method
- Retrieving the name of the associated Business Process of every Opportunity Record Type
- Retrieving all available picklist values of every Business Process
- Re-deploying the new SalesProcessMapping__mdt custom metadata records
Some pitfalls and caveats as follows:
- The OpportunityStage object reveals the stage-to-probability mapping and should be used if recording Probability values
- Picklist Values from the Metadata API are URL encoded, and need to be decoded before matching against values from Schema methods or OpportunityStage object query results, which are not encoded.
Enough said, let’s proceed to the golden lines: