[SalesForce] Class for Create Contract

I have created a new Apex Class called by a custom button that copy some field values from a opportunity and creates a new contract object with this information. I am trying to check if the opportunity stage is equal to Closed Won in order to executed all the commands in the class but it does not work. Is there an alternative way to do that? Follow is my apex class? Thanks in advance.

 public with sharing class CreateContract {

   Opportunity    opp;

public CreateContract(ApexPages.StandardController stdController) { 
   opp = (Opportunity)stdController.getRecord();     
}

public pagereference Create() {
    opp = [SELECT Id, accountId, Amount, CloseDate, StageName FROM Opportunity WHERE Id=:opp.Id];

   // Create the contract
    Contract c = new Contract();
    c.accountId = opp.accountId;
    c.ContractTerm = 12;
    c.StartDate = opp.CloseDate;
    c.OwnerExpirationNotice = '30';
   // c.Importe__c = opp.Amount;
    c.Amount__c = opp.Amount;
    insert c;
    // Activate the contract
    c.Status = 'Draft';

    update c;
    // Copy attchments
    list<Attachment> attlist = [SELECT Id, Name, Body FROM Attachment WHERE ParentId=:opp.id];
    for (Attachment att:attlist) 
     {
        Attachment a = new Attachment(ParentId = c.Id,
            Name = att.name,
            Body = att.body);
            insert a;
     }
    // Display the new contract
    pagereference p = new pagereference ('/'+c.id);
     p.setRedirect(true);      
     return p;
    }
  }

Best Answer

I didn't see any checking of closed won in your code, so I added the check to the SOQL query for the opportunity below. The try catch around the SOQL query will prevent any contracts from being created if the opportunity is not closed won. Also, you weren't handling the attachment cloning in bulk, so I adjusted that as well.

public with sharing class CreateContract {

    Opportunity    opp;

    public CreateContract(ApexPages.StandardController stdController) { 
        opp = (Opportunity)stdController.getRecord();     
    }

    public PageReference Create() {
        PageReference pageRef = null;
        try{
            //If opp was not closed won, then the query will throw a SOQL exception and no contracts are created.
            Opportunity opp = [SELECT Id, AccountId, Amount, CloseDate, StageName FROM Opportunity WHERE Id=:opp.Id And IsClosed = true and IsWon = true];

            //Create the contract
            Contract c = new Contract(
                AccountId = opp.AccountId
                ,ContractTerm = 12
                ,StartDate = opp.CloseDate
                ,OwnerExpirationNotice = '30
                ,Amount__c = opp.Amount
            );
            insert c;

            //Activate - does this need to be a separate DML transaction?
            c.Status = 'Active';
            update c;

            // Copy attachments
            //Better to do this DML in bulk... so created a list of new attachments
            List<Attachment> newAttachments = new List<Attachment>();
            for (Attachment att: [SELECT Id, Name, Body FROM Attachment WHERE ParentId=:opp.id]) {
                newAttachments.add(
                    new Attachment(
                        ParentId = c.Id
                        ,Name = att.name
                        ,Body = att.body
                    )
                );
           }
           insert newAttachments;

           pageRef = new PageReference ('/'+c.id);
           pageRef.setRedirect(true); 
       }catch(QueryException e){
           //Added example of how to represent an Apex Error in Visualforce using a CustomLabel (Setup->Create->Custom Label)
           ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL,Label.Could_Not_Find_Closed_Won_Opp));
       }catch(DMLException e){
           //Error handle not being able to insert Contract or its related attachments
       }

       return pageRef;
    }    
}
Related Topic