function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
K.G.K.G. 

How Close To "Last" Can I Execute Apex Code, And How?

Dear Salesforce Developer community,

Every time "Opportunity.StageName" or "Opportunity.Program__c" gets changed in any way (user edit, Apex, Workflow, Process), my department needs the value of "Opportunity.OwnerId" verified and possibly changed.

The rules of the change are complicated enough that I need to put them in code, which I'm comfortable doing.

According to business rules, I want to enforce this being the "final clean-up" on DML to "Opportunity" records.  If some Apex/WF/PB's themselves that I don't personally write/control change "StageName" or "Program__c," I want to clean up after that.

What I can't figure out is how to actually squeeze my code in "last" without causing infinite loops.

I can follow best practices like consolidating what triggers already exist into "1 per object," using "RUN_ONCE" logic on the methods they call, etc.

But how do I account for developers after me or fellow admins writing Processes (which seem to execute after, rather than before, triggers) and try to squeeze this logic in "after" their potential effects on "Opportunity.StageName" and "Opportunity.Program__c"?

Thanks so much,
K
Best Answer chosen by K.G.
bob_buzzardbob_buzzard
There's not a lot you can do I'm afraid - the order of execution:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm

is quite clear that processes fire after triggers.

The options that you have are:

(a) Produce an apex invocable method and try to ensure this is included into any process - this would be unlikely to succeed IMHO
(b) Execute a sheduled job that updates all the opportunities that have been changed since the last time it fired. The problem with this is that you would have a window where a process changed an opportunity but the scheduled job hadn't fired.

All Answers

bob_buzzardbob_buzzard
There's not a lot you can do I'm afraid - the order of execution:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm

is quite clear that processes fire after triggers.

The options that you have are:

(a) Produce an apex invocable method and try to ensure this is included into any process - this would be unlikely to succeed IMHO
(b) Execute a sheduled job that updates all the opportunities that have been changed since the last time it fired. The problem with this is that you would have a window where a process changed an opportunity but the scheduled job hadn't fired.
This was selected as the best answer
K.G.K.G.
Thanks, @bob_buzzard.  I was afraid that the answer would be bad news, but wanted to hear it from someone more experienced than myself.  :-)
K.G.K.G.
More discussion also over at http://salesforce.stackexchange.com/questions/105059/how-close-to-last-can-i-execute-apex-code-and-how
K.G.K.G.

@bob_buzzard, if you still see this (or anyone else):

Do you have any suggestions for a place to build (and, after using, delete) a "daily scratchpad" with 3 pieces of data per scratchpad-record?

(Can be stored as any kind of plain-text as long as I can serialize it & deserialize it from Apex code.)

1) The Opportunity ID in question,

2) whether it needs reownerization, and

3) its Primary Contact ID [if it needs reownerization].

 

I'm thinking an overnight batch job might be nice, but I would only want to perform it on "suggested" records from the day for performance.

Right now I've essentially got calls with these 3 parameters to the same "helper method" coming out of every piece of code that causes a need for "reownerization."  That "helper method" does DML & SOQL every time it executes.

If I could have all these "reownerization-triggering" pieces of code instead store the parameter values in a log, it could be the batch's job to look for unprocessed logs from before the current day, read their input as parameters, do everything at once, and then delete the log.