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
Andrew LikensAndrew Likens 

Update Contacts From Account When Field Value is Changed trigger

Here are my requirements:

1. I have accounts in a 'Potential Customer' picklist value for one of our custom fields on the account "Account_Status__c." When that value is changed from "Potential Customer" to "Customer", I want to invoke a method "ContactUpsert.ContactUpdate(con.Id)." However, I ONLY want to invoke that method when Account_Status__c is "Customer" and a field on the contact Contact_Status__c is "Contact." Otherwise, all related contacts to an account in the "Potential Customer" status should be static. Once that account is changed to "Customer" it should do an UPDATE to all related contacts. It can be any update to the contacts as long as it's an update. Our internal API triggers when an object is updated in Salesforce. I'm a developer newbie so any help would be greatly appreciated!! Much thanks in advance!!
Best Answer chosen by Andrew Likens
Nayana KNayana K
As per these statements "Once that account is changed to "Customer" it should do an UPDATE to all related contacts. It can be any update to the contacts as long as it's an update. Our internal API triggers when an object is updated in Salesforce.", I think the following code is suitable.
trigger AccountTrigger on Account(after update)
{
	if(trigger.isAfter)
	{
		if(Trigger.isUpdate)
		{
			Set<Id> setAccId = new Set<Id>();
			
			
			for(Account objAcc : Trigger.New)
			{
				if(Trigger.oldMap.get(objAcc.Id).Account_Status__c == 'Potential Customer'
					&&
				  objAcc.Account_Status__c == 'Customer')
				  setAccId.add(objAcc.Id);
			}
			List<Contact> lstConToUpdate = new List<Contact>([	SELECT Id 
																FROM Contact 
																WHERE Contact_Status__c = 'Contact'
																	AND AccountId IN:setAccId]);
// perform DML update on contacts			
if(!lstConToUpdate.isEmpty())
				update lstConToUpdate;
		
		}

	}
}

 

All Answers

Nayana KNayana K
trigger AccountTrigger on Account(after update)
{
	if(trigger.isAfter)
	{
		if(Trigger.isUpdate)
		{
			Set<Id> setAccId = new Set<Id>();
			for(Account objAcc : Trigger.New)
			{
				if(Trigger.oldMap.get(objAcc.Id).Account_Status__c == 'Potential Customer'
					&&
				  objAcc.Account_Status__c == 'Customer')
				  setAccId.add(objAcc.Id);
			}
			
			for(Contact objCon : [	SELECT Id 
									FROM Contact 
									WHERE Contact_Status__c = 'Contact'
										AND AccountId IN:setAccId])
			{
				/* if ContactUpsert.ContactUpdate method updates single contact, then it is bad practice.
				Because, DML statement inside for loop is not a good practice. This is not recommendable*/
				
				ContactUpsert.ContactUpdate(objCon.Id);
			}
		}
	}
}

Below approach is recommendable
trigger AccountTrigger on Account(after update)
{
	if(trigger.isAfter)
	{
		if(Trigger.isUpdate)
		{
			Set<Id> setAccId = new Set<Id>();
			Set<Id> setConId = new Set<Id>();
			for(Account objAcc : Trigger.New)
			{
				if(Trigger.oldMap.get(objAcc.Id).Account_Status__c == 'Potential Customer'
					&&
				  objAcc.Account_Status__c == 'Customer')
				  setAccId.add(objAcc.Id);
			}
			
			for(Contact objCon : [	SELECT Id 
									FROM Contact 
									WHERE Contact_Status__c = 'Contact'
										AND AccountId IN:setAccId])
			{
				/*If you have a method which takes ContactIds 
				and updates them in bulk, let's say its sigature is ContactUpsert.ContactUpdate(Set<Id> setConIds) 
				then it is better to collect these contact ids and call that method outside this for loop*/
				setConId.add(objCon.Id);
			}
			
			if(!setConId.isEmpty())
				ContactUpsert.ContactUpdate(setConId);
		}
	}
}

 
Andrew LikensAndrew Likens
Thank you so much for the reply! I am doing a bulk update of all related contacts. However, I am getting an error.

Error: Compile Error: Method does not exist or incorrect signature: ContactCreate.ContactInitialCreate(Set<Id>) at line 29 column 17
Andrew LikensAndrew Likens
I can confirm that is the correct method name. Here is my class.
 
