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
SFDCDevQASFDCDevQA 

Exception on Trigger for System Admin Profile

My current trigger checks the opportunity probability percentage and denies deletion based on probability.  We want to add an exception that if the profile of the user trying to delete is the System Admin then it would not cause the trigger to fire.  Can someone please help me with what I would need to add that exception into my code?  I found one other question/answer from years ago on the topic but the answer didn't make sense to me so I wasn't sure if it was written for an s-control or something.

 

trigger CannontDeleteOpportunity95 on Opportunity (before delete) {
 if(System.Trigger.IsDelete)
        {
        for (Opportunity Opps : trigger.old)
            if (Opps.Probability >= 95)
          
                {
                Opps.addError('Error: You cannot delete this Opportunity.  Please contact a system Administrator for assistance');
                }
        }          
}

 

Thanks,

Amanda

Best Answer chosen by Admin (Salesforce Developers) 
Alex.AcostaAlex.Acosta

I'm guessing the UserInfo class will bring back the 18 digit id for profiles while you're providing the 15 digit Id.

 

Try this then...

 

trigger CannontDeleteOpportunity95 on Opportunity (before delete) {
 if(System.Trigger.IsDelete && UserInfo.getProfileId().subString(0,15) != '00e600000013jtd')
        {
        for (Opportunity Opps : trigger.old)
            if (Opps.Probability >= 95)
          
                {
                Opps.addError('Error: You cannot delete this Opportunity.  Please contact a system Administrator for assistance');
                }
        }          
}

 

 

Otherwise if you want to make this work on both sandbox and production servers, try this....

trigger CannontDeleteOpportunity95 on Opportunity (before delete) {

Profile adminId = [SELECT Id from Profile where Name='System Administrator' LIMIT 1];
if(System.Trigger.IsDelete && UserInfo.getProfileId() != adminId.Id) { for (Opportunity Opps : trigger.old) if (Opps.Probability >= 95) { Opps.addError('Error: You cannot delete this Opportunity. Please contact a system Administrator for assistance'); } } }

All Answers

Alex.AcostaAlex.Acosta

Easiest way to do this if you have a single system admin profile is to hard-coded it. Personally I'm a fan of making things dynamic, but this should suffice.

trigger CannontDeleteOpportunity95 on Opportunity (before delete) {
 if(System.Trigger.IsDelete && UserInfo.getProfileId() != '<SystemAdminProfileId>')
        {
        for (Opportunity Opps : trigger.old)
            if (Opps.Probability >= 95)
          
                {
                Opps.addError('Error: You cannot delete this Opportunity.  Please contact a system Administrator for assistance');
                }
        }          
}

 

SFDCDevQASFDCDevQA

I've tried this using

&& UserInfo.getProfileId() != '00e600000013jtd'

and

&& UserInfo.getProfileId() != <'00e600000013jtd'>

 

And both ways it continues to block all users, including system admin, from deleting the opportunity.  What am I doing wrong?  00e600000013jtd is the System Admin profile ID in the sandbox and I'm testing in the sandbox.

 

Thanks,

Amanda

SFDCDevQASFDCDevQA

Any ideas on why it is blocking deletion no matter who you are?  Does it need a longer ID string for the profile or something?

 

Thanks so much,

Amanda

Alex.AcostaAlex.Acosta

I'm guessing the UserInfo class will bring back the 18 digit id for profiles while you're providing the 15 digit Id.

 

Try this then...

 

trigger CannontDeleteOpportunity95 on Opportunity (before delete) {
 if(System.Trigger.IsDelete && UserInfo.getProfileId().subString(0,15) != '00e600000013jtd')
        {
        for (Opportunity Opps : trigger.old)
            if (Opps.Probability >= 95)
          
                {
                Opps.addError('Error: You cannot delete this Opportunity.  Please contact a system Administrator for assistance');
                }
        }          
}

 

 

Otherwise if you want to make this work on both sandbox and production servers, try this....

trigger CannontDeleteOpportunity95 on Opportunity (before delete) {

Profile adminId = [SELECT Id from Profile where Name='System Administrator' LIMIT 1];
if(System.Trigger.IsDelete && UserInfo.getProfileId() != adminId.Id) { for (Opportunity Opps : trigger.old) if (Opps.Probability >= 95) { Opps.addError('Error: You cannot delete this Opportunity. Please contact a system Administrator for assistance'); } } }
This was selected as the best answer
SFDCDevQASFDCDevQA

You are awesome! 

Thanks,

Amanda

SFDCDevQASFDCDevQA

I'm trying to create a test class for this and am hitting some errors.  Here's the test class I've tried to make.  I did not include the user info at first but then my code coverage said it was like 20% so I added in user info and that is when the errors started.  it says currently "Error: Compile Error: Only top-level class variables can be declared static at line 27 column 28"

 

