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 to update contact field based on opportunity stage

Hi, 

 

I'm new to Apex, and want to create what I think is a pretty simple cross-object field update trigger. 

 

An Opportunity has an Instructor Name lookup to a Contact record. When I change the opportunity record to Active, I want a custom field to update the instructor employment status to Employed on the Contact record. Likewise, when Opportunity stage moves to Ended, I want Contact status to go to Available. 

 

Any ideas on how I can accomplish this? Thanks very much for your input. 

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

Which one would win would be down to you - as it would prolly need to be defined in the business logic in the trigger.

 

You could potentially have a  custom counter field on Contact - Active_Count__c. The triggers below could increment or decrement the counter depending on the transition of status.

 

Trigger on Opportunity

- If Active, Increment Active_Count__c. If Increment_Active_Count__c is now 1, Set to Employed

- If Inactive, Decrement Active Count. If Active Count = 0, set to Available

 

Trigger on MTT

- If Active, Increment Active_Count__c. Set to Employed if Active_Count__c is now 1

- If Inactive, Decrement Active Count. If Active Count = 0, set to Available

All Answers

Ritesh AswaneyRitesh Aswaney

Hey,

Since you're looking to accomplish a cross-object workflow-type update between two Standard objects, there is a nifty app on the App Exchange - http://appexchange.salesforce.com/listingDetail?listingId=a0N300000023bFjEAI (Aspira XObject). Its free to install for cross object updates between standard salesforce objects, recommend that you give it a whirl.

 

There's always Apex - you're right in thinking its a fairly simple trigger - here goes :

 

trigger OpportunityAfterTrigger on Opportunity (after update)

{

//a list to hold the Instructors to update

List<Contact> liftOfInstructors = new List<Contact>();

 

for (Opportunity opp : trigger.new)

{

//we save a soql query by instantiating a contact object with the id

Contact instructor = new Contact(Id = opp.Instructor__c); //replace instructor__c with name of ur contact field

liftOfInstructors.add(instructor);

 

//check that the opp stage has changed to Active from a different value earlier

if(opp.StageName = 'Active' && trigger.OldMap.get(opp.Id).StageName != 'Active')

instructor.Employment__c = 'Employed'

else if(opp.StageName = 'Ended' && trigger.OldMap.get(opp.Id).StageName != 'Ended')

instructor.Employment__c = 'Available';

 

}

 

if (liftOfInstructors != null && !liftOfInstructors.isEmpty()

Database.update(liftOfInstructors);

 

}

CaitlinGMCaitlinGM

Thanks for your response and for the tip on the app; I'll check it out. 

 

I've been thinking since I posted this that my problem isn't as simple as I thought, since this solution would work if Instructors:Opportunities is 1:1, but it's 1:many. I don't want to confuse the instructor status by having multiple Opportunities, some ended, some Active, tied to the one instructor. 

 

I think what I need to do to ensure accurate instructor status is to search a related list of Opportunities on the Contact record to see if it contains an Opportunity with the Stage of Active. If so, I want to create a field update to change Employment Status on the Contact to Employed. 

 

Can Apex do this? Do you think I should make this a new topic? 

Ritesh AswaneyRitesh Aswaney

Don't think so, this topic should suffice.

 

So is it 1:n from Contacts to Opportunities or the other way round. Or is it n:n ? (Are you using Opportunity Contact Roles, or how are you establishing the relationship?)

 

Even if you had to iterate through all the Opps a Contact was associated with, and then set the Status to Employed if one of the Opps were Active - that's possible in Apex too.

CaitlinGMCaitlinGM

Yes, it is 1:n from Contacts:Opportunities. Each Opportunity has only one Instructor but each Instructor teaches multiple classes/Opportunities. 

 

We have a lookup custom field on Opportunity to Contact, and then a related list on Contact showing all Opportunities associated with one instructor. 

 

"Even if you had to iterate through all the Opps a Contact was associated with, and then set the Status to Employed if one of the Opps were Active - that's possible in Apex too."

 

That's great--exactly what is needed. Two questions: 

 

1) Can we also have instructor status change back to Available if an Active stage is no longer in the Opportunities list? 

