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
Eager-2-LearnEager-2-Learn 

preventing an admin from deleting or editing a record but allow trigger too do it.

Hi,

I am writing this small app to keep track of our user license in a specific way so that we know what department and cost center is paying for the license.  I created a two custom objects (master/detail).  When an action is performed on the user record the trigger executes custom code that creates a child record (detail)  with info about that user record and what department, etc.  The master object holds the allotted license count, used, and balance.  here is the issue.

Because this is an admin app and an admin has all permissions I need to know how I can prevent the admin from deleting or editing these child records.  The only way they should be edited is if the admin changed the User record's license department.  If the user is marked inactive then the trigger code deletes the child record as described above.

Is there a way to detect when a user is using the page layout delete or edit capability on the child (related list) record so that I can have my code produce a message to the admin that they are not allowed to do that but still have the trigger code on the user trigger delete or edit the records on the child record?

I have not done this yet but I was thinking the solution is this: 
Create a static variable at the user trigger level and since I would set it to a value (TRUE) when the user record is updated by the time the delete DML or update DML fires on the child record I could have code in the child record trigger test for that value.  If it is true do nothing but if it is FALSE (assumed the user clicked edit or delete at the child record level/related list show an error (child.addError('You cannot do this action").

Or will I not have scope to the variable that is created in the user trigger by the time execution gets to the child trigger?  This is what I am not certain of.
Best Answer chosen by Eager-2-Learn
Eager-2-LearnEager-2-Learn
Ok -- I figured a way to make it work!
I created a static boolean variable in the User object Trigger Handler class like so "public static Boolean UserTriggerExecuting = false;"  Then I set it to TRUE when the methods in that handler class are called.  

In the trigger before insert, before update, and before delete events for the custom object I check for the condition of UserTriggerExecuting == FALSE and if it false that means the custom object trigger should not be allowed to insert, delete or update the records because it was not performed by the User object's trigger.  The custom object trigger code is below.  Obviously if after I do further testting and this works I will move all that logic into its own class.

For the life of my I do not understand why SF allows the ability at the standard related list page layout to remove the New button but they have no way of disabling the edit or delete links!

I hope this helps any folks out there with a similar use case.



trigger LicenseTrackingUserTrigger on License_Tracking_User__c (before update, before insert, before delete) {

    Boolean UserTriggerExecuting = UserTriggerManager.UserTriggerExecuting;

System.debug( 'UserTriggerExecuting: ' + UserTriggerExecuting );
    if ( trigger.isUpdate || trigger.isInsert ){
        for ( License_Tracking_User__c ltu : Trigger.new ) {
            if ( !UserTriggerExecuting ) {
                ltu.addError('Action Not Allowed!');
            }
        }
    }
    if ( trigger.isDelete ) {
        for ( License_Tracking_User__c ltu : Trigger.old ) {
            if ( !UserTriggerExecuting ) {
                ltu.addError('Action Not Allowed!');
            }
        }  
    }
}


All Answers

Ashish_SFDCAshish_SFDC
Hi , 


You should try have one more Admin's Cloned profile which does not have the Delete Option. 

Then you must write the Class / Trigger in the System Mode so that It gets executed and records get deleted. 


Regards,
Ashish

Eager-2-LearnEager-2-Learn
Thank you for this option.  I cloned our current admin profile and it seems to allow me to now edit the object to not allow admins to modify the object.  Strange that the out of the box admin profile does not allow me to do this. 

Aside from this option as if I do this option I need to find out the impacts of creating future objects and how what there default settings will be for this new profile.  Maybe there is no impact!

Is there any other way to do this with code -- it would be nice if SF set a system variable value that lets us know that a GUI fired off the trigger and not apex code.
Ashish_SFDCAshish_SFDC
Hi , 


The Standard Admin profile is not editable in certain sections - however we can clone and override. 

We can edit that profile in Future based on addition later. 

You can create a visualforce page with the custom button on it which inturn fires the trigger and add the javascript event on clicking the page on that button to update a hidden field with a check box that says - from UI - True etc.


Regards,
Ashish 
Eager-2-LearnEager-2-Learn
I want to stay away from VF page if I can help it.  The problem with changing the object level so that it is not editable or deletable is that the apex code cannot overwrite the object level setting.  I wish they allowed a way to simply not allow the edit/del links on the related list!
Eager-2-LearnEager-2-Learn
Ok -- I figured a way to make it work!
I created a static boolean variable in the User object Trigger Handler class like so "public static Boolean UserTriggerExecuting = false;"  Then I set it to TRUE when the methods in that handler class are called.  

In the trigger before insert, before update, and before delete events for the custom object I check for the condition of UserTriggerExecuting == FALSE and if it false that means the custom object trigger should not be allowed to insert, delete or update the records because it was not performed by the User object's trigger.  The custom object trigger code is below.  Obviously if after I do further testting and this works I will move all that logic into its own class.

For the life of my I do not understand why SF allows the ability at the standard related list page layout to remove the New button but they have no way of disabling the edit or delete links!

I hope this helps any folks out there with a similar use case.



trigger LicenseTrackingUserTrigger on License_Tracking_User__c (before update, before insert, before delete) {

    Boolean UserTriggerExecuting = UserTriggerManager.UserTriggerExecuting;

System.debug( 'UserTriggerExecuting: ' + UserTriggerExecuting );
    if ( trigger.isUpdate || trigger.isInsert ){
        for ( License_Tracking_User__c ltu : Trigger.new ) {
            if ( !UserTriggerExecuting ) {
                ltu.addError('Action Not Allowed!');
            }
        }
    }
    if ( trigger.isDelete ) {
        for ( License_Tracking_User__c ltu : Trigger.old ) {
            if ( !UserTriggerExecuting ) {
                ltu.addError('Action Not Allowed!');
            }
        }  
    }
}


This was selected as the best answer