1

We have a few validation rules to protect our records to be modified if they meet the criteria, but a few days ago one of the validation rules stopped working, right now we don't know the exact reason.

Also we tried to debug it and if we remove the OR Section with the stage names, works perfectly, we tried many variations of this and all of those failed.

We're thinking on a workaround creating a new custom field to make the validation rule shorter, but is there any other solution that we're not seeing?

AND(
    NOT($Profile.Name = "Profile A"),
    NOT($Profile.Name = "Profile B"),
    NOT($Profile.Name = "Profile C"),
   OR(
      ISPICKVAL(StageName, "Closed Won"),
      ISPICKVAL(StageName, "Closed Renewal"),
      ISPICKVAL(StageName, "Closed Change Order")),
   OR(
       ISCHANGED(AccountId),
       ISCHANGED(Name),
       ISCHANGED(StageName),
       ISCHANGED(Description),
       ISCHANGED(Amount),
       ISCHANGED(Probability),
       ISCHANGED(CloseDate),
       ISCHANGED(OwnerId)
      )
)
4
  • are you sure you don't have non-breaking spaces in the stagenames? (either the schema ones or the VR ones). Just code up a VR of ISPICKVAL(StageName, 'Closed Won') and see if it works. If all those stagenames are considered as "Won" stages, you can replace with simply IsWon
    – cropredy
    Nov 15, 2022 at 4:41
  • I added a formula field on the sandbox to make sure I'm typing them correctly, even with that, it allows to change the Stage to the 'previous ones', so I don't know if I'm missing anything or if I should raise a ticket directly with Salesforce Nov 15, 2022 at 17:33
  • 1
    oh -- you want to check that the stagename can't be changed from Closed Won? then you need PRIORVALUE function
    – cropredy
    Nov 15, 2022 at 17:35
  • Thanks! That solved the issue! Nov 15, 2022 at 18:39

2 Answers 2

0

Given that you care about validating whether the Opportunity is moving out of one of the three stagenames, your OR block for StageName needs to change from:

OR(
  ISPICKVAL(StageName, "Closed Won"),
  ISPICKVAL(StageName, "Closed Renewal"),
  ISPICKVAL(StageName, "Closed Change Order"))

to:

OR(
  ISPICKVAL(PRIORVALUE(StageName), "Closed Won"),
  ISPICKVAL(PRIORVALUE(StageName), "Closed Renewal"),
  ISPICKVAL(PRIORVALUE(StageName), "Closed Change Order"))

Notes: PRIORVALUE Help doc

1
0

There's a few tricks you can use to optimize this, even though it looks correct as is.

First, consider moving to Custom Permissions. Create a Custom Permission, assign it to any Profiles or Permission Sets you want, then you can optimize the validation rule as:

AND(
  NOT($Permission.EditClosedOpps),
  OR(
    ISPICKVAL(StageName, "Closed Won"),
    ISPICKVAL(StageName, "Closed Renewal"),
    ISPICKVAL(StageName, "Closed Change Order")),
  OR(
    ISCHANGED(AccountId),
    ISCHANGED(Name),
    ISCHANGED(StageName),
    ISCHANGED(Description),
    ISCHANGED(Amount),
    ISCHANGED(Probability),
    ISCHANGED(CloseDate),
    ISCHANGED(OwnerId)
  )
)

Second, consider using CASE as a shortcut to comparing values in a picklist. Unfortunately, you can't return TRUE or FALSE, but we can return, for example, a number, so we'll use the 1 = CASE() model.

AND(
  NOT($Permission.EditClosedOpps),
  1 = CASE(
    StageName, 
    "Closed Won", 1, 
    "Closed Renewal", 1, 
    "Closed Change Order", 1, 
    0
  ),
  OR(
    ISCHANGED(AccountId),
    ISCHANGED(Name),
    ISCHANGED(StageName),
    ISCHANGED(Description),
    ISCHANGED(Amount),
    ISCHANGED(Probability),
    ISCHANGED(CloseDate),
    ISCHANGED(OwnerId)
  )
)

Third, consider making this eight validation rules instead of one. This allows you to attach specific errors to specific fields, making it obvious which fields are disallowed, rather than a generic error at the top of the page.

AND(
  NOT($Permission.EditClosedOpps),
  1 = CASE(
    StageName, 
    "Closed Won", 1, 
    "Closed Renewal", 1, 
    "Closed Change Order", 1, 
    0
  ),
  ISCHANGED(AccountId)
)

...

AND(
  NOT($Permission.EditClosedOpps),
  1 = CASE(
    StageName, 
    "Closed Won", 1, 
    "Closed Renewal", 1, 
    "Closed Change Order", 1, 
    0
  ),
  ISCHANGED(Name)
)

... etc

This design will also make it easier to troubleshoot if a specific validation rule is not working, and allows them to be tweaked individually.

1
  • Hi @sfdcfox, first of all, thanks for all your help in this community, I really appreciate that. I followed your suggestions, custom permissions, using CASE instead of OR for the picklist value, and for each field, but I got the same issue, the other profiles can still do changes and logically doesn't make sense at all AND( NOT($Permission.EditClosedOpps), 1 = CASE(StageName, "Closed Won", 1, "Closed Renewal", 1, "Closed Change Order", 1, 0), ISCHANGED(StageName) ) Nov 15, 2022 at 2:27

You must log in to answer this question.

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