4

Is there a way to soql procesbuilder to tun activation off?

For example

List<Processbuilder> pbColl = new List<Processbuilder>();  
Processbuilder pb=[SELECT status FROM Processbuilder WHERE status Active];

for(Processbuilder turnoff : pb){
            turnoff.status = false;
            pbColl.add(pb)}
update pbColl;

If not is there a simple way to turn all activated Processes off/on?

2

If you want to be able to "flip a switch" in code to disable Process Builders, you could use a boolean Custom Setting field. Then update your Process Builders so that the very first entry criterion is the custom setting being true, and if it is not, stop. Then from Apex you will be able to set the Custom Setting field to false whenever you need to stop the processes from executing.

3

Ben Edwards has a set of tools which includes one called Salesforce Switch which enabled you to do this.

He has also put the source code on GitHub:

I also wrote a lightning component to allow on mass enable/disable:

At it's core, it uses the Tooling API.

Getting Flow/Process Info

GET: /services/data/v43.0/tooling/query?q=Select+Id,ActiveVersion.VersionNumber,LatestVersion.VersionNumber,DeveloperName+From+FlowDefinition+ORDER+BY+DeveloperName

Updating Flow/Process Info

POST: /services/data/v43.0/tooling/sobjects/FlowDefinition/{FlowId}/?_HttpMethod=PATCH

With JSON:

{
  'Metadata': {
       'activeVersionNumber': {versionNumber/null}
   }
}

NOTE: the ?_HttpMethod=PATCH is only required if your calling from Apex

1

Not natively in Apex. You'd need to use the Tooling API and query InteractionDefinitionVersion. See also: Error - Failed To Execute Flow - 301 Prefix - Process Builder That would allow you to query for the data, but I don't think you'd be able to turn the flows on/off this way. You may be having a bit of an X-Y Problem. You will generally get better answers if you describe your high level objective rather than the specific means you are pursuing to achieve it.

1

This is possible by using the Tooling API. There are three steps required to

  1. find active processes and store their information in the org
  2. switch all processes OFF
  3. switch all prior active processes back ON again

Copy the following code, paste it in anonymous Apex window in the Developer Console. Highlight each step (start and end marked in code) and execute consecutively.

I've done the same with Validation Rules, check on GitHub: ValidationRuleOnOff

