+ Start a Discussion
Carrlos BoydCarrlos Boyd 

Urgent Trigger help: When record owner is changed, related record owner is changed

I have two custom objects. The first object, First_Object__c, has multiple related records from the second custom object, Second_Object__c. Only one Second_Object__c record can be in status "In Progress" at any given time. After the owner of the First_Object__c record is changed , I need the owner of the one Second_Object__c record that is currently in status "In Progress" to be immediately updated. This needs to happen whether the owner is previously a user or a queue.

Maybe here's a better way to put it:
IF record owner of First_Object__c is changed, THEN change record owner of related record of Second_Object__c to the same owner IF status is "In Progress".

I cannot use a Master/Detail relationship because I need the related records to be owned by different users and/or queues.
Best Answer chosen by Carrlos Boyd
Maharajan CMaharajan C
HI Carlos,

Sorry for the late reply.Yesterday its almost late night to me.

There is a some small changes. Please use the below code:

trigger OwnerChange on First_Object__c(after update) {
     
    Set<Id> ParentIds = new set<Id>();
    List<Second_Object__c> Childs = new List<Second_Object__c>();
    List<Second_Object__c> ChildstoUpdate = new List<Second_Object__c>();
    Map<Id,Id> newOwnerId = new Map<Id,Id>();
    for(First_Object__c a:trigger.new) 
    {
        First_Object__c  old = trigger.OldMap.get(a.Id);
        if(a.OwnerId != old.OwnerId)
        {
           ParentIds.add(a.Id);
            If(!newOwnerId.containsKey(a.Id))
            {
                newOwnerId.put(a.Id, a.OwnerId);
            }
        }
    }
    If(ParentIds.size() > 0)
    {
        Childs = [Select Id,First_Object__c from Second_Object__c where First_Object__c IN : ParentIds and Status__c = 'In Progress']; // use your Lookupfield Api Name insetad of ParId
    } 
    
    If(Childs.size() > 0)
    {
        for(Second_Object__c con : Childs)
        {
            Second_Object__c c = new Second_Object__c(Id = con.Id);
            c.ownerId = newOwnerId.get(con.First_Object__c);  // use your Lookupfield Api Name instead of ParId
            ChildstoUpdate.add(c);
        }
    }
    If(ChildstoUpdate.size() > 0)
    {
        Update ChildstoUpdate;
    }
}

Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Raj

All Answers

Maharajan CMaharajan C
Hi Carlos,

The Trigger have to be like below:

trigger OwnerChange on First_Object__c(after update) {
     
    Set<Id> ParentIds = new set<Id>();
    List<Second_Object__c> Childs = new List<Second_Object__c>();
    List<Second_Object__c> ChildstoUpdate = new List<Second_Object__c>();
    Map<Id,Id> newOwnerId = new Map<Id,Id>();
    for(First_Object__c a:trigger.new) 
    {
        if(a.OwnerId != trigger.oldmap.get(a.Id).OwnerId)
        {
           ParentIds.add(a.OwnerId);
            If(!newOwnerId.containsKey(a.Id))
            {
                newOwnerId.put(a.Id, a.OwnerId);
            }
        }
    }
    If(ParentIds.size() > 0)
    {
        Childs = [Select Id,ParId from Second_Object__c where ParId IN : ParentIds and Status = 'In Progress']; // use your Lookupfield Api Name insetad of ParId
    } 
    
    If(Childs.size() > 0)
    {
        for(Second_Object__c con : Childs)
        {
            Second_Object__c c = new Second_Object__c(Id = con.Id);
            c.ownerId = newOwnerId.get(con.ParId);  // use your Lookupfield Api Name insetad of ParId
            ChildstoUpdate.add(c);
        }
    }
    If(ChildstoUpdate.size() > 0)
    {
        Update ChildstoUpdate;
    }
}

Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Raj
Carrlos BoydCarrlos Boyd
I'm confused about what you mean by "use your Lookupfield Api Name instead of ParId".
Manoj DeshmukhManoj Deshmukh
Hi Carrlos,
Pleas try Below Trigger :
trigger Changeownertrigger on First_Object__c(after update) {
       
          Set<Id> FirstObjectIds = new Set<Id>();
          Map<Id, String> oldOwnerIds = new Map<Id, String>();
          Map<Id, String> newOwnerIds = new Map<Id, String>();
          Second_Object__c[] SecondObjectUpdates = new Second_Object__c[0];
          
          for (First_Object__c f : Trigger.new)
          {
             if (f.OwnerId != Trigger.oldMap.get(f.Id).OwnerId)
             {
                oldOwnerIds.put(f.Id, Trigger.oldMap.get(f.Id).OwnerId);
                newOwnerIds.put(f.Id, f.OwnerId);
                FirstObjectIds.add(f.Id);
             }

          }
            if (!FirstObjectIds.isEmpty()) {
             for (First_Object__c FrstObj : [SELECT Id, (SELECT Id, OwnerId FROM Second_Object__c) FROM First_Object__c WHERE Id in :FirstObjectIds])
                {
                String newOwnerId = newOwnerIds.get(FrstObj.Id);
                String oldOwnerId = oldOwnerIds.get(FrstObj.Id);
                for (Second_Object__c sec : FrstObj.Second_Object__c)
                {
                   if (sec.OwnerId == oldOwnerId) 
                   {
                   Second_Object__c updatedSecondObject = new Second_Object__c(OwnerId = newOwnerId, Id = sec.Id);
                   SecondObjectUpdates.add(updatedSecondObject);
                   }
                }
                 
                }
           }
                update SecondObjectUpdates;
    }