@IsTest
private class CannontDeleteOpportunity95
{
    static testMethod void testDelete()
    {
         Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule',Probability=0.95);
        insert o;
        
            //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
      User u = new User(Alias = 'systad', Email='systemadminuser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='systemadminuser@testorg.com');


      System.runAs(u) {
      // The following code runs as user 'u'  
      
           delete o;
        }

    static testMethod void testDeleteFail()
    {
            Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule', Probability=0.95);
        insert o;
        
  //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
      User u1 = new User(Alias = 'standa', Email='standarduser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');


      System.runAs(u) {
      // The following code runs as user 'u1'  
      
           try
           {
              delete o;
              // should throw an exception - the following assertion will cause an error if the code carries on
              System.assert(false);
           }
           catch (DMLException e)
           {
               // expected - could assert the message here
           }
        }
}

Alex.AcostaAlex.Acosta

You are missing a curly bracket, I've added the correction it to your test class in red.

 

@IsTest
private class CannontDeleteOpportunity95
{
    static testMethod void testDelete()
    {
         Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule',Probability=0.95);
        insert o;
        
            //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
      User u = new User(Alias = 'systad', Email='systemadminuser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='systemadminuser@testorg.com');


      System.runAs(u) {
      // The following code runs as user 'u'  
      
           delete o;
        }
    } // <-- Here's the missing bracket
    static testMethod void testDeleteFail()
    {
            Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule', Probability=0.95);
        insert o;
        
  //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
      User u1 = new User(Alias = 'standa', Email='standarduser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg.com');


      System.runAs(u) {
      // The following code runs as user 'u1'  
      
           try
           {
              delete o;
              // should throw an exception - the following assertion will cause an error if the code carries on
              System.assert(false);
           }
           catch (DMLException e)
           {
               // expected - could assert the message here
           }
        }
}

 

SFDCDevQASFDCDevQA

That figures.  I swear I looked at all those stupid parenthesis and brackets until I was crosseyed.  It's still only giving me 25% test coverage for my trigger.  I'm fairly new to triggers and test classes and I just don't understand what I'm doing wrong.  I have a test account and opportunity created and it tests deleting as a standard user and a system admin.  I don't understand what else it wants me to test.
Can you help me understand why it's not covering the trigger?

 

Thanks,

Amanda

SFDCDevQASFDCDevQA

I'm going through all these trigger and test class examples trying to figure out how this stuff fits together and I'm just spinning and spinning.  I don't understand why I can't just test the trigger myself.  Why do I have to create a test class with completely different verbage that is 10 times longer than the actual trigger!

I've tried changing the first test to the standard user with the probability lower and that just makes the whole thing fail.  I've tried adding additional code for the error at the end and that's not working.  This is what I have at this point with my additional changes but it still says that it is only testing the 1st line of the trigger.

 

@IsTest
private class CannontDeleteOpportunity95
{
    static testMethod void testDelete()
    {
         Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule',Probability=0.95);
        insert o;
        
            //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
      User u = new User(Alias = 'system', Email='saplingsystemuser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='saplingsystemuser@testorg.com');


      System.runAs(u) {
      // The following code runs as user 'u'  
      
           delete o;
        }
    }
    static testMethod void testDeleteFail()
    {
            Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule', Probability=0.95);
        insert o;
        
  //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
      User u1 = new User(Alias = 'standa', Email='saplingstandarduser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='saplingstandarduser@testorg.com');


      System.runAs(u1) {
      // The following code runs as user 'u1'  
      
           try
           {
              delete o;
              // should throw an exception - the following assertion will cause an error if the code carries on
           }
           catch (Exception e)
           {
           system.debug('Error:'+e);


               // expected - could assert the message here
               
           
           
        }}
}
Alex.AcostaAlex.Acosta

Keep in mind, reason why test cases can be longer than code logic is because there can be many senarios, and as good practice you want to cover them all. Also confirm that your test methods are not failing...

 

 

Best way to find out what code did not get covered is by looking at your results....

 

Once you run your tests, you click on the percent of code coverage it tells you hit....

 

When you click on this number, it will show you what was covered and what was not as shown below.

Red means not covered and blue means covered.

 

SFDCDevQASFDCDevQA

I did that.  That's why I said it says that it is only covering the first line of the trigger.  And I'm not getting any Fails.  So of 4 lines, the first line is blue and the other 3 lines are red but I can't figure out why.  Do I have to cover every single probability percentage or something?  And I have code at the end that I thought was covering the error part but it says that isn't covered either.   The only thing that seems to be getting covered is the fact that the System Admin can delete.

 

Alex.AcostaAlex.Acosta

That is pretty strange. I uploaded this into a sandbox of mine and I'm having the same issue, but when I run the test case in eclipse i get 100% code coverage. I also added asserts to validate prior to running the logic. I would create a change set as though you're going to push it to prod and just validate it, don't deploy and see what results you get.

 

@IsTest
private class CannontDeleteOpportunity95
{
    static testMethod void testDelete()
    {
         Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule',Probability=0.95);
        insert o;
        
            //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator'];
      User u = new User(Alias = 'system', Email='saplingsystemuser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='saplingsystemuser@testorg.com');

test.starttest();
    
      System.runAs(u) {
      // The following code runs as user 'u'  
            system.assert(UserInfo.getProfileId().subString(0,15) == '00e600000013jtd');
           delete o;
        }
test.stoptest();
    } 


    static testMethod void testDeleteFail()
    {
            Account a=new Account(Name='Test Account');
           insert a;
           
           // create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule', Probability=0.95);
        insert o;
        
  //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
      User u1 = new User(Alias = 'standa', Email='saplingstandarduser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='saplingstandarduser@testorg.com');

test.starttest();
      System.runAs(u1) {
      // The following code runs as user 'u1'  
      system.assert(UserInfo.getProfileId().subString(0,15) != '00e600000013jtd');
           try
           {
              delete o;
              // should throw an exception - the following assertion will cause an error if the code carries on
           }
           catch (Exception e)
           {
           system.debug('Error:'+e);

} 
               // expected - could assert the message here
               
           
           
        }
  test.stopTest();
      }
}

 

Alex.AcostaAlex.Acosta

Well digging into this more... on the screen where you see your test case results... download your debug log and search for 'Error:'

 

I'm pretty sure something is failing but since you have your try catch, you are just not seeing a failed test case.

SFDCDevQASFDCDevQA

This is the error being throw, I guess.  I wasn't sure where to start and stop copying since it's one big page of stuff so I just grabbed a little before the error and some after the error.

 

EXCEPTION_THROWN|[49]|System.DmlException: Delete failed. First exception on row 0 with id 006g0000001sCZNAA2; first error: INSUFFICIENT_ACCESS_OR_READONLY, insufficient access rights on object id: []
13:26:54.364 (1364372000)|USER_DEBUG|[54]|DEBUG|Error:System.DmlException: Delete failed. First exception on row 0 with id 006g0000001sCZNAA2; first error: INSUFFICIENT_ACCESS_OR_READONLY, insufficient access rights on object id: []
13:26:54.158 (1369767000)|

 

I also tried deploying this to production and got a failed error on another test class that is part of a package.  Not sure what that's about.

Alex.AcostaAlex.Acosta

The issue that's occuring is your none system admin is create an opportunity and someone lower on the totem pole is trying to access a record above their permissions.... what you'll need to do is set the opportunity owner to the person attempting to delete the opportunity, so they have access to it... try this:

 

static testMethod void testDeleteFail()
    {
            
        
  //create test user
            Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
      User u1 = new User(Alias = 'standa', Email='saplingstandarduser@testorg.com',
      EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
      LocaleSidKey='en_US', ProfileId = p.Id,
      TimeZoneSidKey='America/Los_Angeles', UserName='saplingstandarduser@testorg.com');

test.starttest();
      System.runAs(u1) {
      // The following code runs as user 'u1'  
      system.assert(UserInfo.getProfileId().subString(0,15) != '00e600000013jtd');
           try
           {
Account a=new Account(Name='Test Account');
           insert a;
// create test opportunity
        Opportunity o = new Opportunity(Name='Test Opportunity',closedate=system.today(), stagename='Confirmed Teaching/Class Schedule', Probability=0.95, accountId = a.id);
        insert o;
              delete o;
              // should throw an exception - the following assertion will cause an error if the code carries on
           }
           catch (Exception e)
           {
           system.debug('Error:'+e);

} 
               // expected - could assert the message here
               
           
           
        }
  test.stopTest();
      }

 

Alex.AcostaAlex.Acosta

Just tested this logic and my test code coverage went up. Please make sure you have the latest example as I have corrected the prior post.

SFDCDevQASFDCDevQA

Ah, so create the user first, then the opportunity.  That gets me up to 75% and now it just says I don't have coverage for the error.  Just messed with the error stuff some more and changed the probability from 0.95 to 95.0 and it finally says 100%!!!!  (I hate how sometimes it wants you to give the percentage in decimal form and sometimes in full form).

Thank you so much!

Alex.AcostaAlex.Acosta

No problem. Now deploy that puppy and feel good about pushing your first piece of code into production ;D