1

So I managed to change the Primary Contact for a specific account on Update, but I can't figure out how to do it on Insert. I'm guessing it should be very similar to the update trigger. Could you guys give me a tip?

Thanks in advance.

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

    if(Trigger.isAfter){
        if(Trigger.isInsert){

        } else if(Trigger.isUpdate){
            Set<Id> accountIds = new Set<Id>();
            List<Account> updatedAccounts = new List<Account>();
            for (Contact c : Trigger.new) {
                accountIds.add(c.AccountId);
            } 

            List<Contact> contactList = new List<Contact>([Select Id, Is_Primary_Contact__c, AccountId from Contact where Is_Primary_Contact__c = true AND AccountId IN :accountIds]);
            List<Contact> updContacts = new List<Contact>();
            List<Account> updAccounts = new List<Account>();

            Map<Id,Account> accMap = new Map<Id,Account>([Select Id, Primary_Contact__c From Account where Id IN :accountIds]);

            for (Contact c : Trigger.new) {
                Contact oldC = trigger.oldMap.get(c.Id);
                if(c.Is_Primary_Contact__c != oldC.Is_Primary_Contact__c && c.Is_Primary_Contact__c == true){
                    for(Contact exC : contactList){
                        if(exC.Id != c.Id && exC.AccountId == c.AccountId){
                            exC.Is_Primary_Contact__c = false;
                            updContacts.add(exC);

                            Account acc = accMap.get(exC.AccountId);
                            acc.Primary_Contact__c = c.Id;
                            updAccounts.add(acc);
                        }
                    }      
                }
            }

            update updContacts;
            update updAccounts;
        }  
    } 
}
0

As I can see from your code, you are doing 2 queries even before checking if the Contact is primary or not, its called as premature caching. This can be totally avoided by checking first if contact's Primary Contact status is changed or contact is created.

As sfdcfox has suggested, you can null check old variables to see if its insert or update,

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

    if(Trigger.isAfter){

        Map<Id,Id> accountIDvsPrimaryContactId = new Map<Id,Id>();
        for (Contact c : Trigger.new) {
            if(c.Is_Primary_Contact__c && (Trigger.oldMap == null || !Trigger.oldMap.get(c.Id).Is_Primary_Contact__c)) { //If primary contact is true or has changed to true
                accountIDvsPrimaryContactId.put(c.AccountId , c.Id); //create Map of Account vs Primary contact
            }
        }

        List<Account> toBeUpdatedAccounts = [SELECT ID, Primary_Contact__c  FROM Account WHERE ID in :accountIDvsPrimaryContactId.keySet()];
        List<Contact> oldContactsToBeUpdated = new List<Contact>();

        for(Account acc : toBeUpdatedAccounts){
            oldContactsToBeUpdated.add(new Contact(Id=acc.Primary_Contact__c) , Is_Primary_Contact__c = false); //Make old contacts as non primary
            acc.Primary_Contact__c = accountIDvsPrimaryContactId.get(acc.Id); //Set account's primary contact with new contact id
        }

        //Updating all contacts and Accounts

        update oldContactsToBeUpdated;
        update toBeUpdatedAccounts;

    } 
}

There is still one scenario, which needs to be thought for..

What if someone uses dataloader and make 2 contacts for same account as primary, then your code should be smart enough to understand this and throw errors.

I can think about doing this in Before Trigger and Using SF unique field constraints.

0

Aside from other technical problems, you could simply check if the record is new or not:

if(c.Is_Primary_Contact__c && (oldC == null || !oldC.Is_Primary_Contact__c)) {

This eliminates the need for checking if this is insert/update earlier in the code.

There's other, more efficient ways you could do this, too, but this should get you started.

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.