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
DustinLHDustinLH 

User Lookup Owner Change Trigger Modification

I have the following trigger that takes the user that is in the Assigned field and makes them the record owner once the record is created. Also, if the owner is changed on the record, it will update the Assigned field. This is working perfectly for me, but I am having an issue with code coverage for my other triggers, etc. 

 

I would like to tweek the trigger to say that if the Assigend field is blank, then make the record owner the current user (i.e. normal behavior) and populate the Assigned field with the current user (or maybe it would be easier to populate the Assigned field with the current user so that it assigns ownership that way). This way, I will not get all of these exceptions thrown. I still want the 2nd part of the trigger to work (when owner is changed update the Assigned). 

 

Can someone please help me tweek this trigger?

 

trigger ReferralAssignOwner on Referral__c(before insert, before update) {
  for(Referral__c r:Trigger.new)                                         // For each record
    if(Trigger.isInsert)                                                 // If we're inserting
      r.OwnerId = r.Assigned__c;                                         // Assign ownership from Assigned__c
    else                                                                 // Otherwise (an update)
      if(r.OwnerId != Trigger.oldMap.get(r.id).OwnerId)                  // If ownership has changed
        r.Assigned__c = r.OwnerId;                                       // Place the new owner in Assigned__c
      else                                                               // Otherwise (owner not changed, is an update)
        if(r.Assigned__c != Trigger.oldMap.get(r.id).Assigned__c)        // If the Assigned__c field changed
          r.OwnerId = r.Assigned__c;                                     // Assigned ownership from Assigned__c
}

 

Best Answer chosen by Admin (Salesforce Developers) 
Nisse Knudsen.ax1026Nisse Knudsen.ax1026

You actually need to delete the whole if-statement including the curly brackets:

 

trigger ReferralAssignOwner on Referral__c(before insert, before update) {
	
	if(Trigger.isBefore) {
	
		if(Trigger.isInsert) {
			
			for(Referral__c r: Trigger.New) {
			
				if(r.Assigned__c == null) {
				
					r.Assigned__c = UserInfo.getUserId();	
				}
					
				r.OwnerId = r.Assigned__c;		
				
			}
			
		}
		else if(Trigger.isUpdate) {
			
			for(Referral__c r: Trigger.New) {
			
				if(r.OwnerId != Trigger.oldMap.get(r.id).OwnerId) {
					
					r.Assigned__c = r.OwnerId;
						
				}
				else if(r.Assigned__c != Trigger.oldMap.get(r.id).Assigned__c) {
					
					if(r.Assigned__c == null) { // If the Assignee had been changed to NULL 
						r.Assigned__c = UserInfo.getUserId();	
					}
					
					r.OwnerId = r.Assigned__c;
				}
				
			}
			
		}
		
	}
	
	
	
}

 

All Answers

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

Firs try to invert the if(Trigger.isInsert) and the for-loop, since Trigger.isInsert will stay the same. Now you have n conditional checks, instead of 1.

 

I assume that Assigned is a lookup to the user object. If it might be a text field, you have to compare to empty string instead of null:

 

trigger ReferralAssignOwner on Referral__c(before insert, before update) {
	
	if(Trigger.isBefore) {
	
		if(Trigger.isInsert) {
			
			for(Referral__c r: Trigger.New) {
			
				if(r.Assigned__c == null) {
				
					r.Assigned__c = UserInfo.getUserId();	
				}
					
				r.OwnerId = r.Assigned__c;		
				
			}
			
		}
		else if(Trigger.isUpdate) {
			
			for(Referral__c r: Trigger.New) {
			
				if(r.OwnerId != Trigger.oldMap.get(r.id).OwnerId) {
					
					if(r.OwnerId == null) { // If the Owner had been changed to NULL 
						r.OwnerId = UserInfo.getUserId();	
					}
					
					r.Assigned__c = r.OwnerId;
						
				}
				else if(r.Assigned__c != Trigger.oldMap.get(r.id).Assigned__c) {
					
					if(r.Assigned__c == null) { // If the Assignee had been changed to NULL 
						r.Assigned__c = UserInfo.getUserId();	
					}
					
					r.OwnerId = r.Assigned__c;
				}
				
			}
			
		}
		
	}
	
	
	
}

 

DustinLHDustinLH

You are correct, the Assigned field is a user lookup field. That trigger works great! But now the test code that we just worked on has less coverage (I am assuming it is because it does not test for a blank Assigned field). Can you please take another look at the test class that we worked on? Here it is:

 