Please mark it as solved, it will help others
Thank you,
Manoj
Maharajan CMaharajan C
Sorry for the confusing its a Lookup field Api name in  Second_Object__c which connects Second_Object__c  to the First_Object__c.

You link the Second_Object__c to First_Object__c via Some Lookup field right here you have to use that Field API Name.

Is that understandable?
Manoj DeshmukhManoj Deshmukh
Hi Carrlos,
Please try Below Trigger :
trigger Changeownertrigger on First_Object__c(after update) {
       
          Set<Id> FirstObjectIds = new Set<Id>();
          Map<Id, String> oldOwnerIds = new Map<Id, String>();
          Map<Id, String> newOwnerIds = new Map<Id, String>();
          Second_Object__c[] SecondObjectUpdates = new Second_Object__c[0];
          
          for (First_Object__c f : Trigger.new)
          {
             if (f.OwnerId != Trigger.oldMap.get(f.Id).OwnerId)
             {
                oldOwnerIds.put(f.Id, Trigger.oldMap.get(f.Id).OwnerId);
                newOwnerIds.put(f.Id, f.OwnerId);
                FirstObjectIds.add(f.Id);
             }

          }
            if (!FirstObjectIds.isEmpty()) {
             for (First_Object__c FrstObj : [SELECT Id, (SELECT Id, OwnerId FROM Second_Object__c) FROM First_Object__c WHERE Id in :FirstObjectIds])
                {
                String newOwnerId = newOwnerIds.get(FrstObj.Id);
                String oldOwnerId = oldOwnerIds.get(FrstObj.Id);
                for (Second_Object__c sec : FrstObj.Second_Object__c)
                {
                   if (sec.OwnerId == oldOwnerId) 
                   {
                       if(sec.Status__c == 'In Progress')
                          {
                             Second_Object__c updatedSecondObject = new Second_Object__c(OwnerId = newOwnerId, Id = sec.Id);
                             SecondObjectUpdates.add(updatedSecondObject);
                          }
                   }
                }
                 
                }
           }
                update SecondObjectUpdates;
    }

Please mark it as solved, it will help others
Thank you,
Manoj
Carrlos BoydCarrlos Boyd
I use the same name as the first object name:

API Name: First_Object__c
Data Type: Lookup(First Object)
Carrlos BoydCarrlos Boyd
Manoj, I get an error message with your trigger:

