0

I have 2 objects A and B where B is linked to A via LOOKUP relationship. There is a checkbox on object A which becomes TRUE when the stage (Picklist field) for object A is changed to "Funded", and when this becomes TRUE, it does not allow the record of object A to be altered and even it does not allow related record of object B to be altered.

Now we have a new requirement where users should be able to update the related record of object B, and to do the same I have created a new checkbox field in object A and I am bypassing the validation rule (which prevents records of A and related records of B to be altered) via this checkbox which I am updating it to TRUE using BEFORE UPDATE trigger on object B and then resetting the checkbox (updating it back to FALSE) using AFTER Update trigger so that validation rule works after the related record of object B is altered, but my After update trigger is failing with below error.

Apex trigger BAfterUpdateTrigger caused an unexpected exception, contact your system administrator. BAfterUpdateTrigger: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 and id 0830C000000sZWQAY: first error:FIELD_CUSTOM_VALIDATION_EXCEPTION. Object A has been locked and cannot be edited. Please contact your admin if you need to make any adjustments.

Below is my validation rule

Rule condition:

AND( 
Lock_Credit_Package__c = TRUE, 
NOT( LockByPass__c = TRUE) 
)

Error message:

Object A has been locked and cannot be edited. Please contact your admin if you need to make any adjustments.

Looking at the error message it seems that the After update trigger is failing due to validation rule which I am bypassing through Before update trigger using a bypass flag field "LockByPass__c" on object A.

Before Update Trigger:
trigger BUTrigger on Object_B__c (before update) {

if(Trigger.IsUpdate){
    Set<Id> creditPackageIds = new Set<Id>();
    for(Object_B__c dr: Trigger.new){
        creditPackageIds.add(dr.Credit_Package__c);
    }

    Map<Id, Object_A__c> creditPackageMap = new Map<Id, Object_A__c>([
        SELECT Id, LockByPass__c FROM Underwriting__c WHERE Id IN :creditPackageIds
    ]);

    List<Object_A__c> creditPackageUpdate = new List<Object_A__c>();
    for(Object_B__c dr: Trigger.new){

        if(dr.Credit_Package__c != null){  
           Object_A__c cp = creditPackageMap.get(dr.Credit_Package__c);           
           cp.LockByPass__c = True;      
           creditPackageUpdate.add(cp);                      
         }
    update creditPackageUpdate;         
    }
 }   
}

After Update Trigger:

trigger AUTrigger on Object_B__c (after update) {

    Set<Id> creditPackageIds = new Set<Id>();
    List<Object_A__c> updatedUnd = new List<Object_A__c>();
    List<Object_B__c> drList     = new List<Object_B__c>([SELECT Id, Name, Credit_Package__c FROM Object_B__c WHERE Id IN :Trigger.newMap.keySet()]);

    for(Object_B__c dr: drList){
        creditPackageIds.add(dr.Credit_Package__c);
    }

    Map<Id, Object_A__c> undMap  = new Map<Id, Object_A__c>([SELECT Id, LockByPass__c FROM Object_A__c WHERE Id IN :creditPackageIds]);

    for(Object_B__c dr: drList){

        if(dr.Credit_Package__c != null){        
           Object_A__c und = undMap.get(dr.Credit_Package__c);           
           und.LockByPass__c = False;
           updatedUnd.add(und);
         }
    }
    update updatedUnd;    
}

Can somebody suggest a better solution to bypass the validation rule?

1 Answer 1

0

Try this formula for your validation:

AND( 
 Lock_Credit_Package__c, 
 NOT( LockByPass__c ),
 NOT( ISCHANGED( LockByPass__c ))
)

You must log in to answer this question.

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