Tuesday 17 September 2013

CUSTOM BUTTONS

CUSTOM BUTTONS IN  Particular RECORD DETAILPAGE  :
Below show Detail is my custom Button
Note : Detail Page link is same as Detail page Button..
Difference is  it is Button & link

Go to object detail pageà Custom Buttons and Links à newà

Select Radio Button ( Detail Page Button).

Select Visualforce pageà below displays content of standard VF page(use standard controller only). Then save

Then go to PageLayout Drag and drop the custom Button  then Save it.

Create one record

 





When we click on Show Detail Button it will display Below VF page:

<apex:page standardController="test__c" extensions="selectDetail">
 <apex:form >
   <apex:pageBlock mode="inlineEdit" >
  <apex:pageblockTable value="{!ll}" var="a">
    <apex:column value="{!a.name}"/>
    <apex:column value="{!a.Email__c}"/>
    <apex:column value="{!a.Gender__c}"/>
    <apex:column value="{!a.Phone__c}"/>
    <apex:column value="{!a.field1__c}"/>
    <apex:column value="{!a.field2__c}"/>
    <apex:column value="{!a.field3__c}"/>
    <apex:column value="{!a.field4__c}"/>
   </apex:pageblockTable>
   <apex:commandButton value="Save" action="{!mysave}"/>
   </apex:pageBlock>
  </apex:form>

</apex:page>


public with sharing class selectDetail {
    public selectDetail(ApexPages.StandardController controller) {
ll = [select id,name,Email__c,Gender__c,Phone__c,field1__c,field2__c,field3__c,field4__c from test__c  where id=:apexpages.currentpage().getparameters().get('id')];
 }
   public Pagereference mysave(){
    update ll;  
   pagereference pp= new pagereference('/'+ll.id);
   return pp;
   }
public test__c ll{get;set;}
}
Note: after save it, it will go to detail Page.

CUSTOM BUTTONS IN   RECORDS DETAILPAGE  :

Go to object detail pageà Custom Buttons and Links à newà

Fill the details:

Select Radio Button ( List Button).

Select Visualforce pageà below displays content of standard VF page(use standard controller only). Then save

Then go to Search Layout  click on edit Students(sobject) List Viewà

Add Button to right Save it

 

Click Sobject Records and click GO

 

 

 






Click on GO Button: display below
After Click on Details MS display as below:
<apex:page standardController="Student__c" recordSetVar="Rec" extensions="select1">
  <apex:form >
   <apex:pageBlock >
    <apex:dataTable value="{!rec}" var="a">
    <apex:column value="{!a.name}"/>
    <apex:column value="{!a.DOB__c}"/>
    <apex:column value="{!a.Email__c}"/>
    <apex:column value="{!a.Teacher_No__c}"/>
    </apex:dataTable>
  
   </apex:pageBlock>
  </apex:form>
</apex:page>
public with sharing class select1 {
public List<student__c> ll{get;set;}
    public select1(ApexPages.StandardSetController controller) {
       ll=controller.getSelected();
    }

}


Create and Email a PDF with Salesforce.com


This is a continuation of my post a couple of days ago, Attach a PDF to a Record in Salesforce, and shows how to dynamically generate a PDF and attach it to an email. The code is fairly similar and has the same issue with testing the PageReference getContent() method.

You can run this demo at my developer site.

PdfEmailer Visualforce Page
The Visualforce page simply allows the user to enter their email address and select a sample Account from the picklist. This is Account that is passed to the PdfGeneratorTemplate Visualforce page to generate the PDF.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<apex:page controller="PdfEmailController">
  <apex:sectionHeader title="PDF Example" subtitle="Email a PDF" 
    description="Example of how to email a dynamically generated PDF."/>
 
  <apex:form >
    <apex:pageMessages />
    <apex:pageBlock title="PDF Input">
 
      <apex:pageBlockButtons >
        <apex:commandButton action="{!sendPdf}" value="Send PDF"/>
      </apex:pageBlockButtons>
 
      <apex:pageBlockSection >
 
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Email to send to" for="email"/>
          <apex:inputText value="{!email}" id="email"/>
        </apex:pageBlockSectionItem>
 
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Account" for="account"/>
            <apex:selectList value="{!accountId}" id="account" size="1">
                 <apex:selectOptions value="{!accounts}"/>
            </apex:selectList>
        </apex:pageBlockSectionItem>
 
      </apex:pageBlockSection>
 
    </apex:pageBlock>
  </apex:form>
 
