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
mgodseymgodsey 

Prepopulating Contact Role on New Opportunity

Our org currently has a custom opportunity button that is displayed in the contact page list view. When creating the new opportunity, the opportunity contact role defaults to the contact the opp was created from by using the following parameter:

conid={!Contact.Id}

Now we are trying to completely override the standard 'New' Opportunity page with a Visualforce page. Is there anyway to default the Opportunity Contact Role if I am passing in the contact Id through a custom button? Or will I have to store this Id somewhere, and then write a trigger after insert to create the Opportunity Contact Role?

Below is some of the extension code for the VF page. Thanks for any guidance!

public with sharing class OpportunityNewExtension {
    private Opportunity currentOpp;
   
    //following Ids are passed in through the custom button
    public Id accountId;
    public Id contactId;

    public OpportunityNewExtension(ApexPages.StandardController controller) {
       
        //get information about the opportunity and related account
        currentOpp = (Opportunity)controller.getRecord();
        accountId = ApexPages.currentPage().getParameters().get('accountId');
        Account acct = [SELECT Type, BillingCountry FROM Account WHERE Id=: accountId];

        //set default values for required fields
        currentOpp.StageName = Status.Omit;
        currentOpp.Name = 'Default'; //will be updated via workflow on save
        currentOpp.CloseDate = System.today()+30;
Best Answer chosen by mgodsey
James LoghryJames Loghry
Not sure how you are calling the page, but you need someway of passing in your default contact Id like you're asking.  You can either do this as an Http parameter e.g. /id=oppid?contactId=yourdefaultcontactId, or you could store the default contact id in a custom setting, so that's manageable by an administrator.

The example below shows where your constructor would read in a http parameter called "contactId".

Save the contactId as a member variable, and then when you create the Opportunity you would also create the first OpportunityContactRole and associate it with the default contact id. 

public with sharing class OpportunityNewExtension {
    private Opportunity currentOpp;
  
    //following Ids are passed in through the custom button
    public Id accountId;
    public Id contactId;

    public OpportunityNewExtension(ApexPages.StandardController controller) {
      
        Map<String,String params = ApexPages.currentPage().getParameters();
        //get information about the opportunity and related account
        currentOpp = (Opportunity)controller.getRecord();
        accountId = params.get('accountId'); //doesnt natively come from contact detail page / vf button.. 
        contactId = params.get('contactId'); //assuming VF button, coming from contact detail page.

        Account acct = [SELECT Type, BillingCountry FROM Account WHERE Id=: accountId];

        //set default values for required fields
        currentOpp.StageName = Status.Omit;
        currentOpp.Name = 'Default'; //will be updated via workflow on save
        currentOpp.CloseDate = System.today()+30;


Then when you save the Opportunity, you'd also create a Opportunity Contact Role for that Opportunity.  Note, you can't create the OCR before the Opportunity if the Opportunity does not exist yet.

public PageReference saveOppAndCreateOCR(){
    insert currentOpp;

    OpportunityContactRole ocr = new OpportunityContactRole(
        OpportunityId=currentOpp.Id
        ,ContactId = contactId
    );
    insert ocr;
}

All Answers

James LoghryJames Loghry
Not sure how you are calling the page, but you need someway of passing in your default contact Id like you're asking.  You can either do this as an Http parameter e.g. /id=oppid?contactId=yourdefaultcontactId, or you could store the default contact id in a custom setting, so that's manageable by an administrator.

The example below shows where your constructor would read in a http parameter called "contactId".

Save the contactId as a member variable, and then when you create the Opportunity you would also create the first OpportunityContactRole and associate it with the default contact id. 

public with sharing class OpportunityNewExtension {
    private Opportunity currentOpp;
  
    //following Ids are passed in through the custom button
    public Id accountId;
    public Id contactId;

    public OpportunityNewExtension(ApexPages.StandardController controller) {
      
        Map<String,String params = ApexPages.currentPage().getParameters();
        //get information about the opportunity and related account
        currentOpp = (Opportunity)controller.getRecord();
        accountId = params.get('accountId'); //doesnt natively come from contact detail page / vf button.. 
        contactId = params.get('contactId'); //assuming VF button, coming from contact detail page.

        Account acct = [SELECT Type, BillingCountry FROM Account WHERE Id=: accountId];

        //set default values for required fields
        currentOpp.StageName = Status.Omit;
        currentOpp.Name = 'Default'; //will be updated via workflow on save
        currentOpp.CloseDate = System.today()+30;


Then when you save the Opportunity, you'd also create a Opportunity Contact Role for that Opportunity.  Note, you can't create the OCR before the Opportunity if the Opportunity does not exist yet.

public PageReference saveOppAndCreateOCR(){
    insert currentOpp;

    OpportunityContactRole ocr = new OpportunityContactRole(
        OpportunityId=currentOpp.Id
        ,ContactId = contactId
    );
    insert ocr;
}

This was selected as the best answer
AshlekhAshlekh
Hi,

If you write a trigger then It will execute every time when the trigger event occur and second thing you have to keep the id of contact in some where like in custom setting. So this way you are hardcode the id in somewhere. It this approach full fill your requirment the you can with this way. Other way is assign the conact id at the time of DML operation.
David "w00t!" LiuDavid "w00t!" Liu
Agree that the URL parameter solution that James outlined is simpler and cleaner than the trigger method. 

It requires no triggers, no additional fields to store values, and you don't need to worry about scenarios where Salesforce automatically creates a Contact Role where you might be duplicating work. 

Also, you can probably implement James' code in less than 5 minutes!