i wrote a function that whenever an account owner is changed, if there is an opportunity with a specific type, avoid changing it's owner. because it's not really possible, what i did is save the old owner of the opportunity, and after the update is done and the owner is changed, revert it back to the old owner.
That's the code, and it works perfectly fine (partial, not the entire class):
public class AccountTriggerHandler extends TriggerHandler {
protected override void beforeUpdate(){
avoidOpportunityOwnerChangeOnOwnerChangeBeforeUpdate();
}
protected override void afterUpdate(){
if(!beforeUpdateMap.isEmpty())
{
avoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate(testSetId,beforeUpdateMap);
}
}
static map<id,id> beforeUpdateMap;
public void avoidOpportunityOwnerChangeOnOwnerChangeBeforeUpdate()
{
System.debug('avoidOpportunityOwnerChangeOnOwnerChangeBeforeUpdate');
if(AccountTriggerHandler.isExecutingavoidOpportunityOwnerChangeOnOwnerChangeBeforeUpdate && !Test.isRunningTest() ){
return;
}
AccountTriggerHandler.isExecutingavoidOpportunityOwnerChangeOnOwnerChangeBeforeUpdate = true;
List <Account> newAccountList = (List<Account>)Trigger.New;
Map <Id, Account> oldAccountMap = (Map <Id, Account>)Trigger.oldMap;
Set<Id> newAccSetId = new Set<Id>();
for( Account acc_i: newAccountList)
{
if(acc_i.OwnerId != oldAccountMap.get(acc_i.Id).OwnerId)
{
newAccSetId.add(acc_i.id);
}
}
list<Opportunity> opps = [Select id, accountid, isClosed, Type, ownerid, owner.name from Opportunity where accountid in :newAccSetId];
beforeUpdateMap=new map<id,id>();
for(Opportunity opp_i : opps){
System.debug('opp_i: ' + opp_i);
if(!opp_i.isClosed && opp_i.type == 'Renewal Business')
{
beforeUpdateMap.put(opp_i.Id,opp_i.ownerid);
}
}
System.debug('beforeUpdateMap after func avoidOpportunityOwnerChangeOnOwnerChangeBeforeUpdate: ' + beforeUpdateMap);
}
public static boolean isExecutingavoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate = false;
@future
public static void avoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate(Set<Id> newAccSetId,map<id,id> beforeUpdateMap)
{
System.debug('avoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate');
if(AccountTriggerHandler.isExecutingavoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate){
return;
}
AccountTriggerHandler.isExecutingavoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate = true;
list<Opportunity> updateOpps = new list<Opportunity>();
Set<Id> oppSetId = new Set<Id>();
oppSetId = beforeUpdateMap.keySet();
list<Opportunity> opps = [Select id, type, isClosed, accountid, ownerid, owner.name from Opportunity where id in:oppSetId];
for(Opportunity opp_i : opps){
id a = beforeUpdateMap.get(opp_i.Id);
opp_i.OwnerId = a;
updateOpps.add(opp_i);
}
system.debug('opps to revert owner after account owner change: ' + updateOpps);
if(!updateOpps.isEmpty())
{
update updateOpps;
}
}
}
now, i wanted to write a test class for it. notice there is a future method called "avoidOpportunityOwnerChangeOnOwnerChangeAfterUpdate". it should retrieve the old owner.
that's the test i wrote: (UPDATED AFTER YOUR SUGGESTIONS)
@isTest private static void testavoidOpportunityOwnerChangeOnOwnerChange()
{
Account accountTest = TestUtil.getAccountByName('AccountTestAvoid');
insert accountTest;
Opportunity testOpp = TestUtil.getOpportunityByNameAndStage('TestOne', 'Customer Confirmed Quote', accountTest.id);
testOpp.type = 'Renewal Business';
insert testOpp;
Account acc = [SELECT Id, Name,OwnerID from Account Where name = 'AccountTestAvoid' limit 1];
Opportunity opp = [SELECT id,name,ownerId from opportunity limit 1];
Profile p = [SELECT Id FROM Profile where name ='system administrator' limit 1];
User usr = TestUtil.getUserByNameAndProfileId('test',p.Id);
insert usr ;
accountTest.ownerId = usr.id;
Test.startTest();
update accountTest;
Test.stopTest();
Account accRes = [SELECT Id, Name,OwnerID from Account Where name = 'AccountTestAvoid' limit 1];
Opportunity oppRes = [SELECT id,name,ownerId from opportunity limit 1];
System.debug('accRes.OwnerId: ' + accRes.OwnerId);
System.debug('acc.OwnerId: ' + acc.OwnerId);
System.debug('oppRes.OwnerId: ' + oppRes.OwnerId);
System.debug('opp.OwnerId: ' + opp.OwnerId);
System.AssertNotEquals(accRes.OwnerId,acc.OwnerId);
System.AssertNotEquals(oppRes.OwnerId,opp.OwnerId);
}
The second assert fails, and seems like the opportunity owner is not changed at all. in the UI - When the account records transferred to another user, the associated open opportunities automatically transferred to the new account owner without firing the opportunity trigger.
(Whenever an account owner is changed, all the opportunities owners are changed to the same one, didnt happen here)
how can i simulate the same process in a test class?