Error: Compile Error: SELECT Id, (SELECT Id, OwnerId FROM Second_Object__c) FROM First_Object__c
^
ERROR at Row:1:Column:37 Didn't understand relationship 'Second_Object__c' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names. at line 19 column 49
Carrlos BoydCarrlos Boyd
Maharajan, I got it to save after I changed (Status = 'In Progress') to (Status__c = 'In Progress'). But when I changed the owner of the first object record, the second object record that is currently 'In Progress' remained the same.
Maharajan CMaharajan C
HI Carlos,

Sorry for the late reply.Yesterday its almost late night to me.

There is a some small changes. Please use the below code:

trigger OwnerChange on First_Object__c(after update) {
     
    Set<Id> ParentIds = new set<Id>();
    List<Second_Object__c> Childs = new List<Second_Object__c>();
    List<Second_Object__c> ChildstoUpdate = new List<Second_Object__c>();
    Map<Id,Id> newOwnerId = new Map<Id,Id>();
    for(First_Object__c a:trigger.new) 
    {
        First_Object__c  old = trigger.OldMap.get(a.Id);
        if(a.OwnerId != old.OwnerId)
        {
           ParentIds.add(a.Id);
            If(!newOwnerId.containsKey(a.Id))
            {
                newOwnerId.put(a.Id, a.OwnerId);
            }
        }
    }
    If(ParentIds.size() > 0)
    {
        Childs = [Select Id,First_Object__c from Second_Object__c where First_Object__c IN : ParentIds and Status__c = 'In Progress']; // use your Lookupfield Api Name insetad of ParId
    } 
    
    If(Childs.size() > 0)
    {
        for(Second_Object__c con : Childs)
        {
            Second_Object__c c = new Second_Object__c(Id = con.Id);
            c.ownerId = newOwnerId.get(con.First_Object__c);  // use your Lookupfield Api Name instead of ParId
            ChildstoUpdate.add(c);
        }
    }
    If(ChildstoUpdate.size() > 0)
    {
        Update ChildstoUpdate;
    }
}

Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Raj
This was selected as the best answer
Maharajan CMaharajan C
If you are going to use Manoj Trigger then you have to made the below changes:

trigger Changeownertrigger on First_Object__c(after update) {
       
          Set<Id> FirstObjectIds = new Set<Id>();
          Map<Id, String> oldOwnerIds = new Map<Id, String>();
          Map<Id, String> newOwnerIds = new Map<Id, String>();
          Second_Object__c[] SecondObjectUpdates = new Second_Object__c[0];
          
          for (First_Object__c f : Trigger.new)
          {
             if (f.OwnerId != Trigger.oldMap.get(f.Id).OwnerId)
             {
                oldOwnerIds.put(f.Id, Trigger.oldMap.get(f.Id).OwnerId);
                newOwnerIds.put(f.Id, f.OwnerId);
                FirstObjectIds.add(f.Id);
             }

          }
            if (!FirstObjectIds.isEmpty()) {
             for (First_Object__c FrstObj : [SELECT Id, (SELECT Id, OwnerId,First_Object__r FROM Second_Object__r) FROM First_Object__c WHERE Id in :FirstObjectIds])
                {
                String newOwnerId = newOwnerIds.get(FrstObj.Id);
                String oldOwnerId = oldOwnerIds.get(FrstObj.Id);
                for (Second_Object__c sec : FrstObj.SecondObjects)  // use the child relationship name of First_Object__c Lookup field in second_Object__c you can get this value from Child Relationship Name in First_Object__c Lookup field detail page in second_Object__c
                {
                   if (sec.OwnerId == oldOwnerId) 
                   {
                       if(sec.Status__c == 'In Progress')
                          {
                             Second_Object__c updatedSecondObject = new Second_Object__c(OwnerId = newOwnerId, Id = sec.Id);
                             SecondObjectUpdates.add(updatedSecondObject);
                          }
                   }
                }
                 
                }
           }
                update SecondObjectUpdates;
    }
Carrlos BoydCarrlos Boyd
Maharajan, your trigger with the small changes worked perfectly!! Do you think you can help me with 2 more that are similar?
Maharajan CMaharajan C

Yes Carlos you can ask. if you want to ping me also use my skype Id: maharaja0393 when you need my help.