+ Start a Discussion
Sourav PSourav P 

Can merge accounts but shouldn't able to manually delete an account

Hi,
I have a profile, which should able to merge accounts. But They shouldn't manually delete any accounts. Although the delete button in the account has been removed, in the list view its till visible.
can anyone, help me with a trigger , that while they delete, it should through an error message but while merging there shoulnt be an issue. Thanks
Avishek Nanda 14Avishek Nanda 14
Hi Sourav,

You can't use a Validation Rule to prevent a Deletion.  That has to be a trigger. Please Find the Below Trigger Which Will Prevent User To delete the Account Record. 

Below Code, I have used Custom Label to store the Profile Id. If In Future if your org needs to extend this Feature to some other profile then You can add the value only in the custom label without even changing the code. 

If you want to add the same logic to User Label then you can add the user id in comma separated value in the label. 

Handler Class : 
public class CannotDeleteAccount {
    public static void NoDeleteAccount (List<Account> accounts){
        system.debug('before delete trigger');
        String ProfileId = UserInfo.getProfileid();
        set<string> strkey = new set<string>(Label.Profile_Group.split(','));
        System.debug('Profile Id of Current User'+ProfileId);
        
        for (Account acc: accounts){
            If(strkey.contains(ProfileId)){
                a.addError('You cannot delete the Account');
            }
        }
    }
}

Trigger :

trigger accountTrigger on Account (before delete) {
    if(checkRecursive.runOnce()){
        if(Trigger.isBefore){
            System.debug('Inside the Trigger');
            CannotDeleteAccount.NoDeleteAccount(Trigger.Old);
        }
    }
}

If this helps Mark this as the best answer. 
Sourav PSourav P
Hi Avishek, thank you
Let me try it
Sourav PSourav P
Hi Avishek,
The handler class, i modified a bit as below as it was showing Invalid identifier error.
 
public class CannotDeleteAccount {
    
    public void NoDeleteAccount(List<Account> accLst){
        system.debug('before delete trigger');
        Profile teamLeadprof = [select id,name from Profile where name = 'Team Leader' order by name limit 1];   
        Id profId = teamLeadprof.Id;
        System.debug('Profile Id of Current User : '+profId);
        Id currUser = UserInfo.getProfileId();
        for(Account acc : accLst){
          if(currUser==profId)
            acc.adderror('You Cannot delete the Account');
        }
    }    
}

The trigger class is also showing the same kind of error as below,
Error: Compile Error: Invalid identifier ' '. Apex identifiers must start with an ASCII letter (a-z or A-Z) followed by any number of ASCII letters (a-z or A-Z), digits (0 - 9), '$', '_'. at line 1 column 50

I am not able to know here, why so. can you plz help me out. Thanks

 
Trigger accountTrigger on Account (before delete) {
if(checkRecursive.runOnce()){
        if(Trigger.isBefore){
            System.debug('Inside the Trigger');
            CannotDeleteAccount.NoDeleteAccount(Trigger.Old);
        }
    }
}

 
Avishek Nanda 14Avishek Nanda 14
Hi Sourav,

I wrote the same code of yours in my developer org and I wasn't able to delete an account. Your Code Works Perfectly Fine. 

The only thing you missed in defining the method as static. Since the Nonstatic method cannot be referenced from a static context: void.

And also if you are using Check Recursive you have to add the class as well. This is a best practice we use to make sure the trigger doesn't go in recursive. 

So Your Code should look something like this. 
Add this Recursive Class. 

public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
}

You Handler Class 

public class CannotDeleteAccount {
    
    public static void NoDeleteAccount(List<Account> accLst){
        system.debug('before delete trigger');
        Profile teamLeadprof = [select id,name from Profile where name = 'Team Leader' order by name limit 1];   
        Id profId = teamLeadprof.Id;
        System.debug('Profile Id of Current User : '+profId);
        Id currUser = UserInfo.getProfileId();
        for(Account acc : accLst){
            if(currUser==profId)
                acc.adderror('You Cannot delete the Account');
        }
    }    
}

You Trigger. 

Trigger accountTrigger on Account (before delete) {
    if(checkRecursive.runOnce()){
        if(Trigger.isBefore){
            System.debug('Inside the Trigger');
            CannotDeleteAccount.NoDeleteAccount(Trigger.Old);
        }
    }
}

Your Test Class :
@isTest
public class TestAccountDelete {
    static testMethod void deleteAccount() {
       
       Profile userProfile = [select name from Profile where name='Team Leader'];
       List<User> usersList = [select Name,Profile.Name from User where Profile.Name='Team Leader'];
       Account accToDelete = new Account();
       accToDelete.OwnerId = usersList[0].Id; 
       accToDelete.Rating='Hot';
       insert accToDelete;
       delete accToDelete;
    }
    public static testMethod void ValidationTest() {

      Profile p = [SELECT Id FROM Profile WHERE Name='Team Leader'];
      User u1 = new User(Alias = 'newUser', Email='newuser1@testorg.com',
         EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
         LocaleSidKey='en_US', ProfileId = p.Id,
         TimeZoneSidKey='America/Los_Angeles', UserName='newusr@testorg.com');

      System.runAs(u1) {
         // The following code runs as user u1
         System.debug('Current User: ' + UserInfo.getUserName());
         System.debug('Current Profile: ' + UserInfo.getProfileId());
         Account ac1 = new Account(); 
         ac1.OwnerId = u1.Id; 
         ac1.Name = 'test'; 
         ac1.ratings = 'started';
         insert ac1; 
         // Verify the "You cann't delete this record" error is thrown whenever an attemp is made to delete a Account

        Boolean errorThrown = false;
        try 
        {
            delete ac1;
        } 
        catch (Exception e) 
        {
            System.debug(e);
            if (e.getMessage().contains('You can\'t delete this record')) 
            {
                errorThrown = true;
            }
        }         
      }
   }
}

Let me know if this helps. 
Sourav PSourav P
Hi Avishek, Thanks a lot
Let me try this.
Sourav PSourav P
Thanks Avishek,It worked :)
Sourav PSourav P
But a small issue. Even they are not able to merge the accounts. So, is that possible to alter the code a bit that only for manual deletion it should work and not while merging ? Thanks