Thursday 28 August 2014

Creating Progress Bar field using Formula| Without any coding

In this post we will discuss on creating Progress bar field without any coding, just by using formula field. Initially it seems like we can’t create dynamic progress bar field by using only formula in Salesforce. There are some approach, where developers stores 4 images with interval of 25% or 10 images with 10% interval and displaying image with help of Case or IF statement.
We will create Progress bar field, which will reflect every percentage.
Progress Bar using Formula field in Salesforce
Progress Bar using Formula field in Salesforce
To create perfect Progress bar field, we will need to take help of two images.
  1. Empty filled image with border (Download Sample)
  2. Filled rectangular image (Download Sample)
Upload above two images in Static resource. Once it is uploaded create a formula field.
In Formula field we will be appending both images and repeating “Filled Image” as per percentage field. Logic can be seen in below image.
Logic for Progress Bar using Formula field in Salesforce
Logic for Progress Bar using Formula field in Salesforce
Formula for Progress Bar Image
1IMAGE('/resource/1398170360000/BlueProgressBar''Test'10, ( percField__c * 100 )) &
2IMAGE('/resource/1398170333000/ProgressBorder''Test'10, (100 - percField__c * 100 )) &
3' ' &
4TEXT (percField__c * 100) &
5'%'

Wednesday 13 August 2014

Batch Apex in Salesforce

To use batch Apex, you must write an Apex class that implements the Salesforce-provided interfaceDatabase.Batchable, and then invoke the class programmatically.

To monitor or stop the execution of the batch Apex job, go to Setup --> Monitoring --> Apex Jobs. For more information, see “Monitoring the Apex Job Queue” in the Salesforce online help.

The Database.Batchable interface contains three methods that must be implemented:
 start method
global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}
The start method is called at the beginning of a batch Apex job. Use the start method to collect the records or objects to be passed to the interface method execute. This method returns either a Database.QueryLocator object or an iterable that contains the records or objects being passed into the job.
execute method:
global void execute(Database.BatchableContext BC, list<P>){}
The execute method is called for each batch of records passed to the method. Use this method to do all required processing for each chunk of data.

This method takes the following:
o             A reference to the Database.BatchableContext object.
o             A list of sObjects, such as List<sObject>, or a list of parameterized types. If you are using aDatabase.QueryLocator, the returned list should be used.
Batches of records are not guaranteed to execute in the order they are received from the start method.
finish method
global void finish(Database.BatchableContext BC){}
The finish method is called after all batches are processed. Use this method to send confirmation emails or execute post-processing operations.

Batch Apex Governor Limits


Keep in mind the following governor limits for batch Apex:
  • Up to five queued or active batch jobs are allowed for Apex.
  • A user can have up to five query cursors open at a time. For example, if five cursors are open and a client application still logged in as the same user attempts to open a new one, the oldest of the five cursors is released.
  • Cursor limits for different Force.com features are tracked separately. For example, you can have five Apex query cursors, five batch cursors, and five Visualforce cursors open at the same time.
  • A maximum of 50 million records can be returned in the Database.QueryLocator object. If more than 50 million records are returned, the batch job is immediately terminated and marked as Failed.
  • The maximum value for the optional scope parameter is 2,000. If set to a higher value, Salesforce chunks the records returned by the QueryLocator into smaller batches of up to 2,000 records.
  • If no size is specified with the optional scope parameter, Salesforce chunks the records returned by the QueryLocator into batches of 200, and then passes each batch to the execute method. Apex governor limits are reset for each execution of execute.
  • The startexecute and finish methods can implement only one callout in each method.
  • Batch executions are limited to one callout per execution.
  • The maximum number of batch executions is 250,000 per 24 hours.
Only one batch Apex job's start method can run at a time in an organization. Batch jobs that haven’t started yet remain in the queue until they're started. Note that this limit doesn’t cause any batch job to fail and execute methods of batch Apex jobs still run in parallel if more than one job is running.   

Step 1: Write an apex class for Batch Apex.

Sample code:

global class AccountUpdate implements Database.batchable<sObject>
{

    String query,field,value;
   
    global AccountUpdate(String f, String v)
    {
        field = f;
        value = v;
        query = 'Select ' + field + ' FROM Account';
    }

    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        return Database.getQueryLocator(query);
    }
   
    global void execute(Database.BatchableContext BC, List<sObject> scope)
    {
         for(sobject s : scope)
         {
             s.put(Field,Value);
         }
         update scope;
    }
   
    global void finish(Database.BatchableContext BC)
    {
    }
   
}

            The above class is used to update Description field with some value.

Step 2: Go to Setup Ã  Developer Console.


Step 3: Execute the Batch Apex.

Id batchInstanceId= Database.executeBatch(new AccountUpdate('Description','Updated'));


 Step 4: Monitor the Apex jobs.
To monitor the Apex jobs, go to Setup --> Monitoring --> Apex Jobs.


Monday 11 August 2014

Getting record from other Salesforce organization Using Apex and SOAP Web Service API

