Thursday, April 26, 2012

Uploading an Attachment using Visualforce and a Custom Controller in Salesforce

Upload a file as an Attachment to a record using Visualforce and Extensions


In Salesforce we can easily upload a file through attachment by simply making and an extension on any object and using Visualforce page for inserting a new attachment.

Goal:--Our goal is that we want to make a custom button on account and then by onclick on this custom button which is there on detail page of any individual account  we are redirected to a page which is designed for inserting a new attachment and onclick on "upload Attachment" button on VF Page Parent Window is reloaded through JavaScript and Child window Close automatically.

Finally we easily see this attachment on page in notes and attachment Section on the page and inspite of this there is a custom page is there is also for designing "Notes & Attachment" related list through page in which we also have Serial no. corresponding to each record implement there by use of Wrapper Class. 

 So finally We have :--

 Step 1:--- 

1. Apex Class ===> Have Wrapper Class and Code for making Custom "Notes & Attachment" related list (which is show on page by editing page Layout ) and here have a extension (therefore we can now use Custom Button functionality)

2. Now Page is designed for  Custom "Notes and Attachment" related List.

 Note:--- In case of Custom "Notes & Attachment" related list for data Parent is required therefore extension comes in existence.

Code :---

Apex Class:---

public class NotesAttachmentModelController{
    public List<Attachment> attachmentList{set;get;}
    public List<Account> allAccounts{get;set;}
    public List<AttachmentModel> modelList{get;set;}
    public Integer srNo{get;set;}
    Account acc;
    public NotesAttachmentModelController(ApexPages.StandardController sc){
        acc = (Account)sc.getRecord();
        allAccounts = [SELECT id,name from account where id=:acc.id];
        attachmentList = [SELECT id,name,ContentType,OwnerId,ParentId from Attachment
                           where ParentId =: acc.id];
        system.debug('#################### value in Attachment List'+attachmentList);
        srNo=0;
        integer  i =0;
        modelList = new List<AttachmentModel>();
        for(Attachment att : attachmentList){
            AttachmentModel am = new AttachmentModel();
            am.srno = ++i;
            am.att = att;
            modelList.add(am);
        }
    }
    public class AttachmentModel{
        public Integer srNo{get;set;}
        public Attachment att{get;set;}
        public AttachmentModel(){
            srNo = 0;
            att = new Attachment();
             
        }
    }
}
 
 
 
Page:----
  
<apex:page standardController="Account" extensions="NotesAttachmentModelController">
  <apex:form >
      <apex:pageBlock title="Notes & Attachment">
      <apex:pageBlockButtons >
          <apex:commandButton value="Add Note"/>
          <apex:commandButton value="Attach Fil"/>
          <apex:commandButton value="View All"/>
      </apex:pageBlockButtons>
          <apex:pageBlockTable value="{!modelList}" var="mod">
              <apex:column headerValue="Srno" value="{!mod.srno}"/>
              <apex:column value="{!mod.att.name}" headerValue="Name"/>
              <apex:column headerValue="Type">
              <apex:outputText value="{!mod.att.ContentType}"/>
              </apex:column>
              <apex:column headerValue="Owner">
              <apex:outputText value="{!mod.att.OwnerId}"/>
              </apex:column> 
              <apex:column headerValue="ParentId">
              <apex:outputText value="{!mod.att.ParentId}"/>
              </apex:column>
          </apex:pageBlockTable>
      </apex:pageBlock>
  </apex:form>
</apex:page> 
 
Test Class:---
 
@isTest
public class TestNotesAttachmentModelController{
public static TestMethod void runTest(){
    Account acc = new Account(Name ='Test iBirds');
    insert acc;
     Attachment attach=new Attachment();    
     attach.Name='Unit Test Attachment';
     Blob bodyBlob=Blob.valueOf('Unit Test Attachment Body');
     attach.body=bodyBlob;
     attach.parentId=acc.id;
     insert attach;
     ApexPages.StandardController sc = new ApexPages.StandardController(acc);
     NotesAttachmentModelController na = new NotesAttachmentModelController(sc);
    }
}
 
After this we implement logic for attachment insertion on parent and 
automatic reload of Parent Page through JavaScript.
 
Apex Class:---
 
Now on click on Custom Button Class uploadAttachmentAssignmentController execute.

 
 
