Time based workflow goes scheduled apex - Answers - Salesforce Trailblazer Community
Trailblazer Community
Ask Search:
Roger WickiRoger Wicki 

Time based workflow goes scheduled apex

Dear community

I've just made an overview of all automated processes we have in our org. I recognized that we have some triggers and workflow rules on the same object. As of a statement from our integration partner, they recommended us to use either workflows or apex, because of the execution order of those two together.

Now I have some questions about changing my workflow into a scheduled apex job. As I have found in some documentations, scheduling apex jobs seem to be quite easy, but they have a low limit (I've read about 25 and 100). As far as I've seen so far, there does not seem to be a limit to the number of time-based-workflow jobs that are allowed. So if I am to change the workflow into scheduled apex, I could encounter problems.

But for that, I'd need to know more about the schedulable interface first. For me it seems that I can schedule one job at a time. That job may however be a bulk job. I can have a maximum of 25 (or 100) of those jobs.

The workflow rule I have running at the moment is quite simple: If an opportunity has it's valuta date blank 5 days after the payable deadline, a field update job should update a picklist field to "go 1. admonition" and send a task to the accounting department.

So far so good. Now if I am looking at the time-based jobs from this workflow, there is an estimated number of 150 scheduled jobs. These 150 jobs however are one and the same proceedure however. They all set the admonition status.

If I look at the schedulable interface, I see that I can do a set of steps (anything I want actually) in a certain time period. This one set of steps for this time period seems to be "one job". Please correct me if I'm wrong.

So to handle the workflow, I'd simply need one scheduled apex job that checks every day for all opportunities, if there needs to be sent an admonition. This could however cause heavy SOQL jobs and probably I'm going to run into limits. But I've come up with an idea:

I create a trigger on opportunity which creates a new record of a custom object (apex job), writes to that object information like what opportunity(/sObject) this job is linked to, when this job has to be executed, what type of actions need to be taken (like updating a field) and so on. Then I would have the scheduled apex job get all objects of this type which have their execution date today and execute their job by retrieving the job information from the record itself and either delete or archive the job after execution.

So with that I would have one scheduled apex job that runs every day for the whole process.


This is only a mind construct, nothing begun so far. I need to know if I could achieve something like this before I start at all. The positive thing about this is that this job object could work for all types of sObjects.
I imagine I could run into problems with things like what fields I reference to (I'd need to use the API name of the field as a text value on the apex job object) or so.
Best Answer chosen by Roger Wicki
Jeff MayJeff May
There is a very explicit order of execution (for other readers, here is the official sequence:   http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm

The process will not be any faster if you switch to triggers from Workflow rules.  The business logic in the trigger would have to be the same as the Workflow Rule criteria to make sure the trigger was only operating on the desired records (just like a Workflow Rule.  

Think of it this way, it all the execution steps are going to happen, and all the same business processing has to happen, then it doesn't really matter where in the sequence the work gets done. 

The decision to use a trigger vs a workflow vs a scheduled job should be based on the business needs.  Any data that you need to be up to date and accurate cannot be set in a scheduled job.  Any data that just has to be correct "now and then" can be considered for updating in a scheduled job -- but we should ask what the benefit is of not just using Workflow Rules to keep it up to date all the time.  

The choice between a trigger and a Workflow Rule should come down to a) can the Workflow Rule access the record and field that needs updating. If yes, lean toward a trigger.  If not, then a trigger is your only option.

Keep in mind that you cannot control the order in which triggers run, or the order in which Workflow Rules run, so in both models, you need to define your record selection criteria carefully.

If your business process requires that a field be set before Workflows or Assignment Rules are fired, then you need a trigger (due to the Order of Execution). However, the Salesforce platform is very scalable and if you are trying to set different fields, tasks, Alerts based on different record criteria, you will be doing yourself, your org, and your successor a huge favor by keeping your customizations in the Configuration sector (UI), and not head into Coding (Apex).

Just my .02

All Answers

Jeff MayJeff May
You've done a lot of great research.  Nice job.  The best approach will depend on what you are trying to achieve (or the problem you are trying to solve).  Can you describe the business problem for us so we can offer our opinions on how to best use these 'automation' features.
Roger WickiRoger Wicki
Alright, here it goes

We have the following opportunity fields:
Date: PayableUntil__c
Date: ValutaDate__c
Text: AdmonitionStatus__c
Date: FirstAdmonitionDate__c
Date: SecondAdmonitionDate__c
  • Before we create our invoice with Conga Composer, we set a date into the field PayableUntil__c.
  • When an invoice is paid, the ValutaDate__c is set to the date the invoice was paid and thus this opportunity is no longer relevant for the admonition process.
  • If an invoice is not paid (ISBLANK(ValutaDate__c)) five days after the PayableUntil__c, write "go 1. Admonition" to the AdmonitionStatus__c and send a task to the accounting department to admonish the client.
  • When the Accounting department admonishes, they set the FirstAdmonitionDate__c to that day's date and overwrite AdmonitionStatus__c with "yes 1. Admonition".
  • If an invoice is not paid 21 days after FirstAdmonitonDate__c, write "go 2. Admonition" to the AdmonitionStatus__c and send a task to admonish the client to the accounting department.
  • When the Accounting department admonishes, they set the SecondAdmonitionDate__c to that day's date and overwrite AdmonitionStatus__c with "yes 2. Admonition".
For that process I currently have two workflow rules, one for each admonition. Both are "Evaluate the rule when a record is created, and any time it’s edited to subsequently meet criteria". The first admonition has a time-based execution of a field update (AdmonitionStatus__c) and a Task five days after PayableUntil__c and the second admonition a field update (AdmonitionStatus__c) and a Task 21 days after FirstAdmonitionDate__c.

First Admonition:
AND(
ISBLANK(ValutaDate__c),
NOT(ISBLANK(PayableUntil__c))
)

Second Admonition:
AND(
ISBLANK(ValutaDate__c),
NOT(ISBLANK(PayableUntil__c)),
NOT(ISBLANK(FirstAdmonitionDate__c))
)

That's status quo. Now I'm up to doing the same process with Apex. The difficult part of this business problem is the "do something in the future" thing which is kinda easy with time-based workflows but probably harder with apex.


Hope this helps.
Jeff MayJeff May
Got it.  Now the question is, why would you want to build something in Apex that is provided by Salesforce out of the box?  The Apex will be harder to write, harder to maintain, and harder to explain/diagnose if something goes wrong.
Roger WickiRoger Wicki
Basically it is just a matter of advice from our implementation partners and the way, when Workflow rules are calculated. They provided us with this information:

Trigger Execution Order
  1. Loads the original record
  2. Loads the new field values
  3. Check compliance with layout- specific rules
  4. Executes all before triggers
  5. Runs system validation steps again
  6. Saves the record to the database
  7. Executes all after triggers
  8. Executes assignment rules
  9. Executes auto-response rules.
  10. Executes workflow rules
  11. If there are workflow field updates go to 4
Now with every Workflow I have, the whole process is taking longer and longer and it may come to cascading effects that I didn't want. That's why they recommended us to use either Workflows or Apex, but not both at the same time.

I know of course that finely built triggers and Workflow rules work just fine together, but I would be limited in my vision if I'd believe that the salesforce admin after me is that correct and foresighted about those aspects. I strongly believe in "NTU" (Never Trust an User) be he admin or not ;-)
Jeff MayJeff May
There is a very explicit order of execution (for other readers, here is the official sequence:   http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm

The process will not be any faster if you switch to triggers from Workflow rules.  The business logic in the trigger would have to be the same as the Workflow Rule criteria to make sure the trigger was only operating on the desired records (just like a Workflow Rule.  

Think of it this way, it all the execution steps are going to happen, and all the same business processing has to happen, then it doesn't really matter where in the sequence the work gets done. 

The decision to use a trigger vs a workflow vs a scheduled job should be based on the business needs.  Any data that you need to be up to date and accurate cannot be set in a scheduled job.  Any data that just has to be correct "now and then" can be considered for updating in a scheduled job -- but we should ask what the benefit is of not just using Workflow Rules to keep it up to date all the time.  

The choice between a trigger and a Workflow Rule should come down to a) can the Workflow Rule access the record and field that needs updating. If yes, lean toward a trigger.  If not, then a trigger is your only option.

Keep in mind that you cannot control the order in which triggers run, or the order in which Workflow Rules run, so in both models, you need to define your record selection criteria carefully.

If your business process requires that a field be set before Workflows or Assignment Rules are fired, then you need a trigger (due to the Order of Execution). However, the Salesforce platform is very scalable and if you are trying to set different fields, tasks, Alerts based on different record criteria, you will be doing yourself, your org, and your successor a huge favor by keeping your customizations in the Configuration sector (UI), and not head into Coding (Apex).

Just my .02

This was selected as the best answer
Roger WickiRoger Wicki
Any two cents are worth much in the right moment. Thank you Jeff.

I guess with the data being "up to date" you refer to scheduled jobs run as there is capacity (like for scheduled reports)?  That would indeed not be good for this process (unless it happens withing a +/-12h timeframe).

"Keep in mind that you cannot control the order in which triggers run, or the order in which Workflow Rules run, so in both models, you need to define your record selection criteria carefully."

Does this apply as well if I use a trigger manager with the trigger template that can be found around the developer.force.com/stackoverflow ? Because as I understand it, the order Trigger Handlers are added to the Trigger Manager, is also the order of execution.


I agree on keeping it simpler by having more in the Configuration Sector then in Code. This surely makes life easier in general. And who would I be to ignore SteveMo's K.I.S.S!    :-D
Jeff MayJeff May
You are correct about the time gap on scheduled jobs.  Also, from a systems perspective, why would you build a separate mechanism (the Apex code in the scheduled job) to detect records that have changed and need attention, when you already have 2 of those mechanisms available?

When a database event happens (create, update, delete), Salesforce will run the triggers that are listening on that event.  There is no way to control the sequence of 2 triggers that are listening on the same event (Account create, for example).  Any code written in a single trigger will be executed in the sequence you write it, but if there are 2 separate triggers, you cannot guarantee the order.   Many people are fooled into thinking differently because once the triggers are added to an org, they are nearly always run in the same order.  However, this is not guaranteed, so after several months of 'everything working fine', all of a sudden 'things break', because the trigger execution sequence changed. (Note that I am only talking about the sequence of 2 triggers listening on the same event for the same object.  The overall execution order is written in stone and will not change randomly).
Roger WickiRoger Wicki
Just as I thought. Thanks a lot!