0

I have a Validation Rule on the Opportunity object where in if the Opportunity has a OpportunityLineItem certain custom fields cannot be edited from the UI. Now I have an Apex Trigger on the OpportunityLineItem where if I try to Add/Edit/Delete an OpportunityLineItem, it will calculate those fields on the Opportunity record.

I already created a Hierarchy Custom Setting called MyCustomSetting__c that has a checkbox field called Skip_Validation__c. Why can I not bypass the Validation Rule?

Validation Rule

 HasOpportunityLineItem && 
(ISCHANGED( Total_List_Price__c))  || 
(ISCHANGED( Total_End_User_Price__c)) ||
(ISCHANGED( Total_End_User_Price_Discount__c)) || 
(ISCHANGED( Total_Standard_Price__c)) || 
(ISCHANGED( Total_Standard_Price_Discount__c)) ||
(ISCHANGED( Total_SPR_Price__c)) || 
(ISCHANGED( Total_SPR_Price_Discount__c)) || 
(ISCHANGED( Total_Price__c)) || 
(ISCHANGED( Total_Price_Discount__c)) ||
(ISCHANGED( Total_SPR_Margin__c)) &&  NOT($Setup.myCustomSetting__c.Skip_Validation__c)

Trigger

trigger TotalOpportunityProductTrigger on OpportunityLineItem (before insert, before update, before delete , after insert, after update, after delete) {


LPGCalculatorSettings__c objCalSetting = LPGCalculatorSettings__c.getValues('RollupTriggerSwitch');

MyCustomSetting__c tempSkipValidation = MyCustomSetting__c.getInstance();


if(tempSkipValidation == null) {
  tempSkipValidation = new MyCustomSetting__c();
    }

tempSkipValidation.Skip_Validation__c = true;
    upsert tempSkipValidation;

if(objCalSetting.value__c){
TotalOpportunityProductTriggerHandler tp = new TotalOpportunityProductTriggerHandler();



if(Trigger.isInsert && Trigger.isAfter){

tp.TotalField(Trigger.new);

       }
else if (Trigger.isUpdate && Trigger.isAfter){

tp.TotalField(Trigger.new);

       }
else if(Trigger.isDelete && Trigger.isAfter){

tp.TotalField(Trigger.old);

    }
}

            tempSkipValidation.Skip_Validation__c = false;
            update tempSkipValidation;
}

I already checked and reviewed the Apex order of execution and I don't think that it will affect my code.

7
  • Do you mean you don't want user to edit the field from UI but should be able to edit it from trigger ? Commented Oct 27, 2016 at 0:30
  • 1
    As per this doc, developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… Order of Execution is ...>Validation Rules >.....> Triggers So I guess you will not be able to bypass "Validation Rules" via trigger code I could be wrong and someone can correct me if so.
    – Varun
    Commented Oct 27, 2016 at 0:37
  • 1
    Notice that before triggers fire before Validation Rules. It can be done.
    – Adrian Larson
    Commented Oct 27, 2016 at 2:11
  • 2
    This is now the third time in 24 hours that you've asked pretty much the same question (first question, second question). Is there a particular reason why this needed to be spread over 3 questions? -1 from me.
    – Derek F
    Commented Oct 27, 2016 at 2:47
  • 2
    Alternatively, asking so many questions on the same topic may mean that this is an X-Y problem. From that link: That is, you are trying to solve problem X, and you think solution Y would work, but instead of asking about X when you run into trouble, you ask about Y.
    – Derek F
    Commented Oct 27, 2016 at 2:55

1 Answer 1

6

Here is a case where using AND/OR is much more clear about which operations you are joining with your logical operators. You may have also confused yourself here with incorrect parentheses and ordering.

Logical operators just join clauses in order.

If you write A && B || C || D && E, it will be true if only C is true, or if A & B is true or if D & E is true. It's equivalent to (A && B) || C || (D && E).

In contrast A && (B || C || D) && E would only return true if A and E are true and at least one of B/C/D are true.

In light of the above, what you have written is equivalent to:

OR(
    AND(
        HasOpportunityLineItem,
        ISCHANGED(Total_List_Price__c)
    )
    ISCHANGED(...),
    ISCHANGED(...),
    AND(
        ISCHANGED(Total_SPR_Margin__c),
        NOT($Setup.myCustomSetting__c.Skip_Validation__c)
    )
)

But this validation rule doesn't match up with what you want at all! I believe what you really want is:

AND(
    HasOpportunityLineItem, NOT($Setup.MySetting__c.Skip_Validation__c),
    OR(
        ISCHANGED(...),
        ISCHANGED(...)
    )
)
1
  • Another consequence of this error is that you should, for instance, not be able to change Total_Price__c even if HasOpportunityLineItem is false.
    – Adrian Larson
    Commented Oct 27, 2016 at 1:29

You must log in to answer this question.

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