0

I need to create a trigger on Contact that is triggered after insert or after update. I have two custom fields. One in Account called 'Primary Contact' which is text field and one in Contact called 'Primary' which is checkbox. When a new Contact is added or updated, my trigger needs to check if the checkbox has been checked(to true) and update the corresponding Account's 'Primary Contact' to the Contacts 'Owner' field. If possible I would greatly appreciate what each line of code is doing. I've seen many examples but they don't explain whats happening. If possible it would be great to see a very simple version.

EDIT: Sorry I made a mistake.Its not suppose to be the 'Owner' field but the 'firstname' and 'lastname' fields in Contact.

trigger UpdatePrimaryFieldInAccount on Contact (after insert, after update) {
    //create list to hold accounts
    List<Account> accList = new List<Account>();

    //Get related Accounts for the contact in this trigger
    Map<Id, Contact> contactWithAccount = new Map<Id, Contact>([SELECT Id,(SELECT Id FROM Account) FROM Contact WHERE Id IN :Trigger.New]);

    //iterate through each contact
    for(Contact c : Trigger.New) {
        if(c.Primary__c) //if custom field is checked
        //change/update Account Primary Contact field
        contactWithAccount.get(c.Id).Primary_Contact__c= c.Owner;
        //add to accList
        accList.add(c.accountId);
    }
    //finally update the accList in the database
    update accList;                             
}
1

Here is one way to implement the trigger with some documenting comments inline:

trigger UpdatePrimaryFieldInAccount on Contact (after insert, after update) {

    // Immediate fields of Contact available in the trigger
    // context so no additional query required
    Map<Id, Id> accountToOwner = new Map<Id, Id>();
    for(Contact c : Trigger.New) {
        if (c.Primary__c && c.AccountId != null) {
            accountToOwner.put(c.AccountId, c.OwnerId);
        }
    }

    if (accountToOwner.size() > 0) {

        // Name of owner does have to be queried from the Id and the
        // results can be put into a map via this handy constructor
        Map<id, User> users = new Map<id, User>([
                select Id, Name
                from User
                where Id in :accountToOwner.values()
                ]);

        // Don't need to query an object to update it
        // with this pattern of setting the Id 
        Account[] updates = new Account[] {};
        for (Id accountId : accountToOwner.keySet()) {
            Id ownerId = accountToOwner.get(accountId);
            updates.add(new Account(
                    Id = accountId,
                    Primary_Contact__c = users.get(ownerId).Name
                    ));
        }
        update updates;
    }                    
}

Often the number of queries governor limit is hit first so this code tries to minimise the queries.

(Your code has a few problems that probably stop it compiling and also runtime problems such as referencing c.Owner that will always be null. Also when doing an update, you need to ensure that there is only ever one record for a particular Id so it is common to use a map keyed by the record Id.)

PS

The changed requirement allows a simpler answer because all the data is available in the trigger context without further querying:

trigger UpdatePrimaryFieldInAccount on Contact (after insert, after update) {
    Map<Id, Account> accounts = new Map<Id, Account>();
    for(Contact c : Trigger.New) {
        if (c.Primary__c && c.AccountId != null) {
            accounts.put(c.AccountId, new Account(
                    Id = c.AccountId,
                    Primary_Contact__c = c.Name
                    ));
        }
    }
    update accounts;                   
}

(You could set Primary_Contact__c = c.FirstName + ' ' + c.LastName if you prefer.)

  • Thank you very much. I really appreciate it. I made a mistake. Its not suppose to be 'Account's 'Primary Contact' to the Contacts 'Owner' field' but instead Primary Contact' to the Contacts 'firstname + lastname' fields. How would that change the code? – Mary Feb 15 '17 at 19:52
  • @Mary See the PS. I recommend you work through the Trailhead Apex Triggers module so you can make these sort of changes more easily yourself. – Keith C Feb 16 '17 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.