function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SFDC GuestSFDC Guest 

Trigger to update previous contact as non primary if new contact is primary.

Hi All,
My requirement is update previous contact as non primary if new contact is primary..
Can you please help me what to write in below trigger. Thanks in advance.
 
Trigger updatePrimaryCheckbox2 on Contact(after insert, after update) {
   Map < Id, Contact > accConMap = new Map < Id, Contact > ();
   List < Contact > conList = new List < Contact > ();
   if (Trigger.isInsert || Trigger.isUpdate) {
    for (Contact cont: Trigger.New) {
     if (cont.AccountId != null && cont.IsPrimaryContact__c == true) {
      accConMap.put(cont.AccountId, cont);
     }
    }
   }
   for (Contact con: [select id, AccountId, IsPrimaryContact__c, Description from contact
     where accountid IN: accConMap.keyset()
    ]) {
    if (con != null && accConMap.containsKey(con.AccountId)) {
    // here logic
    // logic
     conList.add(con);
    }
   }
   update conList;
  }

 
Best Answer chosen by SFDC Guest
Nayana KNayana K
I guess below should work:
Trigger updatePrimaryCheckbox2 on Contact(after insert, after update) {
	Map < Id, Id > accConMap = new Map < Id, Id > ();
	List < Contact > conList = new List < Contact > ();
	
		for (Contact cont: Trigger.New) {
			if (cont.AccountId != null && cont.IsPrimaryContact__c && (Trigger.isInsert || (Trigger.isUpdate && !Trigger.oldMap.get(cont.Id).IsPrimaryContact__c))) {
				accConMap.put(cont.AccountId, cont.Id);
			}
		}
		if(!accConMap.isEmpty()) {
			for (Contact con: [select Id, IsPrimaryContact__c from contact
								where accountid IN: accConMap.keyset()
								AND Id NOT IN: accConMap.values()
								AND IsPrimaryContact__c = true
								]) {
				con.IsPrimaryContact__c = false;
				conList.add(con);
			}
			if(!conList.isEmpty()) {
				update conList;
			}
		}
  }


However, I suggest to have seperate handler class and trigger pattern like below:
public class ContactTriggerHandler {
	public void onAfterInsert(Map<Id, Contact> mapContactOld, List<Contact> lstContactNew) {
		updatePrimaryContactCheckbox(mapContactOld, lstContactNew);
	}
	
	public void onAfterUpdate(Map<Id, Contact> mapContactOld, List<Contact> lstContactNew) {
		updatePrimaryContactCheckbox(mapContactOld, lstContactNew);
	}
	
	private void updatePrimaryContactCheckbox(Map<Id, Contact> mapContactOld, List<Contact> lstContactNew) {
		List<Contact> lstConToUpdate = new List<Contact>();
		Map<Id, Id> mapAccIdToPrimaryConId = new Map<Id, Id>();
		
		for(lstContactNew objContact : lstContactNew) {
			if((Trigger.isInsert || (Trigger.isUpdate && !mapContactOld.get(objContact.Id).IsPrimaryContact__c)) && objContact.AccountId != null && objContact.IsPrimaryContact__c) {
				mapAccIdToPrimaryConId.put(objContact.AccountId, objContact.Id);
			}
		}
		
		if(!mapAccIdToPrimaryConId.isEmpty()) {
			for (Contact objContact : [SELECT Id, IsPrimaryContact__c FROM Contact
								WHERE AccountId IN: mapAccIdToPrimaryConId.keyset()
								AND Id NOT IN: mapAccIdToPrimaryConId.values()
								AND IsPrimaryContact__c = true
								]) {
				objContact.IsPrimaryContact__c = false;
				lstConToUpdate.add(con);
			}
			if(!lstConToUpdate.isEmpty()) {
				update lstConToUpdate;
			}
		}
	}
}
 
trigger updatePrimaryCheckbox2 on Contact(after insert, after update) {
	ContactTriggerHandler objHandler = new ContactTriggerHandler();
	if(Trigger.isAfter) {
		if(Trigger.isInsert) {
			objHandler.onAfterInsert(Trigger.OldMap, Trigger.New);
		}
		else if(Trigger.isUpdate) {
			objHandler.onAfterUpdate(Trigger.OldMap, Trigger.New);
		}
	}
}


 

All Answers

Nayana KNayana K
I guess below should work:
Trigger updatePrimaryCheckbox2 on Contact(after insert, after update) {
	Map < Id, Id > accConMap = new Map < Id, Id > ();
	List < Contact > conList = new List < Contact > ();
	
		for (Contact cont: Trigger.New) {
			if (cont.AccountId != null && cont.IsPrimaryContact__c && (Trigger.isInsert || (Trigger.isUpdate && !Trigger.oldMap.get(cont.Id).IsPrimaryContact__c))) {
				accConMap.put(cont.AccountId, cont.Id);
			}
		}
		if(!accConMap.isEmpty()) {
			for (Contact con: [select Id, IsPrimaryContact__c from contact
								where accountid IN: accConMap.keyset()
								AND Id NOT IN: accConMap.values()
								AND IsPrimaryContact__c = true
								]) {
				con.IsPrimaryContact__c = false;
				conList.add(con);
			}
			if(!conList.isEmpty()) {
				update conList;
			}
		}
  }


However, I suggest to have seperate handler class and trigger pattern like below:
public class ContactTriggerHandler {
	public void onAfterInsert(Map<Id, Contact> mapContactOld, List<Contact> lstContactNew) {
		updatePrimaryContactCheckbox(mapContactOld, lstContactNew);
	}
	
	public void onAfterUpdate(Map<Id, Contact> mapContactOld, List<Contact> lstContactNew) {
		updatePrimaryContactCheckbox(mapContactOld, lstContactNew);
	}
	
	private void updatePrimaryContactCheckbox(Map<Id, Contact> mapContactOld, List<Contact> lstContactNew) {
		List<Contact> lstConToUpdate = new List<Contact>();
		Map<Id, Id> mapAccIdToPrimaryConId = new Map<Id, Id>();
		
		for(lstContactNew objContact : lstContactNew) {
			if((Trigger.isInsert || (Trigger.isUpdate && !mapContactOld.get(objContact.Id).IsPrimaryContact__c)) && objContact.AccountId != null && objContact.IsPrimaryContact__c) {
				mapAccIdToPrimaryConId.put(objContact.AccountId, objContact.Id);
			}
		}
		
		if(!mapAccIdToPrimaryConId.isEmpty()) {
			for (Contact objContact : [SELECT Id, IsPrimaryContact__c FROM Contact
								WHERE AccountId IN: mapAccIdToPrimaryConId.keyset()
								AND Id NOT IN: mapAccIdToPrimaryConId.values()
								AND IsPrimaryContact__c = true
								]) {
				objContact.IsPrimaryContact__c = false;
				lstConToUpdate.add(con);
			}
			if(!lstConToUpdate.isEmpty()) {
				update lstConToUpdate;
			}
		}
	}
}
 
trigger updatePrimaryCheckbox2 on Contact(after insert, after update) {
	ContactTriggerHandler objHandler = new ContactTriggerHandler();
	if(Trigger.isAfter) {
		if(Trigger.isInsert) {
			objHandler.onAfterInsert(Trigger.OldMap, Trigger.New);
		}
		else if(Trigger.isUpdate) {
			objHandler.onAfterUpdate(Trigger.OldMap, Trigger.New);
		}
	}
}


 
This was selected as the best answer
SFDC GuestSFDC Guest
Thank you so much Nayana. It's working great.