2) If we have a second related list showing MTTs (custom object, another type of instructor project, connected to Contact in the same way) on the Contact, can we do the same thing for this second related list, either as part of the same trigger or with a second one? The goal is to see if the Contact has ANY projects with status as Active, stored in two lists on the record, and update the instructor status accordingly. 

 

Right now we have it set up so that we're actively tracking Opportunities. We will soon be actively using MTTs as well so I'd like to prepare for a way to track instructor employement across both.  

Ritesh AswaneyRitesh Aswaney

So you're looking to track changes in Opportunity and MTT Stages, in order to update the Contact (Instuctor) to Employed or Available.

 

This can be achieved by a trigger on Opp and a trigger on this MTT custom object - you wouldn't need to go the other way round i.e. iterate thru all Opps to update contact. It should be enuff to have a trigger on Opps, because a change event on them is what you're looking to capture. The other benefit of this of course is that when the Opp moves to Inactive, the trigger would mark the Contact as available.

 

I've written the trigger on Opp in my first response. (Happy to write you a refined version)

 

Also, you can get away with Aspira for the Opp - Contact update. (free for std objects). Though a trigger would be simple enough too.

CaitlinGMCaitlinGM

That's great. Just the one for Opportunities alone will get us a long way. Also, I'll take a look at Aspira and see what it can do. 

 

I'm wondering, though, if we'll have some conflict between the two triggers. Like I wouldn't want the Opp trigger to set Instructor status to Available if an Opportunity is Ended but an MTT is Active, but the trigger wouldn't know. In that case would the MTT one overrule the Opportunity one? 

 

Thanks for all your help. 

Ritesh AswaneyRitesh Aswaney

Which one would win would be down to you - as it would prolly need to be defined in the business logic in the trigger.

 

You could potentially have a  custom counter field on Contact - Active_Count__c. The triggers below could increment or decrement the counter depending on the transition of status.

 

Trigger on Opportunity

- If Active, Increment Active_Count__c. If Increment_Active_Count__c is now 1, Set to Employed

- If Inactive, Decrement Active Count. If Active Count = 0, set to Available

 

Trigger on MTT

- If Active, Increment Active_Count__c. Set to Employed if Active_Count__c is now 1

- If Inactive, Decrement Active Count. If Active Count = 0, set to Available

This was selected as the best answer
CaitlinGMCaitlinGM

OK, first I want to try out the Aspira solution for Opportunities. I'm having a little trouble envisioning how to set up my workflow rules before I create the relation.

 

I want to attach a field update on the Contact to workflow rule criteria on the Opportunity, but SF won't let me do that.  

 

Thanks for your continued help. 

Ritesh AswaneyRitesh Aswaney

Hey again.

Are you having trouble creating the relation in Aspira, or having created the relation - trouble creating the workflow?

CaitlinGMCaitlinGM

Hi, 

 

I understand how to set up the relation in Aspira, it's just setting up the workflow that I still don't understand. I set up a rule on Opportunities to act when the stage changes, but then I can't attach a field update on Contacts to that...

 

I could create a workflow rule on Contacts to activate every time it's edited, but that's not what I want, I want it to activate only when the criteria on Opportunities is met. Am I missing something? 

 

Also, I think ultimately the solution you presented with the counter field is what we need to do so that it also works for MTTs. Is there any chance you can help me out further with writing those triggers?

 

Thanks. 

gkluehgklueh

I have 2 questions about AspiraXObject...

 

1. Does AspiraXObject only work when the Workflow 'Evaluation Criteria' = "Every time a record is created or edited" and NOT work when set to "When a record is created, or when a record is edited and did not previously meet the rule criteria"?

2. Do you have to create a new trigger each time you create a new workflow or will the existing trigger work for all future workflows of the same record type?

NE NickNE Nick

Hey Every body i am new on saleforce i need help for expert sit out there other end of the world i want a tirrger on opportunity which update cumtom feild (Date Type Number) on contact when opportunity closed lost and closed Won i write the follwing code but its not working for me :( 
Any ideas on how I can accomplish this?

LIST<Contact>cont = new LIST <Contact> ();
   Set<id>oppids = new Set<id>();
    for(Opportunity o :Trigger.new){
        Contact c = new Contact();
        if(o.StageName == 'Closed-Won' && trigger.oldmap.get(oId) != 'Closed-Won' && c.Total_Won__c !=null){
        
        }
    }