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
CaitlinGMCaitlinGM 

Trigger for field update on related object based on stage

I posted a related question a little while back and got some good ideas, but I'm still struggling with writing my first trigger. It should be simple enough: 

 

Opportunity has a Contact related through a lookup field on Opportunity. When Opportunity stage is Active, I want related contact status (Instructor_Status__c; it's a picklist) to change to Employed. 

When Opportunity Stage is not Active, I want related contact status to change to Available. 

 

If it matters, Opportunity:Contact is One:Many. 

 

I have so far: 

 

trigger OpportunityRelatedContact on Opportunity (after insert, after update) { 
{
list<Contact> Listofinstructors = new list<Contact>();

for (Opportunity A : trigger.new)
{

Contact instructor = new Contact(Id = A.InstructorName__c);
listofinstructors.add(Instructor);

if(A.StageName=='Active'){
instructor.Instructor_status__c='Employed';}
}
}
}

 

It's obviously not there yet, and I don't know if I have the right approach. Any help is appreciated. 

Best Answer chosen by Admin (Salesforce Developers) 
Ritesh AswaneyRitesh Aswaney

All's well with the trigger, save for it isnt updating the contacts after setting Instructor_Status__c=Employed

So lets create a list to collect the contacts to be updated and then update them

 

 

trigger OpportunityRelatedContact on Opportunity (after insert, after update) { 
{
Map<Id,Id> instructorsToOppsMap = new Map<Id,Id>();
for(Opportunity A : trigger.new)
           instructorsToOppsMap.put(A.InstructorName__c,A.Id);
 
List<Contact> contactsToUpdate = new List<Contact>{};
      
    for (Contact Instructor: [SELECT Id,Instructor_status__c FROM Contact WHERE Id IN:  instructorsToOppsMap.keySet()])
    {
        Id oppId = instructorsToOppsMap.get(Instructor.Id);
        Opportunity opp = trigger.newMap.get(oppId);
        if (opp.StageName=='Active'){
            Instructor.Instructor_status__c='Employed';
             contactsToUpdate.add(instructor);
         }
}
if(contactsToUpdate != null && !contactsToUpdate.isEmpty())
        Database.update(contactsToUpdate);
}



 

All Answers

saraha@groupesci.comsaraha@groupesci.com

Caitlin,

 

I don't think you should be creating new contacts (instructors), but rather looking up existing ones. You will need to first load them all into a map so that that nyou can go through Opps again and do your updates, something like this:

 

 

trigger OpportunityRelatedContact on Opportunity (after insert, after update) { 
{
	Map<Id,Id> insructorsToOppsMap = new Map<Id,Id>();

	for (Opportunity A : trigger.new)
	{
		insructorsToOppsMap.put(A.InstructorName__c,A.Id);
	}
	for (Contact Instructor: [SELECT Id,Instructor_status__c FROM Contact WHERE Id IN: InstructorIds])
	{
		Id oppId = insructorsToOppsMap.get(Instructor.Id);
		Opportunity opp = trigger.newMap.get(oppId);
		if (opp.StageName=='Active'){
			Instructor.Instructor_status__c='Employed';
	}
}

 

 

 

Hope this helps!

 --Sarah

CaitlinGMCaitlinGM

Hi, 

 

Thank you. That's what I was trying to do. 

 

I'm getting "Error: Compile Error: Variable does not exist: InstructorId at line 10 column 88" 

 

Any ideas? 

 

Thanks!

saraha@groupesci.comsaraha@groupesci.com

Can you post your code plz. Thanks!

CaitlinGMCaitlinGM

 

trigger OpportunityRelatedContact on Opportunity (after insert, after update) { 
{
Map<Id,Id> instructorsToOppsMap = new Map<Id,Id>();

for(Opportunity A : trigger.new)
{
           instructorsToOppsMap.put(A.InstructorName__c,A.Id);
        }
        
    for (Contact Instructor: [SELECT Id,Instructor_status__c FROM Contact WHERE Id IN: InstructorIds])
    {
        Id oppId = instructorsToOppsMap.get(Instructor.Id);
        Opportunity opp = trigger.newMap.get(oppId);
        if (opp.StageName=='Active'){
            Instructor.Instructor_status__c='Employed';

 

 

saraha@groupesci.comsaraha@groupesci.com

Oops my bad, replace InstructorIds with instructorsToOppsMap.keySet() in line 10, like this:

 

for (Contact Instructor: [SELECT Id,Instructor_status__c FROM Contact WHERE Id IN:  instructorsToOppsMap.keySet()])

 

 

CaitlinGMCaitlinGM

Thanks for the follow-up. Now it is allowing me to save the trigger, but when I try to edit and save an opportunity, and then go to the related contact/instructor, I'm not seeing the field update. 

saraha@groupesci.comsaraha@groupesci.com

If you have checked that all your data makes sense (Opp has correct stage, contact(s) exist), then you will need to put some system.debug statements into the trigger to find out what is going on. Look in the Apex Developer Guide for how to use and debug statements.

 

--Sarah

Ritesh AswaneyRitesh Aswaney

All's well with the trigger, save for it isnt updating the contacts after setting Instructor_Status__c=Employed

So lets create a list to collect the contacts to be updated and then update them

 

 

trigger OpportunityRelatedContact on Opportunity (after insert, after update) { 
{
Map<Id,Id> instructorsToOppsMap = new Map<Id,Id>();
for(Opportunity A : trigger.new)
           instructorsToOppsMap.put(A.InstructorName__c,A.Id);
 
List<Contact> contactsToUpdate = new List<Contact>{};
      
    for (Contact Instructor: [SELECT Id,Instructor_status__c FROM Contact WHERE Id IN:  instructorsToOppsMap.keySet()])
    {
        Id oppId = instructorsToOppsMap.get(Instructor.Id);
        Opportunity opp = trigger.newMap.get(oppId);
        if (opp.StageName=='Active'){
            Instructor.Instructor_status__c='Employed';
             contactsToUpdate.add(instructor);
         }
}
if(contactsToUpdate != null && !contactsToUpdate.isEmpty())
        Database.update(contactsToUpdate);
}



 

This was selected as the best answer
saraha@groupesci.comsaraha@groupesci.com

Duh! Of course! Thanks Ritesh.

CaitlinGMCaitlinGM

That makes sense. Thanks so much to both of you for the help--it's working now. This is great. 

 

I eventually need to make something a bit more complex, but now I understand the basics of doing a cross-object field update.