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
albonillalbonill 

Need to auto-populate Opportunity contact

Hello,

 

I am new to Apex so I would like assistance in creating a trigger to automatically update the Opportunity Contact field, with the contact designated as the Renewal Owner (Contact Type) in the contact description.  We have added a field named Contact Type to the Contacts so that we know who to send renewal contracts to.

 

Field Name (field type): API Name:
Opportunity Contact (Lookup(Contact)): Opportunity_Contact__c

Contact type (Picklist): Contact_Type__c

 

The objective of the trigger is to eliminate the need to have to select the contact in the Opportunity Contact lookup field.  This trigger should only fire once (when a new Opportunity is created) and not when someone updates the Opportunity.  If someone wants to change the Opportunity contact to someone else, later on, they should be able to edit that field as well.  Thanks for the help with this.

Best Answer chosen by Admin (Salesforce Developers) 
Eugene NeimanEugene Neiman

Try this

 

 for (List<Contact> contactlist : [SELECT id FROM Contact WHERE AccountId = :opty.AccountId  AND Contact_Type__c = 'Renewal Owner' LIMIT 1]) {

All Answers

Eugene NeimanEugene Neiman

Try something like this:

 

trigger setRenewalOwnerContact on Opportunity (before insert) {

 

 List<Opportunity > optylist = Trigger.new;
  for ( Opportunity opty : optylist ) {
   if (opty.Opportunity_Contact__c == null) {
    for (List<Contact> contactlist : [SELECT id FROM Contact WHERE AccountId = :opty.Account__c AND Contact_Type__c = 'Renewal Owner' LIMIT 1]) {
     for(Contact con : contactlist ) {
        opty.Opportunity_Contact__c = con.id;
     }
    }
   }
  }

}

albonillalbonill

Thanks for the help Eugene.  I pasted your code and this is the message I received:

 

ErrorError: Compile Error: Invalid field Account__c for SObject Opportunity at line 8 column 81

 

The Account object is just "Account" I believe.  I changed it to this in line 8:

 

for (List<Contact> contactlist : [SELECT id FROM Contact WHERE AccountId = :opty.Account AND Contact_Type__c = 'Renewal Owner' LIMIT 1]) {

 

and I received this error message:

Error

Error: Compile Error: Invalid bind expression type of SOBJECT:Account for column of type Id at line 8 column 81

 

I appreciate your help.

SamuelDeRyckeSamuelDeRycke

Try this: 

 

List<Contact> contactlist : [SELECT id FROM Contact WHERE Account = :opty.Account AND Contact_Type__c = 'Renewal Owner' LIMIT 1])

 

edit: nvm this is wrong.

albonillalbonill

Here is the modified code, but I now receive the following error message:

ErrorError: Compile Error: No such column 'Account' on entity 'Contact'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. at line 8 column 38

 

trigger setRenewalOwnerContact on Opportunity (before insert) {

 

 List<Opportunity > optylist = Trigger.new; 
  for ( Opportunity opty : optylist ) {
   if (opty.Opportunity_Contact__c == null) {
    for (List<Contact> contactlist : [SELECT id FROM Contact WHERE Account = :opty.Account AND Contact_Type__c = 'Renewal Owner' LIMIT 1]) { 
     for(Contact con : contactlist ) {
        opty.Opportunity_Contact__c = con.id;
     }
    }
   }
  }

}

 Any suggestions?

albonillalbonill

I was able to save the trigger by making the modificaitons below (using "Account.Name" instead of "Account":

 

trigger setRenewalOwnerContact on Opportunity (before insert) {

 

 List<Opportunity > optylist = Trigger.new; 
  for ( Opportunity opty : optylist ) {
   if (opty.Opportunity_Contact__c == null) {
    for (List<Contact> contactlist : [SELECT id FROM Contact WHERE Account.Name = :opty.Account.Name AND Contact_Type__c = 'Renewal Owner' LIMIT 1]) { 
     for(Contact con : contactlist ) {
        opty.Opportunity_Contact__c = con.id;
     }
    }
   }
  }
  
}

I created a new Opportunity and saved it, but it still isn't populating the Opportunity contact with the Contact that is tagged as the Renewal Owner.  What is missing? 

 

Eugene NeimanEugene Neiman

Try this

 

 for (List<Contact> contactlist : [SELECT id FROM Contact WHERE AccountId = :opty.AccountId  AND Contact_Type__c = 'Renewal Owner' LIMIT 1]) {

This was selected as the best answer
SamuelDeRyckeSamuelDeRycke

update opty;

 

this better not be wrong too :P

albonillalbonill

Hello Eugene,

 

I made the change you suggested, but still nothing.  I was reviewing the code and I don't see, or understand, where we are instructing the trigger to populate the Opportunity_Contact__C field with the First and Last Name of the contact that is tagged as the Renewal Owner.  Thanks again.

 

Regards,

Alex Bonilla

albonillalbonill

Hello Sdry,

 

Excuse my ignorance, but what should I update opty to?

SamuelDeRyckeSamuelDeRycke

"

Hello Sdry,

Excuse my ignorance, but what should I update opty to?"

 

Eugene's code was already updating the object, but not sending those changes back to salesforce database. Have a look at the code below, which is part of the trigger posted above.

 

You told us Opportunity_Contact__C is a Contact lookup, so we should not try to populate the firstname and lastname, but fill in the contact ID in the lookup relation field. Which is what Eugene's code does.

 

//this part will attach the ID of the contact with Contact_Type__c = 'Renewal Owner', from the account your opportunity belongs to. Establishing the lookup relation.

for(Contact con : contactlist ) {
        opty.Opportunity_Contact__c = con.id;
        //what I think he forgot is:
        update opty;
        //usually you shouldn't do dml statements in a for loop, but we know there will only be one (or zero) iterations because of the limit clause in the soql.
}

 caevat: I've only started with salesforce and apex myself recently too, I could be wrong too.

albonillalbonill

Thanks for all your help Eugene!  Your last suggestion did the trick.  Have a great day!

 

 

Regards,

 

Alex Bonilla

Eugene NeimanEugene Neiman

Because the trigger is on the opportunity, you do not need to specifically update the opportunity.  By establishing a join from your opportunity directly to your contact, the other contact fields will populate.  However, as Opportunities connect to Accounts which connect to Contacts, what this code does is to search for a Renewal Owner associated with the account associated with the opportunity.  If one doesn't exist, the opty contact will not populate.

 

I based my suggestion on a working trigger I wrote to pick "drop contacts" for a "site", not unlike what you are attempting to do.

SamuelDeRyckeSamuelDeRycke

Because the trigger is on the opportunity, you do not need to specifically update the opportunity

 

That is the case because it's a before trigger , and would only work in a before insert/update ? Hadn't thought of that. Glad to learn.