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
Sachin Kumar 34Sachin Kumar 34 

Opportunity to Contract Data with New Contract

I want to transfer the data from opportunity to contract.
I had created CREATE CONTRACT button at opportunity page.
Now my requirement is that: Once opportunity will create and saved and user click on the CREATE CONTRACT button.
It will create a new contract for the same opportunity and pass all the field data from opportunity to contract.
So how can achieve this task (By Trigger, Classes or VF)
Best Answer chosen by Sachin Kumar 34
Agustina GarciaAgustina Garcia
Let me show you what I have in mind.

You can create a Visualforce page where the StandardController is Opportunity. Having that, you can got to Opportunity object and create a button similar to this one:

User-added image

Then the page can show Contract fields populated with Opportunity data. Doing in this way, you offer the end use the option to modify values if they want. But in order to do that you also need a Controller. 

In the Controller I would create a inner class with all Contract information. Then you can pre-populate it with Opportunity information. Finally Use the inner class to show the fields in the page.

The last step is the save button, Quite easy, use the fields data. 

Find bellow an example with a single field. You can extend it and add all data you need and also changes look and feel.

VisualforcePage
<apex:page standardController="Opportunity" extensions="CreateContractController">
    <apex:form >
        <apex:pageBlock title="New Contract">
            <apex:pageBlockButtons >
                <apex:commandButton action="{!saveContract}" value="Save"/>
				<apex:commandButton action="{!cancel}" value="Cancel"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Contract Header">
                <apex:inputText value="{!contractInfo.Name}" label="Contract Name"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Controller
public with sharing class CreateContractController
{
    private Id oppId;
    private ContractInfo conInfo;
    private ApexPages.StandardController controller;
    
    public CreateContractController(ApexPages.StandardController c)
    {
        controller = c;
        oppId = controller.getId();
        populateContractInfo(oppId);
    }
    
    public void populateContractInfo(Id opportunityId)
    {
        Opportunity opp = [Select Id, Name From Opportunity Where Id = :opportunityId limit 1];
        
        conInfo = new ContractInfo();
        conInfo.setName(opp.Name);
    }
    
    public ContractInfo getContractInfo()
    {
        return conInfo;
    }
    
    public void setContractInfo(ContractInfo value)
    {
        conInfo = value;
    }
    
    public PageReference saveContract()
    {
        Contract newContract = new Contract();
        
        newContract.Name = conInfo.getName();
        //Populate all required field

        insert newContract;
        
        return new PageReference('/'+newContract.id);
    }
    
    public Class ContractInfo
    {
        private String cName;
        
        public String getName()
        {
            return cName;
        }
        
        public void setName(String value)
        {
            cName = value;
        }
    }
}

Hope this helps

All Answers

Agustina GarciaAgustina Garcia
Actually you have 2 options.

1. Do not create a button and create a Trigger related to Opportunity. And clicking on Save button, a new Contract will be created with the Opportunity information. Something like this.
 
trigger CreateContract on Opportunity (after insert)
{
     //Collection of contracts
     List<Contract> newContracts =new List<Contract>();
 
     //Use loop to provide bulkification for future requirements
     for(Opportunity opp : trigger.new)
     {
         // For each Opportunity create a new Contract
         Contract newCon = new Contract();
         
         ....

         newContracts.add(newCon);
      }

      insert newContracts;         
}

But this mean to keep 2 things in mind:
- What about if you update the opportunity? Do you want to modify the existing and related Contract? Then you would need to add the after update as well.
- The new Contract is created behind the scene, so that you cannot navigate directly to the new Contract.

2. Create a button and link it to a visualforce page with a controller. This will allow you to navigate to the new Contract when the action is done, but what about if the end user forget to click on the button after creating the Opportunity? 

Both options are good. Actually the decition depends on requirements.

Hope this helps.
Sachin Kumar 34Sachin Kumar 34
@Agustina Garcia -  Currently i am using (1) - option, but got the new requirement.

I am looking for the (2) - option, that fulfill my requirement.
Req: Need to create the NEW CONTRACT button. once opportunity will create, user will click on the Button on that based CONTRACT will create.
Now I want to transfer all the record field data into the newly created Contract

 
Agustina GarciaAgustina Garcia
Let me show you what I have in mind.

You can create a Visualforce page where the StandardController is Opportunity. Having that, you can got to Opportunity object and create a button similar to this one:

User-added image

Then the page can show Contract fields populated with Opportunity data. Doing in this way, you offer the end use the option to modify values if they want. But in order to do that you also need a Controller. 

In the Controller I would create a inner class with all Contract information. Then you can pre-populate it with Opportunity information. Finally Use the inner class to show the fields in the page.

The last step is the save button, Quite easy, use the fields data. 

Find bellow an example with a single field. You can extend it and add all data you need and also changes look and feel.

VisualforcePage
<apex:page standardController="Opportunity" extensions="CreateContractController">
    <apex:form >
        <apex:pageBlock title="New Contract">
            <apex:pageBlockButtons >
                <apex:commandButton action="{!saveContract}" value="Save"/>
				<apex:commandButton action="{!cancel}" value="Cancel"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Contract Header">
                <apex:inputText value="{!contractInfo.Name}" label="Contract Name"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Controller
public with sharing class CreateContractController
{
    private Id oppId;
    private ContractInfo conInfo;
    private ApexPages.StandardController controller;
    
    public CreateContractController(ApexPages.StandardController c)
    {
        controller = c;
        oppId = controller.getId();
        populateContractInfo(oppId);
    }
    
    public void populateContractInfo(Id opportunityId)
    {
        Opportunity opp = [Select Id, Name From Opportunity Where Id = :opportunityId limit 1];
        
        conInfo = new ContractInfo();
        conInfo.setName(opp.Name);
    }
    
    public ContractInfo getContractInfo()
    {
        return conInfo;
    }
    
    public void setContractInfo(ContractInfo value)
    {
        conInfo = value;
    }
    
    public PageReference saveContract()
    {
        Contract newContract = new Contract();
        
        newContract.Name = conInfo.getName();
        //Populate all required field

        insert newContract;
        
        return new PageReference('/'+newContract.id);
    }
    
    public Class ContractInfo
    {
        private String cName;
        
        public String getName()
        {
            return cName;
        }
        
        public void setName(String value)
        {
            cName = value;
        }
    }
}

Hope this helps
This was selected as the best answer