1

I'm looking for the most efficient way to accomplish the following: Stop Users via Validation from editing a record when a specific field is BLANK, but allow Process to edit the record at any time.

Another way of looking at it: What "user" does the Process Builder operate under?

Situation:

Accounts are created. A LOOKUP field exists that is BLANK at first (looks to object "Customer"). In 30-60 seconds, the record is supposed to allow a Process Builder routine to edit the record (but not users).

Is there a way to know Process Builder is the one trying to edit the record, so it can be allowed to bypass Validation?

A temporary field won't work(..?) because it would be set and cause the bypass to happen for anyone.

$User.UserType also appears to be useless here.

In pseudo-code:

and( 
  isblank( NeededField__c ),
  $User.SystemOrHuman = "Human"
)

...... this would Validate (block) a human from touching the Record until the NeededField__c is populated.


UPDATE: Related to this - Does Process Builder Run as User or System?


A CLEARER USE CASE:

Accounts are created.

This causes a (custom object) Customer to be created, which links itself to the Account via Apex. No control over how this managed package does this.

We have a Process Builder that, when a new Account appears, sets a few values automatically on the Account, then Time Lapse, runs a Flow that links the Account to the Customer. We control this. This happens one minute later using "5 hours before Created Date" as the reference.

Due to that "one minute later" logic in the Process Builder, if you TOUCH the Account prior to the "one minute", it breaks the update and it never happens, ever. I want to allow the Managed Package to let it's Apex code run (typing this has made me realize it may technically be allowing Apex, not Process Builder, to bypass the Validation).

3
  • Process builder runs as the current user but has system access just like a trigger. So if you are checking user ids it will return the current user, the one who started the process
    – Eric
    Apr 18, 2017 at 20:17
  • The question remains that "is there a marker of some kind" that can be used to KNOW it's a system-access level transaction (aka "System mode" per the linked other Question).
    – AMM
    Apr 18, 2017 at 20:39
  • Not to my knowledge no. At least not without a purposeful intervention at every non UI entry point and a lot of hacking. I would question why it is ok for code to allow it to be blank when it is required for a user to enter. Maybe that answer to that question would help you come up with a solution.
    – Eric
    Apr 18, 2017 at 20:46

2 Answers 2

3

Process Builder runs "as the user", but with "system permissions." This means it can perform operations the user normally couldn't. As such, I think the easiest way to do this would be to write the validation rule as:

NOT(ISNEW()) && ISBLANK(NeededField__c)

Have NeededField be read-only for the user so they can't manually manipulate the record into being editable ahead of time.

As a related concept, perhaps you could use a short trigger to just lock the record:

trigger onObjectX on ObjectX (after insert, after update) {
    ObjectX[] locks = new Object[0], unlocks = new ObjectX[0];
    for(ObjectX record: Trigger.new) {
        if(record.NeededField__c == null) {
            locks.add(record);
        } else {
            unlocks.add(record);
        }
    }
    Approval.lock(locks, false);
    Approval.unlock(unlocks, false);
}

I'm pretty sure there's other alternatives as well of various complexity, but I hope one of these will help you.

5
  • First part: This doesn't work because Apex from the Managed Package breaks and causes a Flow error. That was (is) my (disbled) Validation right now. Second part: Yeah, you WOULD go to Apex (smile). It may end up being the answer..... though overnight....
    – AMM
    Apr 19, 2017 at 12:04
  • .......I pondered the idea that, the reason I HAVE a "5 hour before" timed event (therefore a "1 minute later" execution) is because I cannot populate that field UNTIL the records in question have been saved one time. I'm wondering now if I don't simply do a "if it's not populated AND an edit happens, not ISNEW", then populate it. It makes sense to me.... going to work on it. Thanks for the suggestion.
    – AMM
    Apr 19, 2017 at 12:04
  • @AMM There's other possibilities out there, too, but I just figured that a short, concise trigger would be more beneficial than devising code-free solutions that would take longer and require more maintenance down the road. For example, I also considered using Record Types, more Process Builders, and Page Layouts to simply remove the edit button until after your update happens, but that requires a ton more work than 12 lines of code.
    – sfdcfox
    Apr 19, 2017 at 12:11
  • Thanks. Sad part is... the solution I was going to try? Yeah, I wrote it 2-3 months ago. HOWEVER, thanks to the fact that Field API name updates do NOT UPDATE PROCESS BUILDER FORMULAS, the active PB handling it is simply saying "yeah, that field hasn't changed yet". So, updated it, and voila. ALl is well again. (sigh) Previously: Link_to_Rootstock_Customer__c ... now: Rootstock_CUSTOMER__c ... PB still said the Link_to_ version.
    – AMM
    Apr 19, 2017 at 12:41
  • I've posted a lengthy answer to a related question of mine things to this exchange. Thanks..... salesforce.stackexchange.com/questions/169875/…
    – AMM
    Apr 19, 2017 at 12:56
2

As a workaround you could

  1. write a trigger / code to allow the fields the PB is updating to be edited but no other fields. Downside would be the user could edit those as well...But it may be a viable workaround.

  2. Override the edit button. Have it take to a VF page that checks to see if it can be edited. If not show a message that the user cannot edit the record and a button to take back to the detail view. If they are allowed to edit then take to standard edit page with the nooverride parameter set to 1

Item 2 would cover all bases but would take a small amount of code to work.

1
  • Item 2 doesn't actually cover S1 users, I think, but I'd have to test it out.
    – sfdcfox
    Apr 19, 2017 at 12:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .