+ Start a Discussion
Robert Lange 6Robert Lange 6 

Write trigger for primary contact for account object

I have written a trigger where if the user attempts to make a 2nd related contact on the account object a Primary Contact too, an error is thrown.  I am trying to add syntax to my trigger so if the user adds a related contact to an Account that currently has 0 related contacts, this new contact will automatically become the primary contact.  This is the code I have so far:
Trigger PrimaryContactTrigger on Contact (Before Insert, Before Update) {

    List<Id> actIds = New List<Id>();
    List<Contact> comingCons = New List<Contact>();
    List<Id> conIds = New List<Id>();

    If (Trigger.IsBefore && (Trigger.IsInsert || Trigger.IsUpdate)) {
        For (Contact Con : Trigger.New) {
            If (Con.IsPrimary__c == TRUE) {
                actIds.add(Con.AccountId);
                conIds.add(Con.Id);
                comingCons.add(Con);
            }
            }
        }
        List<Account> allRelatedAccounts = [
                Select Id, (
                        Select Id, IsPrimary__c
                        FROM Contacts
                        WHERE IsPrimary__c = TRUE
                        AND Id != :conIds
                )
                FROM Account
                WHERE Id = :actIds
        ];
        For (Contact EveryCon : comingCons) {
            For (Account EveryAccount : allRelatedAccounts) {
                If (EveryCon.AccountId == EveryAccount.Id && EveryAccount.Contacts.size() > 0) {
                    EveryCon.addError('THERE is already a primary contact for this account');
                }
            }
        }
    }

 
Best Answer chosen by Robert Lange 6
Mayur Naidu 17Mayur Naidu 17
Robert, that is correct. The scenario was overlooked. Please use below code. It will solve the purpose.

Trigger PrimaryContactTrigger on Contact (Before Insert, Before Update) {

List<Id> actIds = New List<Id>();
List<Contact> comingCons = New List<Contact>();
List<Id> conIds = New List<Id>();
List<Account> actIds1 = New List<Account>();
If (Trigger.IsBefore && (Trigger.IsInsert || Trigger.IsUpdate)) {
    For (Contact Con : Trigger.New) {
        If (Con.IsPrimary__c == TRUE) {
            actIds.add(Con.AccountId);
            conIds.add(Con.Id);
            comingCons.add(Con);
        }else{
            actIds.add(Con.AccountId);
            conIds.add(Con.Id);
            List<Account> allRelatedAccounts = [
                    Select Id, (
                            Select Id, IsPrimary__c
                            FROM Contacts
                            WHERE IsPrimary__c = TRUE
                            AND Id != :conIds
                    )
                    FROM Account
                    WHERE Id = :actIds];

            for (Account everyAccount : allRelatedAccounts){
                If (everyAccount.Contacts.size() == 0){
                    Con.IsPrimary__c = True;
                }
            }

        }
    }
}

List<Account> allRelatedAccounts = [
        Select Id, (
                Select Id, IsPrimary__c
                FROM Contacts
                WHERE IsPrimary__c = TRUE
                AND Id != :conIds
        )
        FROM Account
        WHERE Id = :actIds
];
For (Contact EveryCon : comingCons) {
    For (Account EveryAccount : allRelatedAccounts) {
        If (EveryCon.AccountId == EveryAccount.Id && EveryAccount.Contacts.size() > 0) {
            EveryCon.addError('THERE is already a primary contact for this account');
        }

    }
}

}

All Answers

AbhishekAbhishek (Salesforce Developers) 
Hi Robert,

Try this code


trigger primaryContact on Contact (after insert, after update) {
      Set<Id> accountIds = new Set<Id>();
      List<Account> updatedAccounts = new List<Account>();
      for (Contact c : Trigger.new) {
        accountIds.add(c.AccountId);
      }
      // Get accounts with their contacts.
      Map<Id,Account> accountMap = new Map<Id,Account>([Select Id, Primary_Contact__c, (Select Id, Name from Contacts where IsPrimary__c = true) from Account where Id in :accountIds]);
      // Iterate over the new data from trigger
      for (Contact c : Trigger.new) {
        if (c.IsPrimary && accountMap.get(c.AccountId)) {
            Account updAccount = accountMap.get(c.AccountId);
            updAccount.Primary_Contact__c = c.Id;
            if (updAccount.Contacts != null && updAccount.Contacts.size()>0) { // This will identify if account already has primary contact set
              // Not sure what you want to do? Throw an error? or turn off the iS Primary on older contact?
            }
            
            updatedAccounts.add(updAccount);
        } 
      }
      
      update updatedAccounts;
}