global class ContactCreate{
  @future (callout=true)
   public static void ContactInitialCreate(Id contactId) {
     //Construct HTTP request and response
     //Http request method,Endpoint and setBody
     Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('http://dev-svc01.salesforce.signzoneinc.com/Help/Api/Post/v1/Contact/' + contactId + '/Created');
request.setMethod('POST');
request.setHeader('Content-Type', 'text/json');
request.setHeader('Content-Length', '0');
request.setTimeout(20000);
HttpResponse response = http.send(request);
// Parse the JSON response
if (response.getStatusCode() != 201) {
    System.debug('The status code returned was not expected: ' +
        response.getStatusCode() + ' ' + response.getStatus());
} else {
    System.debug(response.getBody());
}
   }
 }

 
Nayana KNayana K
trigger AccountTrigger on Account(after update)
{
	if(trigger.isAfter)
	{
		if(Trigger.isUpdate)
		{
			Set<Id> setAccId = new Set<Id>();
			for(Account objAcc : Trigger.New)
			{
				if(Trigger.oldMap.get(objAcc.Id).Account_Status__c == 'Potential Customer'
					&&
				  objAcc.Account_Status__c == 'Customer')
				  setAccId.add(objAcc.Id);
			}
			
			for(Contact objCon : [	SELECT Id 
									FROM Contact 
									WHERE Contact_Status__c = 'Contact'
										AND AccountId IN:setAccId])
			{
				/* if ContactUpsert.ContactUpdate method updates single contact, then it is bad practice.
				Because, DML statement inside for loop is not a good practice. This is not recommendable*/
				
				ContactUpsert.ContactUpdate(objCon.Id);
			}
		}
	}
}

Use only above code
Nayana KNayana K
Sorry I thought some DML operation is present inside that method. But it is doing callouts. So no worries.
Andrew LikensAndrew Likens
Thanks for the reply. Do you know why I'm getting this error?

Error: Compile Error: Method does not exist or incorrect signature: ContactCreate.ContactInitialCreate(Set<Id>) at line 29 column 17
Nayana KNayana K
trigger AccountTrigger on Account(after update)
{
	if(trigger.isAfter)
	{
		if(Trigger.isUpdate)
		{
			Set<Id> setAccId = new Set<Id>();
			for(Account objAcc : Trigger.New)
			{
				if(Trigger.oldMap.get(objAcc.Id).Account_Status__c == 'Potential Customer'
					&&
				  objAcc.Account_Status__c == 'Customer')
				  setAccId.add(objAcc.Id);
			}
			
			for(Contact objCon : [	SELECT Id 
									FROM Contact 
									WHERE Contact_Status__c = 'Contact'
										AND AccountId IN:setAccId])
			{
				// I think you want to call this from here.
				ContactCreate.ContactInitialCreate(objCon.Id);
			}
		}
	}
}

 
Nayana KNayana K
What about this ContactUpsert.ContactUpdate(con.Id) method?
Andrew LikensAndrew Likens
That is from another class/method. So I tested and it looks like the code is not updating the related contacts. Do we need to insert a DML statement?
Nayana KNayana K
As per these statements "Once that account is changed to "Customer" it should do an UPDATE to all related contacts. It can be any update to the contacts as long as it's an update. Our internal API triggers when an object is updated in Salesforce.", I think the following code is suitable.
trigger AccountTrigger on Account(after update)
{
	if(trigger.isAfter)
	{
		if(Trigger.isUpdate)
		{
			Set<Id> setAccId = new Set<Id>();
			
			
			for(Account objAcc : Trigger.New)
			{
				if(Trigger.oldMap.get(objAcc.Id).Account_Status__c == 'Potential Customer'
					&&
				  objAcc.Account_Status__c == 'Customer')
				  setAccId.add(objAcc.Id);
			}
			List<Contact> lstConToUpdate = new List<Contact>([	SELECT Id 
																FROM Contact 
																WHERE Contact_Status__c = 'Contact'
																	AND AccountId IN:setAccId]);
// perform DML update on contacts			
if(!lstConToUpdate.isEmpty())
				update lstConToUpdate;
		
		}

	}
}

 
This was selected as the best answer
Andrew LikensAndrew Likens
Thank you Nayana very much for the assistance!