</apex:page>
PdfEmailerController
The Controller passes the Account ID that the user entered as a parameter for the Visualforce page being generated. It let creates the attachment from the PDF content. The Body of the attachment uses the Blob returned from the PageReference’s getContent method. You could also use the getContentAsPDF method which always returns the page as a PDF, regardless of the component’s renderAs attribute. However, this method always seems to throw an error in the test class. See the PageReference documentation for more info. The method then constructs the SimpleEmailMessage object and then sends it on its way to the recipient’s inbox.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public with sharing class PdfEmailController {
 
  public ID accountId {get;set;}
  public String email {get;set;}
 
  public List<SelectOption> accounts {
    get {
      if (accounts == null) {
        accounts = new List<SelectOption>();
        accounts.add(new SelectOption('0017000000LgRMb','United Oil & Gas Corp.'));
        accounts.add(new SelectOption('0017000000LgRMV','Burlington Textiles Corp of America'));
      }
      return accounts;
    }
    set;
  }
 
  public PageReference sendPdf() {
 
    PageReference pdf = Page.PdfGeneratorTemplate;
    // add parent id to the parameters for standardcontroller
    pdf.getParameters().put('id',accountId);
 
    // the contents of the attachment from the pdf
    Blob body;
 
    try {
 
      // returns the output of the page as a PDF
      body = pdf.getContent();
 
    // need to pass unit test -- current bug  
    } catch (VisualforceException e) {
      body = Blob.valueOf('Some Text');
    }
 
    Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
    attach.setContentType('application/pdf');
    attach.setFileName('testPdf.pdf');
    attach.setInline(false);
    attach.Body = body;
 
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setUseSignature(false);
    mail.setToAddresses(new String[] { email });
    mail.setSubject('PDF Email Demo');
    mail.setHtmlBody('Here is the email you requested! Check the attachment!');
    mail.setFileAttachments(new Messaging.EmailFileAttachment[] { attach }); 
 
    // Send the email
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Email with PDF sent to '+email));
 
    return null;
 
  }
 
}
PdfGeneratorTemplate Visualforce Page
This is the Visualforce page that is generated in the Controller. It simply uses the StandardController and displays the Account name for the ID passed to it.
1
2
3
4
<apex:page standardController="Account" renderAs="pdf">
  <h1>Congratulations!!</h1>
  <p>You created a PDF for {!account.name}</p>
</apex:page>
Test Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@isTest
private class Test_PdfEmailController {
 
  static Account account;
 
  static {
 
    account = new Account();
    account.Name = 'Test Account';
    insert account;
 
  }
 
  static testMethod void testPdfEmailer() {
 
    PageReference pref = Page.PdfEmailer;
    pref.getParameters().put('id',account.id);
    Test.setCurrentPage(pref);
 
    PdfEmailController con = new PdfEmailController();    
 
    Test.startTest();
 
    System.assertEquals(2,con.accounts.size());
 
    // populate the field with values
    con.accountId = account.id;
    con.email = 'test@noemail.com';
    // submit the record
    pref = con.sendPdf();
 
    Test.stopTest(); 
 
  }
}

Convert lead using apex

How to convert lead using Apex?
Sample Code:

Lead myLead = new Lead(LastName = 'Fry', Company='Fry And Sons');
insert myLead;

Database.LeadConvert lc = new database.LeadConvert();
lc.setLeadId(myLead.id);

LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);

Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());

Console Tab in Salesforce

Console Tab in Salesforce

The console is a tab that combines related records into one screen with different frames so that users have all the information they need when interacting with Salesforce. Common tasks are accomplished with fewer clicks and without much navigation. Administrators choose the information displayed in the console to accommodate varied and evolving business processes.

Setting up and using the Console tab:

1. Click Your Name --> Setup --> Customize --> Console --> Console Layouts.
 
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBdCSM_aNK4haY7VD0FuXNB5IPYF4AxAvXVXe2gS_bR0UXcCUFKixEFABkWHjLMqASduV7pLsMC5_DcUY9_FDjSVtoGXBbJXRSkEDVPf2-qfadfRz4XTmXaLnSGVdvANRW0zkBN7aHNI2P/s1600/console+navigation.png

2. Click "New Button" to create a Console Layout.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyknHcsAJiGteAcwzTEuM_BdOnQiJtfRL3U9M5-RtJxShBMCm9vb1AqqJMdTcaT0MhMdu-sYc625zeBRvTLGhB-mLbIOlSPRzJgXybyTlUw8YNLFpZU19xtAhRmo6OWI991dDiaYJ5Ausn/s1600/new.png