public class uploadAttachmentAssignmentController{  
    public Id recId{get;set;}
    public string fileName{get;set;}  
    public Blob fileBody{get;set;}
    public boolean isSaved{get;set;}  
    public Attachment myAttachment{get;set;}
    public uploadAttachmentAssignmentController(ApexPages.StandardController ctlr){  
        recId = ctlr.getRecord().Id;
        isSaved = false; 
    }          
    public PageReference UploadFile(){  
       isSaved = true; 
        if(fileBody != null && fileName != null)  
        {  
            Attachment myAttachment  = new Attachment();  
            myAttachment.Body = fileBody;  
            myAttachment.Name = fileName;  
            myAttachment.ParentId = recId;
            insert myAttachment; 
           // isSaved = true; 
            system.debug('############# value of isSaved'+isSaved);
        } 
          return null;  
    }   
}
 
Page:---
 
<apex:page id="pg" standardController="Account" extensions="uploadAttachmentAssignmentController">
    <apex:form id="pgb" >
            <apex:pageBlock title="Upload Attachment">         
                <apex:inputFile style="width:100%" id="fileToUpload" value="{!fileBody}" 
                  filename="{!fileName}" />  
                <apex:commandButton value="Upload Attachment" action="{!UploadFile}" />  
                
            </apex:pageBlock> 
             </apex:form> 
              <script>
              alert({!isSaved});
                if({!isSaved} == true){
                alert({!isSaved});
        window.opener.location.reload();
        window.close();
        }
    </script>
</apex:page> 
 
Finally job is completely Done. Enjoy Code and implement thinking.
 
                                         -----Abhinav Sharma 
 
 
 

Saturday, April 21, 2012

Salesforce: System.Assert v/s System.AssertEquals

System.Assert v/s System.AssertEquals

If we talk out main differences in between to then we found out that:-

System.Assert accepts two parameters, one (mandatory) which is the condition to test for and the other a message (optional) to display should that condition be false.

System.AssertEquals and System.AssertNotEquals both accepts three parameters; the first two (mandatory) are the variables that will be tested for in/equality and the third (optional) is the message to display if the assert results in false.

Now testing best practices state that you should assert some condition but also output a “console” message that shows the values of each of the operands. This certainly helps you debug unit tests when asserts are failing,It is like wasting time to check out some variable values! So the time saving trick that isn’t obvious is that when omitting the optional third parameter for System.AssertEquals and System.AssertNotEquals the compiler automatically outputs the values of the operands to the console log. That’s right, instead of typing:

In Case of System.Assert

 System.assert(var1 == var2, "The value of var1 is: " +var1 + " and the value of... oh hell I  don't care I mean it's just a variable");

You could type:

System.assertEquals(var1, var2);

If the second assertion fails the console will output the values of var1 and var2 with the labels “expected” and “actual”. Knowing this now I can see no exceptional reason to use System.assert any longer.
Example for System.Assert

