Posts

How to Clone a Record Programmatically and Set Audit Fields

Ever want to clone a record with full control over the resulting record? I recently was testing a time-based Process Builder and found myself frustrated by the one-hour minimum on the PB. I didn't want to wait that long to verify if it was working correctly. I could clone records for testing, but I couldn't force the Created Date, so I'd have to wait the full hour. Here's a snippet I came up with that will do just that for you. In my case, I have it set so that the createddate of the record will be 55 minutes ago, making testing the PB with a one-hour window much easier. You can run this in Execute Anonymous, and you only have to set the first two fields under "Setup." The other three are optional. Feel free to reach out if you have any questions.

What Happens To "Inflight" Process Builders When You Activate a new Version?

Image
tl;dr : If an individual record is in a "Paused Flow Interview" state, and you create a new version of the Process Builder, the record will "wake up" at its specified time and complete the actions as specified in the version of the PB that was active when the record entered the paused state. There is some confusion as to what happens to Process Builders that have "inflight" time-based actions when you create a new version of the PB.  The information from Salesforce is incomplete and there are contradictory StackExchange answers, including here. At the time of writing, the first answer answers the wrong question, and the 2nd and 3rd answers fully contradict each other. Clearly this is due for someone to just test it. My Test I conducted the following test - I'm going to create a PB, create a test record, and see what happens if I update the PB while the record is pending. One of three things is going to happen: Nothing will happen to the record The re

Update Knowledge Articles in Bulk

Image
Recently we had a big Knowledge Centric Support (KCS) initiative where we generated a ton of Articles for use in a Community. (We're still on Classic Knowledge.) Problem is, some users forgot to tick the "Customer" box when creating the Articles. So those articles didn't appear to external users in the Community. You can update these Articles in bulk, but you need to use a few obscure hooks in Apex. This method will create a draft of the Article, update the Knowledge Article Version, and then re-publish without creating a new Version. The following code will update the 'IsVisibleInCsp' flag for a single Article specified in the 1st query, which will make it visible to Customers. Here's a bulkified version. This is heavy on the CPU so I run it 10 at a time. When going over these in bulk, you might run into a situation where there is an existing draft of an article that has been previously published; i.e., it's actively being updated. In t

Custom Lookup For Flows to Avoid "Disjunctions Not Supported"

Image
Because custom metadata and Flow don't mix , I had to create a service that would run the custom metadata lookup in Apex, where I can control the bulkification. Code Here is some code that will achieve this. It takes a list of field names and a list of values, and a table name, and returns the value from the lookup. To install the code, open Developer Console, and create four files: FlowLookup FlowLookupRequest FlowLookupResult MyException You can copy/paste the code from Github into those files, then save them. That will make the plugin available to your Flow. Step-By-Step Usage Here's an example that looks up a value called a "fireball" from a custom metadata table and assigns the value to a record called iLead__c. Request and Response Formats The process has a request and a response. The request contains: Query Fields - a list of the fields you want to query Query Values - another list of the values for the above fields Result Field - the field to pull the result

"Disjunctions not supported" - Why Custom Metadata and Flow Don't Mix

Salesforce has been focusing a lot on Flow recently, as they should. It splits the difference nicely between Process Builder and Apex code. We recently used Flow to implement what I'd expect is a common use case - when a record is created, lookup a value from a table and update the record. In this case, it's a light lead score we call a "fireball" value. This worked great since in most use cases we'd get one record at a time. But we found during Lead conversion, we would get a few records through at a time, which caused the process to break with a really odd error: Error Occurred: This error occurred when the flow tried to look up records: Disjunctions not supported. After some research it became clear that this is the error you get when you try to query a custom metadata table using an "OR" condition. But my Flow didn't use an "OR" condition in the metadata lookup. The answer was lurking in this obscure documentation: When you define mult

A Pattern for Apex Test Code So You Can Forget About Required Fields

Yeah, yeah, yeah, just take me to the code . I recently had the opportunity to start writing some code in a brand new org, which got me thinking about the best way to do test object creation. You know, that annoying problem where you need to generate an Account in a test class about 77 times. Here’s a pattern I came up with. This method involves some overhead but it has the advantages of (1) allowing you to set defaults for certain objects so you don’t have to worry about them – for some objects create them with all defaults with just one line, and (2) a generic, repeatable pattern. It’s based on an abstract class that implements the base operations using some generic sObject magic outlined here . A lot of code in this post, bear with me. (That's a basic version, for something more robust, look here .) For each object you will use, you need to create a class that implements the abstract factory class. Then, in your test code you would need to inst

Salesforce: A Practical Approach to Queueables

Image
Update, June 2020: Like to live dangerously? Go straight to the code. I've set up a project with the framework and some examples. Salesforce triggers are great, but they run synchronously by default. What if you want to speed up the user experience and run noncritical tasks in the background? That’s what Queueable is for. But it’s not as simple as it’s made out to be. I think most organizations have a simple process where they have a Trigger that calls a Trigger Handler. With a Queueable, you might think you can do something like this. Trigger: Trigger Handler: Then a Queueable to implement your business logic.  The problem with this approach is, as Brian Fear (aka sfdcfox) said in his outstanding response to my StackExchange Question : “The rule is that if you’re synchronous, you get 50 jobs for that transaction. Once you go asynchronous, you get only one child allowed.” Brian went on to provide an example, which works great. Basically it detects if you’ve “Gone Synchronous” and