3. Enter the layout name and click "Save" button.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqC8Qd2Sk9uMzNipHjJhcwjfMvvi5eab2wGp28V0HpZO0JSnsR8tET8Pjlh67DPc3qyMX-tpO37uscPlb2I9JrQD0pwE2KoYkokvJ6Vl4OFIJnm0Ts8uj8yq3akfB7u7LWYz6SwmgBDzgZ/s1600/layout+name.png

4. Open the Console Layout and click "Edit" button in Selected List Views.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKd2wWpQVD8gEZfDEYQKnXi08H09GXkbCIgDglnRgcImCO3obbWybdllVvuAnwueKWLGROsVihXqwmp56sIn9_O-tkKhZ_ibZZvfm8BSEKb7Zn7-oRCz2vV8I-6q26z6D8mmc2UePm1zuV/s1600/edit+layout.png

5. Add or remove objects that you want users to choose from in the list view of the console and click "Save" button.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5IWJzKfbRpGGgk-wjgV5wfu2jgFfcDUM28lNCTRHYHS9mY27FRvcq0iVWaudyEa0nXMVD5loc3EQvc-rxWZGIiDO37txZQXUWGAiQ4yLPWbBL44Hh7nMked5xG7J1VF4CJdJrGCXGqrzE/s1600/add+or+remove.png

6. Go to Create --> Apps.

7. Click "Edit" link to the app in which you want Console tab.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDB07mrzpozKq-iFKimUgS3bOJ8pf2b7ntNO68mo2f67Xf-ERCiUIHpaylAvhBds-GEgn3Xtrt1YEbOgCIpf4xlKubqZ7fzVQfgkr5Iid_PWGi6UPdRtGgAViqdtf1FvuwqQz-VRh3ayAr/s1600/edit+app.png

8. Add Console tab to the Selected Tabs and click "Save" button.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-aHRi2EjKLLjl1bg6RoorSL6ANmGz3SfdKOvmujIAJhoLzyLaDPJ_LJJ9Z2CMDBrXBalOjs9z5AuvSLE-MH5IDj0e2aKQx9q8yXnFMB0fB-dk7hI42qAu8UvMPdYkOEcS9w9Ai7V-VEdP/s1600/adding+console+tab.png

9. Go to Console Layout and click "Console Layout Assignment" button.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP3-OACGhd3CZ-fcFlfdQJhjNu_Uj_jb2QF_LNcavbiVDCNevvCoIdHsCZv4CUyj6mpYEq9aJx-AZoMd0vjBBTdHKXdrvTAL6z_UduyKmRJSKZHrQszq6fM4Dtodxs9coRGhgL4nmRBg88/s1600/Console+Layout+Assignment.png

10. Assign it to the Profiles and click "Save" button.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAQvHomnfJYlCyqWsNDhtNo85qAmU9Rjr_JM0NP1sIBA-dA5zov8kuI7XhTx6531gnLm21qtP3wncIWOlp8T6gl3zbgxeHAAI5zGUjM2jpwmUodEzfYyOeAmYZgTf7n85DeuKAvEkMytI2/s1600/profile.png

11. Click "Console" tab to view it.
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEYcbMB-Rc-GZqXw1luwQ65tWSIjNRLRktPjcQGRookmQTWLvJKn1wGG11ESEmPykcseDeE5BTyRuym6duxUajRUxCdBbXrWKsmy7POV3AasH6LRrNL-sbOWeP3Z2YVmu0GhsQTKP_ua2A/s640/console+tab+sample.png


CONNECTING TO BOX API VERSION 2 USING OAUTH 2

CONNECTING TO BOX API VERSION 2 USING OAUTH 2
Box is a cloud storage provider that has an API for creating integrations.  Box provides its own AppExchange product for connecting custom and standard objects to files storage at Box.  Look for a whitepaper coming out soon that explains why there may be times when it is the best choice to store your files outside of Salesforce.
Here are the steps for connecting to Box’s REST API.  In my reading I learned that there was a direct connection option with a username and password with version 1 of the API, but with version 2 of the API you must use OAuth 2 to authenticate. 
1) Sign-up for a free personal Box account by going to this page and clicking on the ‘Sign Up’ button.
2) During the sign-up process an email will be sent to you and you will have to click on it to confirm the email account.
3) Log into your new Box account.
4) Go to this page and click on ‘Get Started Now’.
5) Go to this page and click on the ‘register for an API key’ link.
    a. Enter a new name for the application like ‘TestAPISundog’
    b. You will now receive your new API Key.  Copy that to a safe place.