/**
* ─────────────────────────────────────────────────────────────────────────────────────────────────┐
* Anonymous Apex to switch ON/OFF active Processes in Process Builder (Flow Definitions)
*
* Execute Step 1-3 anonymous to 
* * [Step 1:] find all active Processes in the org >> Store their Data in Cases
* * [Step 2:] turn all Processes OFF (Metadata -> activeVersionNumber -> null)
* * [Step 3:] turn all Processes back ON (active:true)
*
* All prior active Processes will be re-activated. 
* Data Storage Cases will be delted at the end of Step 3.
* ──────────────────────────────────────────────────────────────────────────────────────────────────
* @author         Heiko Krämer   <sfhcks@myforce.net>
* @created        2020-10-24
* ─────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

// START STEP 1 -> "QUERY FLOW DEFINITIONS, STORE FD DATA"
// Retreive active FlowDefinition from Org, store their URL and Metadata in Cases
List<Id> listOfFlowDefinitionIds       = new List<Id>();
List<Case> flowDefinitionStorageCases  = new List<Case>();
Integer flowDefinitionsProcessed       = 0;
 
// Tooling API Call to receive IDs for all active FlowDefinitions
String toolingSOQL = '/services/data/v49.0/tooling/query?q=Select+Id+From+FlowDefinition';
String baseURL     = URL.getSalesforceBaseUrl().toExternalForm();
String endpoint    = baseURL + toolingSOQL;
 
Http NewReq        = new Http();
HttpRequest hreq   = new HttpRequest();
 
hreq.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
hreq.setTimeout(60000);
hreq.setEndpoint(endPoint);
hreq.setMethod('GET');
HttpResponse hresp = NewReq.send(hreq);
 
String body = hresp.getBody();
System.debug('ResponseBody' + body);
 
// Parse JSON response for IDs >> store IDs in List.
JSONParser parser = JSON.createParser(hresp.getBody());
while (parser.nextToken() != null) {
    if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
        (parser.getText() == 'Id')) {
            parser.nextToken();
            listOfFlowDefinitionIds.add(parser.getIdValue());
        }
}
 
// Loop through FlowDefinition IDs and query all Metadata info via Tooling API
for (Id valId : listOfFlowDefinitionIds) {
    String valIdString = '\'' + valId + '\'';
    String toolingSOQL = '/services/data/v48.0/tooling/query/?q=Select+Metadata+From+FlowDefinition+Where+Id+=+';
    String baseURL     = URL.getSalesforceBaseUrl().toExternalForm();
    String endpoint    = baseURL + toolingSOQL + valIdString;
   
    Http NewReq        = new Http();
    HttpRequest hreq   = new HttpRequest();
   
    hreq.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
    hreq.setTimeout(60000);
    hreq.setEndpoint(endPoint);
    hreq.setMethod('GET');
    HttpResponse hresp = NewReq.send(hreq);
   
    String body = hresp.getBody();
    system.debug('ResponseBody' + body);
    system.debug('Length' + body.length());
   
    
    // Create cases to store data from active FlowDefinition
    // Case Subject is used to store the FlowDefinition endpoint URL
    // Case Description is used to store FlowDefinition Metadada
   
    If (!body.contains('"activeVersionNumber":null')){
        flowDefinitionsProcessed = flowDefinitionsProcessed + 1;
       
        case flowDefinitionStorageCase        = new case();
        flowDefinitionStorageCase.subject     = '/services/data/v48.0/tooling/sobjects/FlowDefinition/' + valId + '# FD' + flowDefinitionsProcessed;
        flowDefinitionStorageCase.description = '{"Metadata' + body.substringAfter('Metadata').removeEnd(']}');
        flowDefinitionStorageCase.origin      = 'Web';
        flowDefinitionStorageCase.status      = 'Closed';
        flowDefinitionStorageCases.add(flowDefinitionStorageCase);
    }
}
insert flowDefinitionStorageCases;
// END STEP 1


// START STEP 2 -> "SWITCH Processes OFF"
// SOQL all prior created cases >> update "activeVersionNumber" to "null" >> process PATCH Calls
List<Case> retrievedFlowDefinitionCases = new List<Case>([SELECT Id, Subject, Description
                                                            FROM Case
                                                           WHERE Subject
                                                            LIKE '%tooling/sobjects/FlowDefinition%']);
system.debug('Number of Cases: ' + retrievedFlowDefinitionCases.size());
 
for (Case flowDefinition : retrievedFlowDefinitionCases){
    String flowDefinitionUrl      = flowDefinition.Subject.substringBeforeLast('# FD');
    String flowDefinitionMetadata = flowDefinition.Description.replace(flowDefinition.Description.substringBetween('activeVersionNumber":', ',"description'), 'null');
    Http h                        = new Http();
    HttpRequest req               = new HttpRequest();
    req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + flowDefinitionUrl);
    req.setBody(flowDefinitionMetadata);
    req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');
    req.setMethod('PATCH');
    HttpResponse res = h.send(req);
    system.debug('HttpRequest: ' + req);  
} // END STEP 2


// START STEP 3 -> "SWITCH FLOW DEFINITION ON"
// SOQL all prior created cases >> process PATCH Calls to restore initial state >> delete all prior created cases
List<Case> retrievedFlowDefinitionCases = new List<Case>([SELECT Id, Subject, Description
                                                            FROM Case
                                                           WHERE Subject
                                                            LIKE '%tooling/sobjects/FlowDefinition%']);
System.debug('Number of Cases: ' + retrievedFlowDefinitionCases.size());
 
for (Case flowDefinition : retrievedFlowDefinitionCases){
    String flowDefinitionUrl      = flowDefinition.Subject.substringBeforeLast('# FD');
    String flowDefinitionMetadata = flowDefinition.Description;
    Http h                        = new Http();
    HttpRequest req               = new HttpRequest();
    req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + flowDefinitionUrl);
    req.setBody(flowDefinitionMetadata);
    req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');
    req.setMethod('PATCH');
    HttpResponse res = h.send(req);
}
delete retrievedFlowDefinitionCases;
// END STEP 3
0

At present time, there is a way to switch on/off process builder. You can utilize Hierarchical custom setting. Which lets you define setting specific to Org Level, Profile Level or User Level.

While creating a custom setting select the type as - "Hierarchy". Now this setting would be created similar to custom object, having suffix - __c. Now create your own custom field of type checkbox so that its boolean value can be utilized into process builder.

Now define the values specific to Profile or User level. So that it will provide relevant value (specific to profile or user through which current execution is being processed).

In the process builder you would be able to call it via formula field as - $Setup.customSettingName__c.customFieldName__c to check whether current user has the right to execute the process builder or not.

For more detail, please refer the following links -

  1. https://developer.salesforce.com/docs/atlas.en-us.236.0.apexref.meta/apexref/apex_methods_system_custom_settings.htm
  2. https://medium.com/@pankajsingh210/salesforce-hierarchy-custom-settings-d6e1dcce75d

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.