In this article, i will explain the code which can be used for connecting and getting the records from different or multiple salesforce organization using Apex and REST Service.
To start first we will need to authorize below two URL which can be accessed from salesforce environment.
This can be done from “Setup | Administration Setup | Security Controls | Remote Site Settings”
  1. https://www.salesforce.com
  2. https://ap1.salesforce.com

This application will prompt for the Username and Password of the other salesforce account and display the 10 records of the Account.


Apex Code:

1public with sharing class FetchAccount {
2
3    //Login Domain May be test, prerellogin.pre
4    String LOGIN_DOMAIN = 'www';
5    public String pwd{get;set;}
6    public String userName{get;set;}
7    public List<Account> acc{get;set;}
8    public String errMsg{get;set;}
9    public String displayError{get;set;}
10
11    public FetchAccount()
12    {
13        displayError = 'none';
14    }
15
16    public void fetch()
17    {
18        errMsg  = 'Some error occurred, please try again';
19        try
20        {
21        //-----------------------------------
22        // Login via SOAP/XML web service api
23        //-----------------------------------
24        HttpRequest request = new HttpRequest();
25        request.setEndpoint('https://' + LOGIN_DOMAIN +'.salesforce.com/services/Soap/u/22.0');
26        request.setMethod('POST');
27        request.setHeader('Content-Type''text/xml;charset=UTF-8');
28        request.setHeader('SOAPAction''""');
29        //not escaping username and password because we're setting those variables above
30        //in other words, this line "trusts" the lines above
31        //if username and password were sourced elsewhere, they'd need to be escaped below
32        request.setBody('<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Header/><Body><login xmlns="urn:partner.soap.sforce.com"><username>' + userName+ '</username><password>' + pwd+ '</password></login></Body></Envelope>');
33        Dom.XmlNode resultElmt = (newHttp()).send(request).getBodyDocument().getRootElement()
34          .getChildElement('Body','http://schemas.xmlsoap.org/soap/envelope/')
35          .getChildElement('loginResponse''urn:partner.soap.sforce.com')
36          .getChildElement('result''urn:partner.soap.sforce.com');
37
38        //-------------------------------
39        // Grab session id and server url
40        //--------------------------------
41        final String SERVER_URL = resultElmt.getChildElement('serverUrl','urn:partner.soap.sforce.com') .getText().split('/services')[0];
42        final String SESSION_ID = resultElmt.getChildElement('sessionId','urn:partner.soap.sforce.com') .getText();
43
44        //----------------------------------
45        // Load first 10 accounts via REST API
46        //---------------------------------
47        final PageReference theUrl = new PageReference(SERVER_URL +'/services/data/v22.0/query/');
48        theUrl.getParameters().put('q','Select a.Phone, a.Name, a.CreatedBy.FirstName, a.CreatedById From Account a limit 10');
49        request = new HttpRequest();
50        request.setEndpoint(theUrl.getUrl());
51        request.setMethod('GET');
52        request.setHeader('Authorization''OAuth ' + SESSION_ID);
53
54        String body = (new Http()).send(request).getBody();
55
56        JSONParser parser = JSON.createParser(body);
57
58        do{
59            parser.nextToken();
60        }while(parser.hasCurrentToken() && !'records'.equals(parser.getCurrentName()));
61
62        parser.nextToken();
63
64        acc = (List<Account>) parser.readValueAs(List<Account>.class);
65        }
66        catch(Exception e)
67        {
68            displayError = 'block';
69        }
70
71    }
72}

Visualforce Code:

1<apex:page controller="FetchAccount" standardStylesheets="true">
2<style type="text/css">
3.errorMsg{
4    font-size:0.8 em;
5    color:red;
6}
7</style>
8<apex:pageBlock >
9<apex:form >
10<apex:outputLabel value="UserName : " for="userName"/>
11<apex:inputText required="true" id="userName" value="{!userName}" />
12<br />
13<apex:outputLabel value="Password : " for="pwd"/>
14<apex:inputsecret id="pwd" value="{!pwd}"/>
15<br />
16<apex:commandButton id="getRecords" value="Get Records" action="{!fetch}"rerender="wrapper" status="waitStatus" />
17<apex:actionStatus startText="Requesting..." stopText="" id="waitStatus"/>
18<hr />
19<apex:outputPanel id="wrapper">
20<div class="errorMsg" style="display:{!displayError}"> {!errMsg} </div>
21<apex:pageBlockTable value="{!acc}" var="account" id="accTable"rowClasses="odd,even" styleClass="tableClass">
22 
23    <apex:column >
24        <apex:facet name="header">Account Name</apex:facet>
25         <apex:outputText value="{!account.name}"/>
26    </apex:column>
27 
28    <apex:column >
29        <apex:facet name="header">Created By</apex:facet>
30         <apex:outputText value="{!account.CreatedBy.FirstName}"/>
31    </apex:column>
32 
33    <apex:column >
34        <apex:facet name="header">Phone</apex:facet>
35         <apex:outputText value="{!account.Phone}"/>
36    </apex:column>
37 
38</apex:pageBlockTable>
39</apex:outputPanel>
40</apex:form>
41</apex:pageBlock>
42</apex:page>