Salesforce.com Workflow to the Second

12/22/2011

I recently came across the requirement for a workflow rule to fire on the update of a record but only if the update occurred more than a couple seconds after the record was created. Why this crazy requirement? Here is a example of the problem I was faced with.

Image you have two custom objects, Exam and Question. There is a master detail relationship between the two where many Questions can be associated with one Exam. There are also some roll-up summary fields on the Exam that count number of questions, number answered correctly, etc. Now also image (lots of imagining today so I hope you can harness your inner child imagination skills) you have a Visualforce page that assigns exams to users. This Visualforce page essentially clones a an Exam and Questions and assigns these to a user. First it inserts the Exam and then all related Questions. On the Exam object there is a workflow rule that need to execute when an Exam is updated. The problem is this workflow rule kept firing every time I inserted Exams and Questions for a user. Why is this happening? I am only inserting records, right? Wrong-a-long-a-ding-dong!!!

So what is happening here? Why is an update occurring on the Exam record when all I am doing is inserting records? The culprit are those very cool, but pesky, roll-up summary fields. When you have a roll-up summary field on a record any time you insert or update a child record an update will occur on the parent. So in the example above every time I would insert the the Questions it would cause on update action on the Exam. This is documented but it might not be something you come across every day. It’s also not obvious as everything happens so fast in the code the Created Date and Last Modified Date on the Exam show the same values in the user interface. If you queried these two date fields you would see they are milliseconds apart.

So how to solve this? There are a few options. We could set a flag, a checkbox field, on the Exam called Disable Workflow that we set to true on the insert of the Exam and then after inserting the Questions we could uncheck this box. In our workflow rule we could prevent the rule from executing by referencing this field. This would work but I don’t like it for a couple reasons. The first is that I hate adding fields to the database that aren’t really needed. Secondly, it’s less efficient as it requires multiple DML (update) operations to make everything flow smoothly. Another options is to get super crafty with our workflow rule.

The insert of the Exam and Questions is going to be finished in milliseconds. What if we make the rule fire on updates but only on updates a few seconds after the record is created. What we need to do is determine the time between the created date of the record and now in seconds. When working with formula fields or validations rules the duration of one day is represented as the value of 1. If we know this we can use our superior deductive reasoning skills to figured out the value for one second.

1 / 24 = 0.0416667 is one hour
0.0416667 / 60 = .00069444 is one minute
0.00001157 = one second

Now in our workflow rule we have have a formula like this:

…and it will evaluate to true on updates but only if those updates are greater than 1 second after the record was created.