+ Start a Discussion
Tecnova AdminTecnova Admin 

Trigger For Account Owner Update !

Hi,
 I am in a situation where I would like to create a trigger to update account owner. As I am new to triggers I do not have any experience on working with triggers.

My partner portal users requests me a lot through emails to change account owner from admin to their name.

To solve this issue, I created a custom checkbox field called Record_Transfer_Record__c

So now I want to create a trigger if current account owner is Admin and current user has checked the custom checkbox Record_Transfer_Record__c then after he hit the save button then Account Owner get changed from Admin to current user who is checking the checkbox.
I tried this code but hard luck no success :(

trigger AccountOwnerChange on Account (before update)
         {
          if(trigger.isBefore && Trigger.isUpdate)
        {
            for(Account obj: trigger.new)
            {
                if(obj.ownerId = '00590000001OizE')
                {
                 if(obj.Record_Transfer_Request__c == True)
                 
                Account a = [SELECT id, OwnerId FROM Account WHERE id =: Trigger.old[0].Id];
                
                  Trigger.new[0].OwnerId = UserInfo.getUserId();
                   {
                                    


                    
    }            
   }
   }
   }
   }
Please help ..........

 
Best Answer chosen by Tecnova Admin
goabhigogoabhigo
I think you are brand new to Salesforce. What you have posted is basically 3 things:
  1. Trigger
  2. Helper class
  3. Test class
This is the best way to write the code. However, in your case, since the trigger code is not very complex you can skip the helper class.

So you will have one trigger:
trigger AccountOwnerChange on Account (before update) {
     Id adminId = [Select Id from User where UserName = 'yourAdminusername'].Id;
     for(Account acc : Trigger.New) {
          if(acc.Record_Transfer_Request__c == True && Trigger.oldMap.get(acc.Id).Record_Transfer_Request__c == False && acc.OwnerId == adminId) {
              acc.OwnerId = UserInfo.getUserId();
           }
      }
}

......... and a test class to test this(cover this):
@IsTest public class TestAccountOwnerChange {
     public static testmethod AccountAownerChange() {
          Account testAccount = new Account( Name = 'Test Account' );
          insert testAccount;
          Account insertedAccount = [Select Name from Account where Id =: testAccount.Id];
          System.assertEquals('Test Account', insertedAccount); 
          testAccount.Record_Transfer_Request__c = True;
          update testAccount;
          Account updatedAccount = [Select Record_Transfer_Request__c from Account where Id =: testAccount.Id];
          System.assertEquals(True, updatedAccount.Record_Transfer_Request__c);
    }
}

Not a best test class. But this is what I can do to give you an idea.

I strongly recommend you to go through these once - you will be a very strong developer ;)
https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

https://developer.salesforce.com/page/How_to_Write_Good_Unit_Tests

Does these help? Let me know.

--
Abhi

All Answers

ra811.3921220580267847E12ra811.3921220580267847E12
Hi,

trigger AccountbeforeUpdateDemo on Account ( before update) {

   Set<Id> accountIds = new Set<Id>();
   Set<Id> accountOwnerIds = new Set<Id>(); 

   
   for(Account acc:trigger.new)
   {
   if(acc.Record_Transfer_Record__c ==true)
   {
   accountOwnerIds.add(acc.ownerID);
   }
   }
   
   if(accountOwnerIds.isEmpty())
   return;
   
   
   List<User> usr1=[select Profile.name from User where Id IN :accountOwnerIds];
   
   if(usr1.isEmpty())
   return;
   
   if(usr1[0].profile.Name =='systemAdministrator')
   
   {
   
   for(Account acc:trigger.new)
   {
   acc.ownerid=UserInfo.getUserId();
   }
   }
   
   }
   
goabhigogoabhigo
Ahh..