6) We need to allow Salesforce to make outbound web service calls to Box.
    a. Log into Salesforce
    b. Click on Your Name, Setup
    c. Go to Administration Setup, Security Controls, Remote Site Settings
          i. Click on New Remote Site
          ii. Enter a name and the URL should be
 https://www.Box.com
          iii. Create another Remote site for
 https://api.Box.com
7) This page walks through how to connect to Box and get the OAuth code.
    a. Note that the only supported production authentication method with version 2 of the Box API seems to be OAuth 2.
    b. If you do not want to use OAuth 2 then this
 page gives some other options with using version one of the API.
    c. This
 page walks through how to verify the OAuth credentials using Postman.
    d. This
 page walks through all the steps with OAuth 2 for Box from authentication, to getting the access token, to making your first API call.
8) Now we are ready to try to connect to our Box account via the Version 2 of the API using OAuth 2.
9) Log into Salesforce
10) Create a Controller called BoxConnect.
  See code at the bottom of this post for the APEX code for that Controller…
  Again I tried to use as little code as possible to make the important pieces obvious.  A lot more needs to be done to this code before it is production ready such as responding to errors from Box.
  This code tries to do three things
    a. Redirect to Box so that the user can enter his/her credentials
          This is done in the boxConnect() method where a PageReference does this
          This code is hit when the CommandButton is clicked on the Visualforce Page
    b. Call Box to request an Access Token
          This is done in getBoxToken()
c. Use the Access Token to make any API calls
        The example API call here is in getBoxFolder() and it lists all of the files in the specified folder.
11) Create a Visualforce page called BoxConnect
      See code at the bottom of this post for the markup for the Visualforce Page…
12) To run this code add apex/BoxConnect to the end of your Salesforce URL
Upload Process Start
13) Click on the ‘Connect to Box’ CommandButton on the Visualforce Page
    a. This will redirect to Box.  Enter the Box credentials
 
Box Account Access
Box Allow Access

        This is done in the boxConnect() method where a PageReference does this
14) Fill in you username and password at Box
    a. Box will automatically send the page back to your Visualforce page because of redirect_uri parameter in the call to authorize via OAuth 2. 
 
    b. Note that the redirect_uri parameter is optional as it can be setup in the app within Box too.  If you do send it and it is not blank at Box, then it must match.
    c. You may have to change your URL from c.na9.visual.force.com to whatever your URL is.
15) Now Box will have redirected back to your page.  Now all of the action takes place in the Controller.
    a. In the constructor we check if the ‘code’ query string parameter is there.  If it is then we grab it and then try to ask for the access token.
    b. The access token code is in getBoxToken().  A HTTP POST call is made with all the needed items in the body.  Make sure you put them in the body and not as headers or query string parameters.  The values must be urlEndcoded and the ‘Content-Type’ and ‘charset’ values are also required.
    c. We now get back a JSON response that we can parse to get our access and refresh tokens.
    d. Now that we have our access token we can make any calls that we want to the API.
    e. The call in the code within getBoxFolder() is to
https://api.box.com/2.0/folders/FOLDER_ID/items, which will return all of the items, files and folders in this folder.  The only tricky part to this one is to get the Authorization header set correctly.
    f.       We again get a JSON value back which can be parsed using the built-in JSON parser in APEX.
    g. We now have the files that were in that specific folder.
         
Box Folder Response


16) Now that we have the code to A) Authenticate B) Get the Access Token and C) Make our first API call, we are now able to make any API calls that we need.
17) More code will have to be written to get a new access code using the refresh token as the access token is only good for 1 hour.  The refresh token also has a certain lifetime so if that is up, then the user will have to authenticate at Box again from the beginning of the OAuth 2.0 process.
APEX Controller Code…