@isTest
private class testReferralAssignOwner {
  static testMethod void test() {
    List<User> testUsers = [select id from user where isactive = true limit 2];
    
    Account a = new Account(Name='test');
    insert a;
    
    List<Referral__c> refs = new List<Referral__c>();
    refs.add(new Referral__c(Client_Name__c=a.id,Phone__c='12345',Assigned__c=testUsers[0].Id));
    refs.add(new Referral__c(Client_Name__c=a.id,Phone__c='12345',Assigned__c=testUsers[1].Id));
    insert refs;

    Map<Id, Referral__c> refMap = new Map<Id, Referral__c>([SELECT Id, Assigned__c, OwnerId FROM Referral__c WHERE Id IN :refs]);

    system.assertEquals(refMap.get(refs[0].Id).OwnerId,testUsers[0].Id); // OwnerId should equal Assigned__c;
    system.assertEquals(refMap.get(refs[1].Id).OwnerId,testUsers[1].Id); // OwnerId should equal Assigned__c;
    refs[0].OwnerId = testUsers[1].Id;
    refs[1].Assigned__c = testUsers[0].Id;
    update refs;
    
    Map<Id, Referral__c> refMap2 = new Map<Id, Referral__c>([SELECT Id, Assigned__c, OwnerId FROM Referral__c WHERE Id IN :refs]);
    
    system.assertEquals(refMap2.get(refs[0].Id).Assigned__c,testUsers[1].Id); // Assigned__c should equal OwnerId now
    system.assertEquals(refMap2.get(refs[1].Id).OwnerId,testUsers[0].Id); // OwnerId should equal Assigned__c now
  }  
}

 

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

If you execute the test method/class you see somewhere at the top of the result page a code coverage percentage. That is a link! If you click on it, there will pop a window open where you see the tested code lines in purple, the non-tested lines in red.

 

By that you can determine which test cases you are missing. As far as I can see, you still need to test the cases where before an insert and update the Assigned__c/OwnerId fields are set to NULL.

DustinLHDustinLH

Awesome! That helps. Can you do me 1 more favor though and update the trigger to not look for OwnerID = NULL? The Owner ID of a record can never be NULL, so I cannot write a test class that makes the Owner ID null to test that part of the trigger... I tried just erasing that chunk, but it doesn't seem to work. 

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

You actually need to delete the whole if-statement including the curly brackets:

 

trigger ReferralAssignOwner on Referral__c(before insert, before update) {
	
	if(Trigger.isBefore) {
	
		if(Trigger.isInsert) {
			
			for(Referral__c r: Trigger.New) {
			
				if(r.Assigned__c == null) {
				
					r.Assigned__c = UserInfo.getUserId();	
				}
					
				r.OwnerId = r.Assigned__c;		
				
			}
			
		}
		else if(Trigger.isUpdate) {
			
			for(Referral__c r: Trigger.New) {
			
				if(r.OwnerId != Trigger.oldMap.get(r.id).OwnerId) {
					
					r.Assigned__c = r.OwnerId;
						
				}
				else if(r.Assigned__c != Trigger.oldMap.get(r.id).Assigned__c) {
					
					if(r.Assigned__c == null) { // If the Assignee had been changed to NULL 
						r.Assigned__c = UserInfo.getUserId();	
					}
					
					r.OwnerId = r.Assigned__c;
				}
				
			}
			
		}
		
	}
	
	
	
}

 

This was selected as the best answer
DustinLHDustinLH

Nisse,

 

This works perfectly! And I got my code coverage where I need it! Thank you again for all of your help! 

 

I just discovered that when creating a new record, using this new trigger and Assigned field, once the record is saved and the owner is assigned, the creator is not following the record in Chatter. This is odd to me since it still shows me as the records creator, but the only person following the record is the new owner. Do you know if there is any way around this? Or should I post that as a separate question to the forum?

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

Glad to hear that!

 

So if any of the responses answered your question, you can mark is as the answer and your post gets the flag that your issue has been solved.

DustinLHDustinLH

Do you have any suggestions about the Chatter issue I mentioned?

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

Haven't seen your post, as I was typing my answer while you posted it :)

 

Here is the link to the API documentation: EntitySubscription object

 

As you can see this is a linker object between a ParentId (which would be the Referral-Id) and a SubscriberID (which would be the Owner/Assignee-Id).

 

You have to create a new instance of that object, set the values and insert them. You have to consider, if you want former Owners of the object to be still as a follower on chatter. If not you need to query those EntitiySubscription records and delete them from the DB.

DustinLHDustinLH

Awesome! Thanks for the info. I ended up writing this small trigger which seems to fix my problem:

trigger ReferralChatterFollow on Referral__c (after insert) {

    for(Referral__c r: Trigger.New) {
                    EntitySubscription follow = new EntitySubscription (
                        parentId = r.id,
                        subscriberId = UserInfo.getUserId());
                    insert follow;
    }
}

 

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

Is this exactly what you wanted? I am not sure, but your main follower field is the owner, isn't it?

 

You didn't want to add the current user, but the new Owner of the Record, right?

 

so replace

 

subscriberId = r.OwnerId

 

 

 

DustinLHDustinLH

No, the owner of the record is automatically following the record, so that is fine. I want the person who created the record to also follow it, but when I tried r.createdby it wont accept that since it is "expecting an ID". So, instead of r.createdby I chose the current user, since the current user should be the creator anyways...

Nisse Knudsen.ax1026Nisse Knudsen.ax1026

Then make use of the field

 

r.CreatedById

 

 

DustinLHDustinLH

Perfect! I made that change, thanks!