First, before writing please go through this - Apex Code Best Practices (https://developer.salesforce.com/page/Apex_Code_Best_Practices)

Following are the issues I can see in your code:
  1. SOQL is inside for loop
  2. Inside if, to check you need to use '==' not '='
  3. You have hard coded the Id of Admin
Here is what I would write:
trigger AccountOwnerChange on Account (before update) {
     Id adminId = [Select Id from User where UserName = 'yourAdminusername'].Id;
     for(Account acc : Trigger.New) {
          if(acc.Record_Transfer_Request__c == True && Trigger.oldMap.get(acc.Id).Record_Transfer_Request__c == False && acc.OwnerId == adminId) {
              acc.OwnerId = UserInfo.getUserId();
           }
      }
}
Assuming that there is only one System Admin with username yourAdminusername (you will have to override accordingly).

Does this help?

--
Abhi
 
goabhigogoabhigo
Also, note that this line - acc.OwnerId = UserInfo.getUserId();, will update the owner ID as current logged user who is updating the checkbox. So ideally, you would need to check if the current logged in user who is changing this field is Partner Portal user.
UserInfo object (http://www.salesforce.com/us/developer/docs/dbcom_apex230/Content/apex_methods_system_userinfo.htm) has enough info to check this.
 
goabhigogoabhigo
Was this helpful? Do you need help? Let me know.
Tecnova AdminTecnova Admin
Hi Abhi / rba811.3921220580267847E12,
Thank You guys for prompt help.

 I don't know why I am facing an Invalid Field error in both of the codes. This is the reason for frustration and due to this I was messed up with code earlier and tried all here and there methods in my code.

@Abhi: Error: Compile Error: Invalid field Record_Transfer_Request__c for SObject Account at line 4 column 17
@rba811.3921220580267847E12: Error: Compile Error: Invalid field Record_Transfer_Record__c for SObject Account at line 9 column 7

Also attached is the Enterprise WSDL I have double checked the custom field. Still getting the error.WSDL Image highlighting custom field
goabhigogoabhigo
Can you please check the FLS of this field?
In Setup, click on the field - then click on Set Field-Level Security button. Check if the profiles have read/edit permission.
Tecnova AdminTecnova Admin
Hey Abhi,

  I just realised that this custom field is not available under custom fields in Sandbox. Because I have created this in production org. Now what ?
goabhigogoabhigo
Ohho :)
Just create that field in Sandbox. That's all. Then write the code, then save. You SHOULD NOPT get that error.
Tecnova AdminTecnova Admin
Hey I have just refreshed my sandbox. I think that will do the copy from production to sandbox.
What do you say ?
goabhigogoabhigo
That should do. Please check the fields under Account. If its present, then its all good.
BTW, sandbox refresh takes time. So wait for completion email OR check the progress in Production. You will see this field only after the refresh is complete.
Tecnova AdminTecnova Admin
Hi Abhi,

  I have saved the apex. Now stuck at class, how to test it ?
goabhigogoabhigo
What have you written? Pls paste the code.
Tecnova AdminTecnova Admin
private with sharing class AccountOwnerChange {    

    public static void onBeforeUpdate(List<Account> accounts) { }
 
}

trigger AccountTrigger on Account (before update) {
if(Trigger.isUpdate)
        Accounts.onBeforeUpdate(Trigger.new);
        }

@IsTest
private with sharing class AccountOwnerChange {

private static testmethod AccountAownerChange()
{
Account testAccount = new Account( Name = 'Test Account' );
            insert testAccount;
            testAccount = [select Id, Name from Account where Id = :testAccount.Id];
            testAccount.Record_Transfer_Request__c = 'true';
            System.assertEquals(testAccount.Name, 'Test Account');  
            
            update testAccount;
    }
        }
            }

I AM CONFUSED IN HOW TO CHECK UPDATE IS WORKING OR NOT
goabhigogoabhigo
I can see multiple issues:
  1. What is inside onBeforeUpdate(List<Account> accounts) method? I assume its the same code I mentioned in above post
  2. testAccount.Record_Transfer_Request__c = 'true'; should be like this - testAccount.Record_Transfer_Request__c = True;
Now run the test class, check for the coverage.
Tecnova AdminTecnova Admin
See I have modified the code in some other workaround and I am getting this error
Error: Compile Error: unexpected token: trigger at line 7 column 0

Code :

public with sharing class AccountOwnerChange {    

    public static void onBeforeUpdate(List<Account> accounts) { }
 
}