public with sharing class BoxConnect {

    public string valueToShow{get;set;}
    private final string boxClientID ='myBoxClientID';
    private final string boxSecretCode ='myBoxSecretCode';
    private final string redirectURI ='https://c.na9.visual.force.com/apex/boxconnect';
    private string codeFromBox;
    private string accessToken;
    private string refreshToken;
     
    public BoxConnect(){
        valueToShow ='Start';
        //Check if we received the authorization code from Box because the redirectUI
        // URI points to this page.  It will look like this…
        codeFromBox = System.currentPageReference().getParameters().get('code');
        if(codeFromBox == null || codeFromBox ==''){
             
        }else{
            //Try to get a token and then make an API call to Box
            getBoxToken();         
        }
    }
     
    public pageReference boxConnect(){
        //Redirect to the OAuth page at Box so the login credentials can be entered.       
        PageReference pr = new PageReference('https://www.box.com/api/oauth2/authorize?' +
            'response_type=code' +
            '&client_id=' + boxClientID +
            '&redirect_uri=' + redirectURI);
        return pr;
    }  
     
    private void getBoxToken(){
    Http h = new Http();
        HttpRequest req = new HttpRequest();
        string endPointValue ='https://www.box.com/api/oauth2/token';
        req.setEndpoint(endPointValue);
        req.setBody('Content-Type=' + EncodingUtil.urlEncode('application/x-www-form-urlencoded', 'UTF-8') +
                    '&charset=' + EncodingUtil.urlEncode('UTF-8', 'UTF-8') +
                    '&grant_type=' + EncodingUtil.urlEncode('authorization_code', 'UTF-8') +
                    '&code=' + EncodingUtil.urlEncode(codeFromBox, 'UTF-8') +
                    '&client_id=' + EncodingUtil.urlEncode(boxClientID, 'UTF-8') +
                    '&client_secret=' + EncodingUtil.urlEncode(boxSecretCode, 'UTF-8') +
                    '&redirect_uri=' + EncodingUtil.urlEncode(redirectURI, 'UTF-8'));
        req.setMethod('POST');
        HttpResponse res = h.send(req);
        //Get back this… {"access_token":"RETURNED_ACCESS_TOKEN",
        //                  "expires_in":3600,
        //                  "refresh_token":"RETURNED_REFRESH_TOKEN",
        //                  "token_type":"bearer"}
        parseAuthJSON(res.getBody());
        if(accessToken != null & accessToken !=''){
            //Try to get items from a folder in Box
            getBoxFolder();
        }else{
            //Just some debug lines to see the request and response
            valuetoShow ='Get Authorization Code Return: ' + res.getBody() + ' end point value: ' + endPointValue + 'request: ' +
                req.toString() +'request headers: ' + req.getHeader('Content-Type') + '; ' + req.getHeader('charset') +
                'request body: ' + req.getBody();
        }      
    }
     
    private void getBoxFolder(){
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        string endPointValue ='https://api.box.com/2.0/folders/904543862/items'; //?limit=5&offset=0
        //Returns this: {"total_count":2,"entries":[
        //    {"type":"file","id":"8308841816","sequence_id":"0","etag":"0","sha1":"6dce26ad1a3578a00a40722ec4472abc143313cf",
        //      "name":"Luschen Quote for West Fargo Property.pdf"},
        //    {"type":"file","id":"8308878690","sequence_id":"1","etag":"1","sha1":"5b595457a86396ddf45318d1ab9ddd6aa3b7bc1e",
        //      "name":"New Google Doc 1.gdoc"}
        //    ],"offset":0,"limit":100,"order":[{"by":"type","direction":"ASC"},{"by":"name","direction":"ASC"}]}
         
        //This one works to get the properties for a specific file     
        //endPointValue ='https://api.box.com/2.0/files/8308878690?fields=modified_at,path_collection,name';
        //Returns this {"type":"file","id":"8308878690","etag":"1","modified_at":"2013-05-25T16:08:52-07:00",
        //   "path_collection":{"total_count":2,"entries":[
        //    {"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files"},
        //    {"type":"folder","id":"904543862","sequence_id":"1","etag":"1","name":"Buy Fargo Home"}
        //    ]},"name":"New Google Doc 1.gdoc"}
        req.setEndpoint(endPointValue);
        req.setHeader('Authorization', 'Bearer ' + accessToken);
        req.setMethod('GET');
        HttpResponse res = h.send(req);
        //Now we could parse through the JSON again and get the values that we want
        valuetoShow ='Get Folder: ' + res.getBody();  
    }
     
    private void parseAuthJSON(string JSONValue){
        JSONParser parser = JSON.createParser(JSONValue);
        accessToken ='';
        refreshToken ='';
        while (parser.nextToken() != null) {
            if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
                if(parser.getText() =='access_token'){
                    parser.nextToken();
                    accessToken = parser.getText();
                }
                if(parser.getText() =='refresh_token'){
                    parser.nextToken();
                    refreshToken = parser.getText();
                }
            }
            if(accessToken !='' && refreshToken != ''){
                break;
            }
        }
    }
     
}
Visualforce Code…

<apex:page showheader="false" sidebar="false" cache="false" contenttype="text/html" controller="BoxConnect">
    <apex:form>
        <apex:commandbutton id="connectToBox" value="Connect to Box" action="{!boxConnect}">
        </apex:commandbutton>
        <apex:outputtext id="outputText" value="{!valueToShow}">
        </apex:outputtext>
    </apex:form>
</apex:page>