You need to sign in to do that
Don't have an account?

Updating a Lookup(user) field with OpportunityContactRole in Trigger
I am trying to take whoever the primary user is in an opportunity's contact roles and populate a Lookup(user) field with this person but need a little help. This is what I have but i am missing some understanding of contactrole and user's id relationship. How would I accomplish this?
trigger UpdateOpportunityContact on Opportunity (after update, after insert) { List<OpportunityContactRole> contactRoles = new List<OpportunityContactRole>(); for( Opportunity acc : [ Select Id, (SELECT OpportunityId,IsPrimary,ContactId FROM OpportunityContactRoles) FROM Opportunity ]) { contactRoles.addALL(acc.OpportunityContactRoles); } for(Opportunity opp : trigger.new) { for(OpportunityContactRole role : contactRoles) { if(role.IsPrimary) { opp.Primary_Contact__c = new User(ContactId = role.ContactId); upsert opp.Primary_Contact__c; } } } }
Some feedback on your code before we move to the solution:
Why do you query all Opportunities in your system here?
for( Opportunity acc : [ Select Id, (SELECTOpportunityId,IsPrimary,ContactId FROMOpportunityContactRoles) FROM Opportunity ])
Just consider a scenario where you've millions of Opportunities, your code will stop working here itself because you haven't applied any filter.
Here, opp.Primary_Contact__c = new User(ContactId =role.ContactId); : you're referring a User in a lookup to Contact. This is incorrect.
It should ideally be;
opp.Primary_Contact__c = new Contact(Id = role.ContactId);
And also this line : upsert opp.Primary_Contact__c;
This shouldn't be in a FOR loop : as a golden rule to make a trigger bulk handled we are not supposed to write any SOQLs or DMLs inside a for loop.
Secondly, you're upserting a record not a field.
So your statement should have been
upsert opp;
All Answers
Some feedback on your code before we move to the solution:
Why do you query all Opportunities in your system here?
for( Opportunity acc : [ Select Id, (SELECTOpportunityId,IsPrimary,ContactId FROMOpportunityContactRoles) FROM Opportunity ])
Just consider a scenario where you've millions of Opportunities, your code will stop working here itself because you haven't applied any filter.
Here, opp.Primary_Contact__c = new User(ContactId =role.ContactId); : you're referring a User in a lookup to Contact. This is incorrect.
It should ideally be;
opp.Primary_Contact__c = new Contact(Id = role.ContactId);
And also this line : upsert opp.Primary_Contact__c;
This shouldn't be in a FOR loop : as a golden rule to make a trigger bulk handled we are not supposed to write any SOQLs or DMLs inside a for loop.
Secondly, you're upserting a record not a field.
So your statement should have been
upsert opp;
I have a question though, I was trying to do this through a subquery and it didn't return any results, can you see what I am doing wrong in the query? I am trying to learn as much as possible (i realize it isn't idea with creating a list for a single object and referring to the single item in the list array) :
trigger UpdateOpportunityContact on Opportunity (before update, before insert) {
List<OpportunityContactRole> contactRoles = new List<OpportunityContactRole>();
for( Opportunity acc : [ Select Id, (SELECT Id,OpportunityId,IsPrimary,ContactId FROM OpportunityContactRoles WHERE IsPrimary=true) FROM Opportunity where Id IN: trigger.new])
{
contactRoles.addALL(acc.OpportunityContactRoles);
if(contactRoles.size() > 0)
{
contactRoles.addALL(acc.OpportunityContactRoles);
for(User pUser : [Select id, Name From User WHERE id=:contactRoles[0].id])
{
acc.Primary_Contact__c = pUser.id;
}
}
}
}
Again thanks for your help!