[SalesForce] Using a VF Page to upload a file to multiple records

So I'm a complete noob to custom dev (but studying to become a developer!).

I have been asked to create a visualforce page that uploads a file to multiple records (one account record and another contact record that is linked to the same account).

So far I have created a page and a controller but they are not complete and probably full of things that can be improved.

  • I'm getting the following error message when attempting to upload a file

Attempt to de-reference a null object
Error is in expression '{!createRecordAndAttachments}' in component in page attach_file_to_multiple_records: Class.AttachFileToMultipleRecordsController.createRecordAndAttachments: line 45, column 1

  • I also doubt the code is setup to upload the same file on to 2 records
  • The cancel button also doesn't return to the previous page

Any help or pointers to allow the code to upload a files to two places and get the cancel button working are appreciated!

Thanks!

Edit – I have worked on the suggestions provided by @battery.cord and cleaned up the vf page and class. I've got to a point where I'm unable to

  • pre-populate a lookup field on the visualforce page with a record id (the record id should be available when clicking the custom button to call the vf page)

VF Page

<apex:page controller="AttachFileToMultipleRecordsController">
<apex:form>
    <apex:pageblock>
        <apex:pageblockbuttons>
            <apex:commandbutton action="{!uploadAttachments}" value="Upload File"/>
            <apex:commandButton action="{!cancelUpload}" value="Cancel" immediate="true"/>
        </apex:pageblockbuttons>
        <apex:pageblocksection title="Attachment" columns="1">
            <apex:inputFile value="{!accountAttachment.body}" filename="{!accountAttachment.name}" />     
            <apex:outputLabel value="The maximum file size is 10 MB." />            
        </apex:pageblocksection>
        <apex:pageblocksection title="Choose Your Records" columns="1">
            <apex:inputField label="Account" id="Account" value="{!Cas.AccountID}" required="true"/>
            <apex:inputField label="Contact" id="Contact" value="{!Cas.ContactId}" required="true"/>
        </apex:pageblocksection>
    </apex:pageblock>
</apex:form>  

Controller

public with sharing class AttachFileToMultipleRecordsController {
public Account Acc                  { get; set; }
public Contact Ctct                 { get; set; }
public Case Cas                     { get; set; }
public Attachment accountAttachment { get; set; }
public Attachment contactAttachment { get; set; }
public String AccID                 { get; set; }

public AttachFileToMultipleRecordsController() {
    // Set variables
    Acc               = new Account();
    Ctct              = new Contact();
    accountAttachment = new Attachment();
    contactAttachment = new Attachment(); 
}

public void AccID(ApexPages.StandardController controller) {
    // Set Account ID in Lookup field
    Cas.AccountID = ApexPages.currentPage().getParameters().get('id'); 
}  

public PageReference uploadAttachments() {
    // Upload both Attachments;
    accountAttachment.ParentId = cas.AccountId;
    contactAttachment.ParentId = Ctct.Id;
    contactAttachment.Body     = accountAttachment.Body; 
    contactAttachment.Name     = accountAttachment.Name; 
    insert new List<Attachment>{ accountAttachment, contactAttachment }; 

    // Return to Account record
    return new PageReference('/'+Acc.Id);
}

public PageReference cancelUpload() {
    // Back to Account record
    {
      PageReference retPage = new PageReference('/'+apexPages.CurrentPage().getParameters().get('id')); 
      return retPage;
    }    
}

}

Best Answer

For the cancel button, you'll need to add immediate="true". Your page has required attributes, so when you try to direct the page, it also tries to submit the page. This is usually what causes my cancel buttons to fail.

I'd also remove the second Attachment record, and remove the transient keyword - I don't think your data is reaching the controller because of this keyword, but I'm not 100% sure.

Instead of having two records, create another record in the method, and pass your attachment data over to that record instead. You're also overwriting your account id when you change the parent id.

Try something like this instead:

accountAttachment.ParentId = LookUpAccountID.Id;

Attachment contactAttachment = new Attachment(); 
contactAttachment.ParentId = Ctct.Id;
contactAttachment.Body = accountAttachment.Body; 
contactAttachment.Name = accountAttachment.Name; 

insert new List<Attachment>{ contactAttachment, accountAttachment }; 

You also don't need to write full getters or setters to emulate their basic behavior, instead of:

public Case Cas
{ get
 {
    return Cas;
 } 
  set
 {
    Cas = value;
 }

}

You can write:

public Case Cas { get; set; } 

And it'll behave the same way.

Related Topic