For your reference, you can check the below blog too,

https://developer.salesforce.com/forums/?id=9060G0000005UEYQA2


I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.


Thanks.
Robert Lange 6Robert Lange 6
Thank you for taking the time to respond.  The blog you referred me to contains the code I posted in my original question, and the code you supplied to me, if I interpret it correctly, does not make the first contact related to the account a primary contact automatically.  I'm not sure why you sent that code to me, but thank you for looking at my question.
Mayur Naidu 17Mayur Naidu 17
Hello Robert! Please use below code. We just need an additional else loop to serve the purpose.


Trigger PrimaryContactTrigger on Contact (Before Insert, Before Update) {

    List<Id> actIds = New List<Id>();
    List<Contact> comingCons = New List<Contact>();
    List<Id> conIds = New List<Id>();
    If (Trigger.IsBefore && (Trigger.IsInsert || Trigger.IsUpdate)) {
        For (Contact Con : Trigger.New) {
            If (Con.IsPrimary__c == TRUE) {
                actIds.add(Con.AccountId);
                conIds.add(Con.Id);
                comingCons.add(Con);
            }else{
                Con.IsPrimary__c = True;

            }
            }
        }
        List<Account> allRelatedAccounts = [
                Select Id, (
                        Select Id, IsPrimary__c
                        FROM Contacts
                        WHERE IsPrimary__c = TRUE
                        AND Id != :conIds
                )
                FROM Account
                WHERE Id = :actIds
        ];
        For (Contact EveryCon : comingCons) {
            For (Account EveryAccount : allRelatedAccounts) {
                If (EveryCon.AccountId == EveryAccount.Id && EveryAccount.Contacts.size() > 0) {
                    EveryCon.addError('THERE is already a primary contact for this account');
                }
                    
           }
       }
}
Robert Lange 6Robert Lange 6
Mayur, Thank you for the reply, but now every time I add a related contact to the account, it makes each added contact a primary contact.
Mayur Naidu 17Mayur Naidu 17
Robert, that is correct. The scenario was overlooked. Please use below code. It will solve the purpose.

Trigger PrimaryContactTrigger on Contact (Before Insert, Before Update) {

List<Id> actIds = New List<Id>();
List<Contact> comingCons = New List<Contact>();
List<Id> conIds = New List<Id>();
List<Account> actIds1 = New List<Account>();
If (Trigger.IsBefore && (Trigger.IsInsert || Trigger.IsUpdate)) {
    For (Contact Con : Trigger.New) {
        If (Con.IsPrimary__c == TRUE) {
            actIds.add(Con.AccountId);
            conIds.add(Con.Id);
            comingCons.add(Con);
        }else{
            actIds.add(Con.AccountId);
            conIds.add(Con.Id);
            List<Account> allRelatedAccounts = [
                    Select Id, (
                            Select Id, IsPrimary__c
                            FROM Contacts
                            WHERE IsPrimary__c = TRUE
                            AND Id != :conIds
                    )
                    FROM Account
                    WHERE Id = :actIds];

            for (Account everyAccount : allRelatedAccounts){
                If (everyAccount.Contacts.size() == 0){
                    Con.IsPrimary__c = True;
                }
            }

        }
    }
}

List<Account> allRelatedAccounts = [
        Select Id, (
                Select Id, IsPrimary__c
                FROM Contacts
                WHERE IsPrimary__c = TRUE
                AND Id != :conIds
        )
        FROM Account
        WHERE Id = :actIds
];
For (Contact EveryCon : comingCons) {
    For (Account EveryAccount : allRelatedAccounts) {
        If (EveryCon.AccountId == EveryAccount.Id && EveryAccount.Contacts.size() > 0) {
            EveryCon.addError('THERE is already a primary contact for this account');
        }

    }
}

}
This was selected as the best answer