/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 *
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest
private class TestCheckInTrigger {
    static testMethod void myUnitTest() {
      
        // Insert Room
          Room__c room = new Room__c(Rent__c=2000.00, Type__c='AC',Room_No__c='RN_121'; );
          insert room;
      
        //Insert Customer
          Customer__c customer = new Customer__c(Gender__c = 'Male',First_Name__c ='Abhinav', 
                                                                                  Nationality__c ='Indian' );
           insert customer;
      
        // Insert Booking
         Booking__c booking = new Booking__c(room__c = room.id, Customer__c = customer.id,
                                                                           Status__c ='Check In');    
        //Start Test From Here
         test.startTest();
      
        try {
             insert booking;
           
        } catch (DmlException e) {
          
            //Assert Error Message
            System.assert( e.getMessage().contains('Insert failed. First exception on ' +
                'row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ' +
                'Enter the Check In Time value'),
                e.getMessage() );
                
            //Assert field
            System.assertEquals(Booking__c.Check_In_Time__c, e.getDmlFields(0)[0]);
          
            //Assert Status Code
            System.assertEquals('FIELD_CUSTOM_VALIDATION_EXCEPTION' ,
                                 e.getDmlStatusCode(0) );
        }
    }
    static testMethod void myUnitTest1() {
  
         // Insert Room
          Room__c room = new Room__c(Rent__c=2000.00, Type__c='AC',Room_No__c='RN_121'; );
          insert room;
      
        //Insert Customer
          Customer__c customer = new Customer__c(Gender__c = 'Male',First_Name__c ='Abhinav',
                                                                                  Nationality__c ='Indian' );
           insert customer;
      
        // Insert Booking
         Booking__c booking = new Booking__c(room__c = room.id, Customer__c = customer.id,
                                                      Status__c ='Check In', Check_In_Time__c = system.Now());
      
         insert booking;
      
        //Start Test From Here
         test.startTest();
      
        //Asserting Results
            System.assertEquals(false, booking.Id == null);
    }
    static testMethod void myUnitTest2() {
        
  // Insert Room
          Room__c room = new Room__c(Rent__c=2000.00, Type__c='AC',Room_No__c='RN_121'; );
          insert room;
      
        //Insert Customer
          Customer__c customer = new Customer__c(Gender__c = 'Male',First_Name__c ='Abhinav', 
                                                                                  Nationality__c ='Indian' );
           insert customer;
      
        // Insert Booking
         Booking__c booking = new Booking__c(room__c = room.id, Customer__c = customer.id,
                                                         Status__c ='Check In', Check_In_Time__c = system.Now(),
                                                         Check_Out_Time__c = system.Now().addDays(2));
      
       //Start Test From Here
        test.startTest();
      
        try {
             insert booking;
           
        } catch (DmlException e) {
          
            //Assert Error Message
            System.assert( e.getMessage().contains('Insert failed. First exception on ' +
                'row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ' +
                'if Status is Check in then Check out time Should not be there'),
                e.getMessage() );
                
            //Assert field
            System.assertEquals(Booking__c.Check_Out_Time__c, e.getDmlFields(0)[0]);
          
            //Assert Status Code
            System.assertEquals('FIELD_CUSTOM_VALIDATION_EXCEPTION' ,
                                 e.getDmlStatusCode(0) );
        }
    }
}

As illustrated you can you system.Assert in Test Classes.At Least 75% code coverage is required.

Sample Assertion Message




Friday, April 20, 2012

Difference in between different Visualforce Table Tags in Salesforce

Different Table Tags


Apex: dataTable
An HTML table that is defined by iterating over a set of data, displaying information about one item of data per row. The body of the < apex:dataTable > contains one or more column components that specify what information should be displayed for each item of data. The data set can include up to 1,000 items.





 Apex: pageBlockTable
A list of data displayed as a table within either an < apex:pageBlock > or <apex:pageBlockSection > component, similar to a related list or list view in a standard Salesforce page. Like an < apex:dataTable >, an < apex:pageBlockTable > is defined by iterating over a set of data, displaying information about one item of data per row. The set of data can contain up to 1,000 items.The body of the < apex:pageBlockTable > contains one or more column components that specify what information should be displayed for each item of data, similar to a table. Unlike the < apex:dataTable > component, the default styling for < apex:pageBlockTable > matches standard Salesforce styles. Any additional styles specified with < apex:pageBlockTable > attributes are appended to the standard Salesforce styles.

 

Apex: repeat
This tag is used as for loop(for list) in apex. You can iterate a list.




Now Difference:--

1. By using <apex:repeat> we can't get proper alignments,just it displays data,but in <apex:dataTable> we can get columns wise alignment data.

2.In <apex:repeat> there is no JavaScript events like onmouseover, onclick..........but they are available in <apex:dataTable>.

3. Main Difference Between <data:table> and <apex:pageBlockTable> is,Unlike the  <apex:dataTable > component, the default styling for < apex:pageBlockTable > matches standard Salesforce styles. Any additional styles specified with 
< apex:pageBlockTable > attributes are appended to the standard Salesforce styles.

Summary

PageBlockTable:
-> Pageblocktable should be inside of <apex:pageblock> or <apex:pageblocksection>
-> <apex:pageblocktable> has a required attribute called "value"
-> It uses the standard salesforce page styles
-> Column headers will be displayed automatically

DataTable:
-> No need to write inside <apex:pageblock> or <apex:pageblocksection>
-> There is no required value
-> The data can be displayed using custom styles
-> We need to specify column headers explicitly

Repeat:
-> There is no proper allignment of data in repeat as compared with datatable