[SalesForce] Updating Custom Metadata Type’s Field value via Apex

I'm trying to update a Custom Metadata Type's Field value via Apex.

I'm building an Account Assignment Round Robin tool, the Tool calls on the Custom Meta Data Type to get the Value of the position of the last assigned AM, once the Accounts have been updated we'd like to Save the updated position of the Last assigned AM, but I'm not sure how to update the Custom Meta Data Type Value (since a DML statement won't work). Thoughts (Screenshots and code below)?


I've looked at a couple of examples but they all seem to be related to "Create" and not updating a value

Metadata Type

public class AccountOwnerAssignment {

public static void AssignOwners(List<Account> triggerOld,List<Account> triggerNew){

    List <User> nonNamedAMs = [SELECT ID, LastName FROM User WHERE AM_Team_Account_Tier__c = 'Non-Named'AND isActive = TRUE ORDER BY lastName DESC];
    List <RoundRobinAssignment__mdt> accountReassignmentNumberRecord = [SELECT AccountReassignmentNumber__c  FROM RoundRobinAssignment__mdt WHERE Label = 'Master'];
    Integer currentOwnerPosition = accountReassignmentNumberRecord[0].AccountReassignmentNumber__c.intValue();

    FOR(integer i=0;i<triggerNew.size();i++){
        //Confirms that the Number of Clients have increased from 0 to a greater number
        IF(triggerNew[i].No_of_Clients__c > 0 && triggerOld[i].No_of_Clients__c == 0){
            currentOwnerPosition = calculatePosition(currentOwnerPosition, nonNamedAMS.Size());
            System.debug('currentOwnerPosition ' + currentOwnerPosition);
            System.debug('nonNamedAMs.size() ' + nonNamedAMs.size());
            System.debug('nonNamedAMs[currentOwnerPosition].ID ' + nonNamedAMs[currentOwnerPosition].ID + 'nonNamedAMs[currentOwnerPosition].LastName ' + nonNamedAMs[currentOwnerPosition].LastName);

            //Update Account with new Account Owner
        triggerNew[i].OwnerId= nonNamedAMs[currentOwnerPosition].ID;
          System.debug('triggerNew[i].OwnerId ' + triggerNew[i].OwnerId);
        }
    }
    // Update the AccountReassignmentNumber to the last AMs postion on the RoundRobinAssignment Custom Metadata Type record
    accountReassignmentNumberRecord[0].AccountReassignmentNumber__c = currentOwnerPosition;
    //Commit update to the AccountReassignmentNumber__c How do I do this?           
}  
    //IF the current positon is greater than the total AM count then the counter is reset else we increment to the next AM
    public static Integer calculatePosition(integer currentOwnerPosition, integer amCount){
        IF(amCount <= currentOwnerPosition){
            currentOwnerPosition = 0;                
        } else {
            currentOwnerPosition = currentOwnerPosition+1;}
        System.debug('New currentOwnerPosition = ' + currentOwnerPosition);
        return currentOwnerPosition;
}}

Best Answer

The way I use to update custom metadata in Apex is via the Andrew Fawcett Github (unmanaged) Custom Metadata Services

Custom Metadata Services (CMS) is a small library created to wrap the native Apex Metadata API to leverage the native SObject types for custom metadata in a more DML orientated way. It also aims to simplify the handling of the async results when developing clients in Lightning, inspired in this case by Lightning Data Services.

The code would look something like this:

Map<SObjectField, Object> mdtValuesByMdtField = new Map<SObjectField, Object> ();
// new RoundRobin value
mdtValuesByMdtField.putAll(new Map<SObjectField, Object>{
    RoundRobinAssignment__mdt.AccountReassignmentNumber__c => yourNewRoundRobinValue
});

//  add in the MDT record key
mdtValuesByMdtField.putAll(new Map<SObjectField, Object>{
            RoundRobinAssignment__mdt.DeveloperName => 'Master',
            RoundRobinAssignment__mdt.Label => 'Master'
});


String deployId = CustomMetadata.Operations
            .callback(
                    // Platform event for deploy status
                    MetadataDeployment__e.getSObjectType(),
                    MetadataDeployment__e.DeploymentId__c,
                    MetadataDeployment__e.Result__c)
            .enqueueUpsertRecords(
                    // Custom Metadata object type
                    RoundRobinAssignment__mdt.getSObjectType(),
                    new List<Map<SObjectField, Object>>{
                            // Custom Metadata record
                            mdtValuesByMdtField
                    })
            .deployId;
Related Topic