0

I have a requirement When an account is created or edited, the value entered in coverage lead field (which is a lookup to user) should copy over to account owner field and also to the owner field of all related contacts. If the coverage lead field is left blank, last modified by field should copy over to account owner as well as related contact's owner fields. I've built a trigger for this requirement but when I try to update/insert Account the User in lookup field is not populating as owner. Can someone help me what needs to be changed in my trigger.

trigger AccountOwnerUpdate on Account (before insert, before update, after insert, after update) {
    Set<Id> accIds = new Set<Id>();
    //List<Account> updatedAccList = new List<Account>();
    List<Account> updatedConList = new List<Account>();
    List<Account> accList = new List<Account>();
    if(trigger.isInsert) {
        system.debug('bbbbbbb');
        for(Account acc : trigger.new) {
            accIds.add(acc.Id);
            system.debug('entered here');
        }
    }
    if(trigger.isUpdate) {
        system.debug('asssss');
        for(Account acc : trigger.old) {
            accIds.add(acc.Id);
            system.debug('entered here');
        }
    }
    for(Account accs : [SELECT Id, Coverage_Lead__c, Owner.Id, LastModifiedById,(SELECT Id, Owner.Id FROM Contacts) FROM Account WHERE Id IN:accIds]) {
        for(Contact con : accs.Contacts) {
            if(accs.Coverage_Lead__c != NULL) {
                accs.OwnerId = accs.Coverage_Lead__c;
                con.OwnerId = accs.Coverage_Lead__c;
            }
            else if(accs.Coverage_Lead__c == NULL) {
                accs.OwnerId = accs.LastModifiedById;
                con.OwnerId = accs.LastModifiedById;
            }
        }
}

Thanks in Advance.

4
  • Please edit your post to describe exactly what is wrong. "isn't working as expected" is not enough detail on the problem.
    – David Reed
    Commented Mar 3, 2021 at 4:04
  • @DavidReed I have made changes to the post to describe my problem...
    – user93540
    Commented Mar 3, 2021 at 4:20
  • I don't quite get what's the error. Could you please clarify this? Is the problem with last modified by field? You cannot modify this field, some information around this can be found here: help.salesforce.com/…
    – MANUELAN00
    Commented Mar 3, 2021 at 5:19
  • @MANUELAN00, Using trigger I am trying to change the owner of Account and its related contacts based on custom lookup field(Lookup to User) in Account. I see when I insert account the value in lookup filed is not updating as Account Owner. Can you help me on this..
    – user93540
    Commented Mar 3, 2021 at 5:33

2 Answers 2

0

There are a few things in regards to your trigger.

  1. You are executing this both before and after, which will cause the trigger to execute twice, and giving your use case can cause some conflicts.
  2. Your account object is never updated as you are updating accs.OwnerId = accs.LastModifiedById. This is not part of the current trigger.new context so it will never get updated.
  3. You are never updating contacts, as contact is a different object outside your Account trigger. You need to execute an update over a list of contacts. e.g. update updatedConList;
  4. With your below query you are always getting the current Coverage_Lead__c value and not the new one, so you should map the new value and then retrieve that in your iteration over contacts.

I have created the below trigger that works for your use case and I hope it solves your problem. However, this query can definitely get improved so don't take it as the best approach. It just one valid example that will give you an idea of what you were doing wrong.

trigger AccountOwnerUpdate on Account (before insert, before update) {
Set<Id> accIds = new Set<Id>();
List<Contact> updatedConList = new List<Contact>();
List<Account> accList = new List<Account>();
Map<Id, String> newOwnerIds = new Map<Id, String>();    

    for(Account acc : trigger.new) {
        system.debug('entered here');
        accIds.add(acc.Id);
        newOwnerIds.put(acc.Id, acc.Coverage_Lead__c);
        
         if(acc.Coverage_Lead__c != NULL) {
              acc.OwnerId = acc.Coverage_Lead__c;
         }
        if(acc.Coverage_Lead__c == NULL){
            acc.OwnerId = acc.LastModifiedById;                
        }
    }

for(Account accs : [SELECT Id, LastModifiedById, (SELECT Id, Owner.Id FROM Contacts)
                    FROM Account WHERE Id IN:accIds]) {
    String newOwnerId = newOwnerIds.get(accs.Id);
    //String oldOwnerId = oldOwnerIds.get(acc.Id);    
                        
    if(newOwnerIds.get(accs.Id) != NULL) {
        system.debug('Coverage_Lead__c !=');
        for(Contact con : accs.Contacts) {
            con.OwnerId = newOwnerIds.get(accs.Id);
            updatedConList.add(con);
        }
    }
    if(newOwnerIds.get(accs.Id) == NULL) {
        system.debug('Coverage_Lead__c ==');
        for(Contact con : accs.Contacts) {
            con.OwnerId = accs.LastModifiedById;
            updatedConList.add(con);
        }   
    }
    
 }
 update updatedConList;
 }

Cheers,

2
  • Thanks for your help. I understood what I did wrong by comparing your code..
    – user93540
    Commented Mar 3, 2021 at 7:31
  • Glad to hear that :)
    – MANUELAN00
    Commented Mar 3, 2021 at 21:17
0

There's a few issues going on here:

  • before vs after events
  • trigger context variables

Please take a look at the following links to gain a better understanding: https://trailhead.salesforce.com/content/learn/modules/apex_triggers/apex_triggers_intro https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm

You should be aware of the differences between before and after events. Before events allow you to modify the field values, like OwnerId, before the records are committed to the DB.

You'll need to iterate over the Accounts in the Trigger.new variable, rather than trying to query the same set, as the referenced sObjects in Trigger.new are on their way to the DB. Otherwise, a new SOQL query of those same records would return what is currently in the DB and require another DML operation to commit to the DB (which could result in a loop).

DML operations are usually performed in after trigger events, see trigger order of execution, due to errors and partial success of Database methods (Database.insert, etc.). You'll want to update the Contacts in an after update.

You must log in to answer this question.