trigger AccountOwnerChange on Account (before update) {
if(Trigger.isUpdate)
        Accounts.onBeforeUpdate(Trigger.new);
        }

@IsTest
private with sharing class AccountOwnerChange {

private static testmethod AccountAownerChange()
{
Account testAccount = new Account( Name = 'Test Account' );
            insert testAccount;
            testAccount = [select Id, Name from Account where Id = :testAccount.Id];
            
            System.assertEquals(testAccount.Name, 'Test Account');  
            
            update testAccount;
            Account updatedAccount = [SELECT billingState FROM Account WHERE Id = :testAccount.Id];
            System.assertEquals('True', updatedAccount.Record_Transfer_Request__c);
            
    }
        }
            }
Tecnova AdminTecnova Admin
@IsTest
private with sharing class AccountOwnerChange {

 Private static testmethod void AccountAownerChange()
{
Account testAccount = new Account( Name = 'Test Account' );
            insert testAccount;
            testAccount = [select Id, Name from Account where Id = :testAccount.Id];
            testAccount.Record_Transfer_Request__c = True;
            System.assertEquals(testAccount.Name, 'Test Account');  
            
            update testAccount;
    }
        }

This Test Class saved now let me try a Test Run
goabhigogoabhigo
I think you are brand new to Salesforce. What you have posted is basically 3 things:
  1. Trigger
  2. Helper class
  3. Test class
This is the best way to write the code. However, in your case, since the trigger code is not very complex you can skip the helper class.

So you will have one trigger:
trigger AccountOwnerChange on Account (before update) {
     Id adminId = [Select Id from User where UserName = 'yourAdminusername'].Id;
     for(Account acc : Trigger.New) {
          if(acc.Record_Transfer_Request__c == True && Trigger.oldMap.get(acc.Id).Record_Transfer_Request__c == False && acc.OwnerId == adminId) {
              acc.OwnerId = UserInfo.getUserId();
           }
      }
}

......... and a test class to test this(cover this):
@IsTest public class TestAccountOwnerChange {
     public static testmethod AccountAownerChange() {
          Account testAccount = new Account( Name = 'Test Account' );
          insert testAccount;
          Account insertedAccount = [Select Name from Account where Id =: testAccount.Id];
          System.assertEquals('Test Account', insertedAccount); 
          testAccount.Record_Transfer_Request__c = True;
          update testAccount;
          Account updatedAccount = [Select Record_Transfer_Request__c from Account where Id =: testAccount.Id];
          System.assertEquals(True, updatedAccount.Record_Transfer_Request__c);
    }
}

Not a best test class. But this is what I can do to give you an idea.

I strongly recommend you to go through these once - you will be a very strong developer ;)
https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

https://developer.salesforce.com/page/How_to_Write_Good_Unit_Tests

Does these help? Let me know.

--
Abhi
This was selected as the best answer
Tecnova AdminTecnova Admin
I have already tried the class which you have mentioned and this gives me the error.
Error: Compile Error: Comparison arguments must be compatible types: String, Account at line 6 column 13

And I really do not know how to fix it.
goabhigogoabhigo
Sorry, my bad.
Change it to:
System.assertEquals('Test Account', insertedAccount.Name);
Tecnova AdminTecnova Admin
Yes I omitted that, and now Test Run fails with this error

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AccountOwnerChange: execution of BeforeUpdate

caused by: System.QueryException: List has no rows for assignment to SObject

Trigger.AccountOwnerChange: line 2, column 1: []
goabhigogoabhigo
You were supposed to change this code as per your Sysem Admin's username:
 
Id adminId = [Select Id from User where UserName = 'yourAdminusername'].Id;

yourAdminusername should be replaced as per your org's username.
 
Tecnova AdminTecnova Admin
Trigger is not working as expected. :(
goabhigogoabhigo
What's the system admin's username? Change it in the trigger code, as mentioned above. It will work :)
Tecnova AdminTecnova Admin
Hey Abhi,

 A big thanks to you for your all support !
I have accomplished the task by making some ammendments in Test Class and Trigger.

Thanks to both of you guys.

goabhigo & rba811.3921220580267847E12
goabhigogoabhigo
Glad that it was helpful.