I came up with a solution using the Account Trigger before and after updates.
Here is the helper Class handling the logic:
It basically will revert the Opportunity's owner back to the old owner, for any Closed Opportunities caught up in the owner transfer.
public with sharing class blogicAccount {
static map<id,id> beforeUpdateMap;
public static void handleBeforeUpdate( list<Account> newAccounts){
set<id> actIds = new set<id>();
for(Account a : newAccounts){
actIds.add(a.id);
}
list<Opportunity> opps = [Select id, accountid, ownerid, owner.name from Opportunity where accountid in :actids];
beforeUpdateMap=new map<id,id>();
for(Opportunity o : opps){
system.debug('***Opp owner on Account beforeUpdate:'+o.owner.name);
beforeUpdateMap.put(o.accountid,o.ownerid);
}
}
public static void handleAfterUpdate( list<Account> newAccounts){
set<id> actIds = new set<id>();
for(Account a : newAccounts){
actIds.add(a.id);
}
list<Opportunity> updateOpps = new list<Opportunity>();
list<Opportunity> opps = [Select id, isClosed, accountid, ownerid, owner.name from Opportunity where accountid in :actids];
for(Opportunity o : opps){
system.debug('***Opp old owner: '+beforeUpdateMap.get(o.accountid));
system.debug('***Opp owner on Account AfterUpdate:'+o.ownerid);
if(o.isClosed && o.ownerid != beforeUpdateMap.get(o.accountid) ){
o.ownerid=beforeUpdateMap.get(o.accountid);
updateOpps.add(o);
}
}
//SET A TRIGGER FLAG to prevent ANY and ALL triggers from firing on the Opportunity Update
//id triggerFlags.ByPassOpptyTrigger=True
// and in the Opportunity Trigger, always check this flag.
update updateOpps;
}
}